# Costs of storing an empty dynamic array of length 2**256-1 vs length 4

If the array is completely empty, is it more expensive to store uint[] of length 2**256-1 vs of length 4?

• If the array is completely empty, then its length is 0. So please clarify what you mean. – goodvibration Feb 5 '20 at 13:45
• with empty, foo[1], foo[2], foo[3] are not set to any value – user57880 Feb 5 '20 at 13:46
• Also, what do you mean by "expensive to store"? The cost is inflicted when you actually change a value in the array, not for keeping that value in there. – goodvibration Feb 5 '20 at 13:46
• If you don't set them to any value, then how can the array length grow? – goodvibration Feb 5 '20 at 13:47
• foo.length = 2**30 – user57880 Feb 5 '20 at 13:48

if the array is only being used below foo[n], and the length is longer than n, is anything above foo[n] adding storage costs?

No.

Arrays use the same storage scheme as mappings. The slots to write to are hashes of the contract address, the position of the variable established at compile-time, and the index. Uninitialized values are not written and they will return 0x00... if accessed. For clarity, Solidity arrays enforce a rule that a contract can only access indexes < length, i.e. don't go past the end.

Generally, the EVM and Solidity are very conservative about writes and they won't reorganize data unless your contract tells them to.

is anything above foo[n] adding storage costs?

Not if there is nothing there.

Try this:

``````pragma solidity 0.5.16;

contract ArrayStuff {

bytes32[] d;

function makeHuge() public {
uint massive = uint(0)-uint(1); // biggest uint possible
d.length = massive;
}
}
``````

You can see it takes about 42K gas to make a huge array.

There are some caveats about doing that. In theory, you have indexes to all of the slots. You can potentially scribble over anything if you can find the right hash collision. In practice, it would be prohibitively challenging to work out the index that will hash to the right slot in order to stomp on anything in particular.

Here's the hash function: https://solidity.readthedocs.io/en/v0.6.1/miscellaneous.html#mappings-and-dynamic-arrays

Hope it helps.

For `storage` it should be the same.

I presume you're asking theoretically. If you actually create one of these things, it will enable you to access the whole of the storage available to the contract via the array - which means you could overwrite other storage variables. I've seen this trick used a few times in "Hack this contract" competitions, and is one reason you should be very careful with variable sized arrays.

• the choice is between a longer array (not 2^256, more closer to 2^33 or practically usually 2^20), or, more frequent increase of the length. a better way to ask is, if the array is only being used below foo[n], and the length is longer than n, is anything above foo[n] adding storage costs? – user57880 Feb 5 '20 at 13:27
• so I ran some tests with this: `contract ArrayLengthGasTest { uint[] array; constructor (uint256 length) public { array.length = length; } }` with longer lengths there was very slightly more gas cost in the transaction, but this is because solidity charges per byte for non-zero transaction data. It's basically negligible. – Zakalwe Feb 5 '20 at 14:56
• although changing the length of the array will invoke one SSTORE each time – Zakalwe Feb 5 '20 at 14:58
• and if you really want an array of 2^20 elements, you should possibly look into `mapping`s which might suit you better. I dread to think how expensive fully populating an array that big would be!! – Zakalwe Feb 5 '20 at 14:59
• it's populated per transaction per person. so, not very expensive. yes a mapping might be better, I had to use an array initially but have reworked the structure of the contract a bit so now it can be treated differently, and a mapping would be better. already made that change after your answer :) – user57880 Feb 5 '20 at 15:01