What is mapping in Solidity?
Mappings in Solidity are hash tables that store data as key-value pairs, where the key can be any of the built-in data types supported by Ethereum. Mappings are a fundamental concept to understand when learning Solidity development.
This article explains what mappings are, how mappings work, the differences between mappings and arrays, and provides examples of mappings so you can develop the best smart contracts on Ethereum and Solidity-compatible blockchains like Optimism and Arbitrum.
What is a hash table?
A hash table is a data structure that stores data associatively. Data is kept in an array format in a hash table, with each data value having its own unique index value. Hash Tables use an array as a storage medium and employ the hash technique to establish an index from which an element is to be inserted or located.
When the index of the needed data is known, it can get returned extremely quickly. As a result, hash tables are data structures in which insertion and search operations are extremely quick, regardless of the quantity of the data.
What is mapping in Solidity?
Mapping is a hash table in Solidity that stores data as key-value pairs, where the key can be any of the built-in data types, excluding reference types, and the value of the data type can be any type.
Mappings are most typically used in Solidity and the Ethereum blockchain to connect a unique Ethereum address to a corresponding value type.
In any other programming language, a mapping is equivalent to a dictionary.
What is the difference between hash tables and Solidity mappings?
Mappings function as hash tables, with key types and corresponding value type pairs, and mappings are valuable because they can hold a large number of _KeyTypes to _ValueTypes. Mappings do not have a length, nor do they have the concept of setting a key or a value. Mappings are only applicable to state variables that serve as store reference types. When mappings are initialized, they include every possible key, and are mapped to values whose byte-representations are all zeros.
Mappings are defined in Solidity in the same way as any other variable type:
What is the difference between Solidity arrays and mappings?
Solidity arrays are better for iterating through a group of data (e.g. using a for loop), compared to mappings which are better when you will be able to obtain values based on a known key (i.e. you don't need to go over data).
Because iterating over an array in Solidity can be expensive compared to fetching data from mappings, and developers may want to store both a value and its key within a smart contract, developers sometimes create an array of keys that serve as a reference to data that can then be retrieved from inside a mapping.
Developers should never let an array in Solidity grow too large because iterating through a large array could cost more in Solidity gas fees than the transaction's value, making mappings a more gas efficient smart contract implementation.
Here are some additional qualities about mappings:
- Mappings have no length.
- Mappings also don't understand the concept of a key or a value being set.
- Mappings can only be used for state variables that serve as storage reference types.
What is a nested mapping?
Nested mapping is mapping from one mapping to another. For example, if we have a username and age and want to store this information with the assistance of a special ID so that others can only get it with the aid of that ID, this is known as double mapping in Solidity.
Here is one nested mapping example:
In this contract, we built one nested mapping, which is referred to as a User. In that mapping, we linked two mappings:
- one for recording the information about the id of the specific user
- one for storing the name and age of the specific user.
The code block below is a simple getter function, which returns information of the user.
How to Use Mappings in Solidity
Here is an example of using mappings in Solidity. The following code snippet functions are:
- Mapping from address to uint and ensures the mapping always returns a value
- If the value was never set, it will return the default value.
- Updating the value at the mapped address
- Resetting the value to the default value.
- Creating a nested mapping from address to another mapping
- Getting values from a nested mapping even when it is not initialized
Solidity Mapping Examples
Here are three examples of mappings in Solidity:
- ERC20 token balances
- Using boolean logic
- Looking up members of a DAO
1. ERC20 User Balances
This code snippet maps user addresses with their addresses' ERC20 balance.
2. Solidity Mapping Bool Example
This code snippet is designed to list candidates names in a list and return how many votes the candidate received. This example has use cases with DAOs where members are expected to vote on organizational decisions.
3. Is a Member (DAOs)
This example is from the Dominion DAO smart contract that maps raisedProposals, stakeholderVotes, votedOn, contributors, and stakeholders.
This code example lists fields for two Solidity structs: ProposalStruct and VotedStruct.
Solidity Mapping of String
Let's try adding some values to the mapping while it's being built for better understanding. In the following example, we:
- Create a contract
- Define a structure
- Declare different structure elements
- Create a mapping
- Add values to the mapping
Solidity Mapping FAQs
Here are a few frequently asked questions about Solidity mappings:
- What is the Solidity mapping length?
- What are the default values of Solidity mappings?
- How can you publicly see Solidity mappings?
What is the Solidity mapping length?
Mappings do not have a length. A key's data is not saved in a mapping, but rather its keccak256 hash is used to store the value to which the key data refers. There is no concept of a key and a value "by themselves."
What are Solidity Mapping default values types?
Here are the default value types for Solidity mappings:
- int/uint - key type = yes; value type = yes
- string - key type = yes; value type = yes
- byte/bytes - key type = yes; value type = yes
- address - key type = yes; value type = yes
- struct - key type = no; value type = yes
- mapping - key type = no; value type = yes
- enum - key type = no; value type = yes
- contract - key type = no; value type = yes
- fixed-sized array - key type = yes; value type = yes
- dynamic-sized array - key type = no; value type = yes
- multi-dimensional array - key type = no; value type = yes
- variable - key type = no; value type = no
How to publicly see Solidity mappings?
Because the property is public, you can use the getter function created by the Solidity compiler to access it.