0

I have an ERC721 contract. In the constructor, X NFTs are minted with X being passed as an argument to the constructor. I need to keep track of various things for each NFT, such as the price. The price would need to be an array of uints with slots equal to x, i.e.

uint[x] public prices;

But I need prices to be available to other functions in the future. If I just define the variable in the constructor, it will not be a global variable. But if I defined it outside the constructor or any other function, I am unable to define the size at a time after contract deployment.

Wat do?

2 Answers 2

1

TLDR; You cannot set the size of an array after compile.

Arrays can have a compile-time fixed size, or they can have a dynamic size. From the Solidity Docs


This means that you need to set the size of the array at compile, so you will not be able to set the size in the constructor (which falls under run-time).

A workaround for your problem would be to have a global non-fixed array size (i.e uint[] public prices) and then globally store the length of the array (uint lengthOfArray, setting it in the constructor, i.e lengthOfArray = x) so that you can use the global length variable in your contract to loop over or whatever you need.

Hope that helps :)

3
  • 1. What's the point in suggesting for him to "globally store the length of the array", and then use "a global non-fixed array size (i.e uint[] public prices)"??? The length of that array will be available via prices.length. 2. This user says "with X being passed as an argument to the constructor" - how do you think those X are being passed other than in an array? Functions in Solidity cannot take a variable number of arguments. This user can simply allocate the global array to the desired size, and then copy (push) all the input elements into it. Commented May 10, 2020 at 9:41
  • This does help, thanks. I thought this would be the case. However I have thought of another solution which is just to use a mapping instead of an array. I don't actually need to loop over them at any point, and even if I did, the keys could still be just increasing integers. So why was I trying to use an array in the first place!? Commented May 10, 2020 at 10:02
  • You can save on storage and forego the extra variable uint lengthOfArray by querying the value of the dynamic array's storage slot. In this example, the dynamic array would be in storage slot 0. assembly { _length := sload(0) } See the Solidity docs for more info Commented Jan 21, 2022 at 22:48
0

Answering my own question- just use a mapping instead :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.