Mappings in Solidity Explained in Under Two Minutes

Doug Crescenzi
Upstate Interactive
3 min readMay 23, 2018

--

Mappings act as hash tables which consist of key types and corresponding value type pairs. They are defined like any other variable type in Solidity:

mapping(_KeyType => _ValueType) public mappingName
example of a hash table

Mappings are incredibly useful for associations and frequently used to associate unique Ethereum addresses with associated value types. For instance in the blockchain-based puzzle game we built it was necessary for us to map a user’s address to their corresponding level in the game:

mapping(address => uint) public userLevel;

Accessing Value Types from a Mapping with Key Types

With this mapping in place we then built a function to identify a user’s current level in the game. Here we pass the currentLevel function an argument — i.e., a particular user’s address — and then we use the userLevel mapping to return that user’s associated level in the game:

function currentLevel(address userAddress) public constant returns (uint) {     return userLevel[userAddress];}

Using a mapping here is helpful because it can store many _KeyTypes to _ValueTypes. In this case there are many users playing the game all at once and they can each have their own corresponding userLevel.

A mappings default value

According to the Solidity docs, “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 are all zeros.

Essentially this means that mappings do not have a length. They also do not have a concept of a key or a value being set. We can only use mappings for state variables that act as storage reference types. It’s then possible to create a getter function call (like public) in which the _KeyType is the parameter used by the getter function in order to return the _ValueType.

Let’s reflect back on our userLevel mapping from our game:

mapping(address => uint) public userLevel;

When userLevel is initialized it’s done in such a way that every possible Ethereum address exists in the mapping and is mapped to a corresponding level of 0. Whether it’s a random Ethereum user’s MetaMask address who perhaps has never even heard of our game before, or maybe an arbitrary smart contract on the Ethereum blockchain doing something totally unrelated, it doesn’t matter. Our mapping still maps them to a corresponding level of 0 in our game, or more appropriately, maps to a “value whose byte-representation are all zeros.”

Take aways

  • Mappings act as hash tables which consist of key types and corresponding value type pairs
  • Mappings are useful because they can store many _KeyTypes to _ValueTypes
  • Mappings do not have a length, nor do they have a concept of a key or a value being set
  • Mappings can only be used for state variables that act as storage reference types
  • When mappings are initialized every possible key exists in the mappings and are mapped to values whose byte-representations are all zeros

--

--

Doug Crescenzi
Upstate Interactive

vp, software engineering @ Foundry, previously founding partner at Upstate Interactive (acq'd by Foundry in '22)