Understanding Mapping in Solidity: Types, Use Cases, and Best Practices

Varun ChoudharyVarun Choudhary
2 min read

Mappings in Solidity are powerful key-value storage structures, similar to hash tables in other languages. They provide constant-time lookups, making them efficient for on-chain data management.

1. What is Mapping in Solidity?

A mapping in Solidity stores key-value pairs, where keys are hashed for fast access. Unlike arrays, mappings do not store data sequentially, making them ideal for quick retrieval.

Basic Mapping Example

pragma solidity ^0.8.0;
contract SimpleMapping {
    mapping(address => uint) public balances;

    function setBalance(uint _amount) public {
        balances[msg.sender] = _amount;
    }

    function getBalance(address _addr) public view returns (uint) {
        return balances[_addr];
    }
}

2. Types of Mappings in Solidity

2.1 Simple Mapping

A basic mapping of key-value pairs.

mapping(address => uint) public userBalances;

2.2 Nested Mapping

Nested mappings allow multiple levels of storage, useful for access control and complex relationships.

contract NestedMapping {
    mapping(address => mapping(uint => bool)) public userPermissions;

    function setPermission(address _user, uint _level, bool _hasAccess) public {
        userPermissions[_user][_level] = _hasAccess;
    }

    function checkPermission(address _user, uint _level) public view returns (bool) {
        return userPermissions[_user][_level];
    }
}

2.3 Mapping with Structs

Mapping can be combined with structs for more structured data storage.

contract StructMapping {
    struct User {
        string name;
        uint age;
    }
    mapping(address => User) public users;

    function setUser(string memory _name, uint _age) public {
        users[msg.sender] = User(_name, _age);
    }
}

2.4 Mapping in Arrays

Though mappings cannot be directly stored in arrays, an array of structs containing mappings is possible.

contract MappingArray {
    struct User {
        mapping(string => uint) scores;
    }
    User[] public users;

    function addScore(uint _index, string memory _subject, uint _score) public {
        users[_index].scores[_subject] = _score;
    }
}

3. Real-Life Use Cases of Mappings in Solidity

3.1 Token Balances

Mappings are widely used for tracking token balances in ERC-20 tokens.

mapping(address => uint) public tokenBalance;

3.2 Role-Based Access Control

Nested mappings help manage user roles and permissions efficiently.

mapping(address => mapping(string => bool)) public rolePermissions;

3.3 Decentralized Voting System

Mappings ensure fair and secure voting mechanisms.

mapping(uint => mapping(address => bool)) public hasVoted;

3.4 Escrow Payments

Smart contracts can use mappings to hold funds securely for transactions.

mapping(address => uint) public escrowBalance;

4. Best Practices for Using Mappings

  • Use Structs for Complex Data: Avoid excessive nesting by using structs.

  • No Iteration: Mappings cannot be iterated over, so store keys in an array when needed.

  • Efficient Access Control: Use nested mappings to manage permissions efficiently.

  • Gas Optimization: Avoid storing unnecessary data to reduce transaction costs.

0
Subscribe to my newsletter

Read articles from Varun Choudhary directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Varun Choudhary
Varun Choudhary