0

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.

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

1 Answer 1

3

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]

Text is summary of this article.

2
  • I have read the whole article and the question actually arose from that. I understand the indexing "virtually" but how is it done in real life, because we don't have 2^256 slots. Jun 13, 2020 at 14:56
  • 1
    @AnhDũngLê actually those slots never existed these are just the numbers to avoid the collision. If the system have just 100 gb than the array can only contain the data of 100gb no more. Jun 13, 2020 at 16:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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