2

I am currently reading the solidty docs , and i came across this :

Mappings can be seen as hash tables which are virtually initialized such 
that every possible key exists and is mapped to a value whose byte-
representation is all zeros: a type’s default value. The similarity ends 
here, though: The key data is not actually stored in a mapping, only its 
keccak256 hash used to look up the value.

Because of this, mappings do not have a length or a concept of a key or 
value being “set”.

I understand what hash tables are , but i have absolutely no clue what the above means. What exactly does virtually initialized mean?

If a mapping was created as (uint=>uint) what would happen in this scenario? I understand the key refereced as a hash , but i fail to understand the concept. How is this computationally beneficial to the smart contract in terms of storage?

Thanks

2 Answers 2

1

Logically, you can think of it as a massive key/value store where every possible key exists and any value can be set or retrieved in one move with the key. The gas cost is consistent at any scale (very important).

This is a quite handy for random access.

We can stuff simple types into values (bytes32, uint, bool) or complex types (array, struct or even another mapping).

For example, suppose every entity A has a list of B ... so you want something like mapping(A => array) BListsThatBelongToInstancesOfA.

If A is known by keys of type bytes32 and B is known by type of uint, then:

mapping(bytes32 => uint[]) BLists;

More commonly, something like keeping track of user balances/scores, etc. by their ethereum address (which the contract can easily determine).

mapping[address => uint) userBalances;

Although the namespace is huge, it doesn't grow the blockchain until something is written to a slot. In the case that one retrieves an item from an "empty" slot, the result will be zero(ish) for the type, meaning 0, false, 0x0 or even (in the case above) array of zero length.

There are some examples of how to use it in practice here: Are there well-solved and simple storage patterns for Solidity?

Mappings and how to use them just don't seem to be well-explained (anywhere I've found), so I took a stab at it here, about 1/3 down. https://medium.com/@robhitchens/solidity-crud-part-1-824ffa69509a

Hope it helps.

2

Not a Solidity developer, but to me that reads like key-value pairs are stored as sparse matrix of keccak256(key) => value instead of key => value. Thus, if you have a key that is, say, 1MB in length, you save space by only storing its keccak256 hash (and, conversely, you waste space with a 1 byte key). Also, if you have a hash collision, you wouldn't know it. So storing a value for key A will result in there being a value when looking up key B when keccak256(A) == keccak256(B). In a regular hash table, you would store the full key to detect collisions or otherwise account for them.

If you try to read a value from the mapping that hasn't been set, the value you get will be 0 (i.e., it is "virtually initialized" to 0) rather than some (for all intents and purposes) random value.

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.