So I know how arrays are stored in storage. If I understand it correctly it first stores the number of items in an array in the first slot, and then in the next slots, it stores the hashed values.
My question is what if I define uint after the array and the array during deployment has only 2 values. So it should take up 3 slots. Then in the fourth slot is the uint I defined.
What if there is a function that will push something to the array? How is it stored?
Will it be stored in the next free slot? Or will it push the uint to the next slot and replace it with the new value?
I hope the question is clear if not I will try to rephrase it. Also if there is some good resource where I can learn all about storage in solidity please share the link.
Thanks a lot!
Fixed-size array stores its values in sequential order, starting with the 0th index. There's no prepended slot that would show the total length. Any unset values use the default value of 0.
pragma solidity ^0.8;
contract MyContract {
address[3] addresses; // storage slots 0, 1, 2
uint256 number; // storage slot 3
constructor(address[2] memory _addresses, uint256 _number) {
addresses = _addresses;
number = _number;
}
}
Passing 2 addresses to the constructor, storage slot values in this case:
_addresses[0]
_addresses[1]
_number
Dynamic-size array stores its values in keys that are hash of the property storage slot (in example below that's 0, as that's the first storage property), and immediately following slots. In the property storage slot, it stores the array length.
pragma solidity ^0.8;
contract MyContract {
/*
* storage slots:
* p (in this case value 0, as this is the first storage property) = length of the array
* keccak256(p) = value of index 0
* keccak256(p) + 1 = value of index 1
* etc.
*/
address[] addresses;
// storage slot 1
uint256 number;
constructor(address[] memory _addresses, uint256 _number) {
addresses = _addresses;
number = _number;
}
}
Passing 2 addresses to the constructor, storage slot values in this case:
_number
_addresses[0]
_addresses[1]
So to answer your questions:
What if there is a function that will push something to the array? How is it stored?
Will it be stored in the next free slot? Or will it push the uint to the next slot and replace it with the new value?
Fixed-size arrays cannot be resized. You can only rewrite its values, while the default value of each item is 0.
In case of dynamic-size arrays, it pushes the new value right after the last one. Since they are stored in slots which indexes are based on a hash, the probability of rewriting another value is practically 0 (i.e. that would mean a hash collision).
In both cases, it doesn't affect how other storage properties are stored.