# How does Smart-contract's storage works?

I keep hearing that for each contract there is a storage as contiguous array (to have constant O(1) lookup) with 2^256 slots, 32 byte each, available. But it cannot physically be true. How is it really implemented in practice? Thanks.

• from where did you hear/read it? because i have never heard about it. Commented Jun 13, 2020 at 11:40
• from the article linked in the answer from Haseeb Saeed. Commented Jun 13, 2020 at 14:57

Yes the array taken is virtual in every aspect. Just assume that array is initlized with zero's. Since Storage is very expensive we don't need any zeros in it. unless explicitly defined by the user.

A key/value store mapping `32-byte keys` to `32-byte values` will do the job nicely. An absent key is simply defined as mapping to the value zero. Because zeros don’t take up any space, storage can be reclaimed by setting a value to zero. This is incentivized in smart contracts with a gas refund when you change a value to zero.

Fixed-Sized Values

For known variables with fixed sizes, it makes sense to just give them reserved locations in storage

``````contract StorageTest {
uint256 a;
uint256[2] b;

struct Entry {
uint256 id;
uint256 value;
}
Entry c;
}
``````

These slots are determined at compile time, strictly based on the order in which the variables appear in the contract code.

Locating Dynamically-Sized Values For dynamic sized values like mapping Solidity uses a hash function to uniformly and repeatably compute locations for dynamically-sized values.

``````contract StorageTest {
uint256 a;     // slot 0
uint256[2] b;  // slots 1-2

struct Entry {
uint256 id;
uint256 value;
}
Entry c;       // slots 3-4
Entry[] d;
}
``````

In the above code, the dynamically-sized array d is at slot 5, but the only thing that’s stored there is the size of d. The values in the array are stored consecutively starting at the hash of the slot.

Mappings

A mapping requires an efficient way to find the location corresponding to a given key. Hashing the key is a good start, but care must be taken to make sure different mappings generate different locations.

In the above code, the “location” for e is slot 6, and the location for f is slot 7, but nothing is actually stored at those locations. (There’s no length to be stored, and individual values need to be located elsewhere.)

To find the location of a specific value within a mapping, the key and the mapping’s slot are hashed together.

Combinations of Complex Types

Dynamically-sized arrays and mappings can be nested within each other recursively. When that happens, the location of a value is found by recursively applying the calculations defined above. This sounds more complex than it is.

e.g: `g[123][0]`