Understanding Mapping in Solidity (set, get, delete, iterate and nested mapping)

Understanding Mapping in Solidity (set, get, delete, iterate and nested mapping)

  1. What is Mapping?

  2. Creating a Mapping

  3. Set, Add, Get, Updat and Delete Mapping

  4. Nested Mapping

  5. Iterable Mappings

What is Mapping?

Mapping in solidity is like a hash table containing a Key Type and Value Type used to store data. Mapping are used to map or associate a keytype to a value type.

Syntax : Mapping(KeyType => ValueType) ;

Image description

The KeyType can be any built-in value types, strings or bytes. The ValueType can be any type including complex types like structs, mappings or arrays.

Key Considerations

  • Mapping can only have a data location of storage and thus are allowed for state variable.

  • Mappings can be marked public

  • Mappings are not iterable except you implement a data structure then iterate over that.

Creating a Mapping

To create a mapping in solidity the keytype and the Value type sould be specified.

Code Sample : In the code sample below, the contract name mappingExample defines a contract, a mapping of keytype, address and value type uint is created.

Image description

How to Set, Get, Delete and Update mapping.

1) Setting or Adding Value

We can set or add value to a mapping.

Code sample : In the code sample below, we created a contract called mappingExample, a mapping called myMapping is defined and values are added to the mapping through the function addMapping().

Image description

The address is set to msg.sender and its mapping value type to uint, of values from "input".

If "input" = 123; then myMapping[msg.sender] = 123;

#note : If the value for the mapping was not set it will always return the default value.

2) Getting Value

We have added values to the mapping. Let's create function to retrieve the values from the mapping .

#note : If the value of mapping was not set it always return 0, the default value for uint.

Code Sample : In the code sample below, a mapping myMapping is defined. We get the mapping value from the mapping through the function getMapping() using myMapping[msg.sender]

Image description

3) Deleting Value

We can delete or remove the value of a mapping, resetting it to the default value, 0.

Code Sample : In the code sample below, a mapping myMapping is defined, we delete values from the mapping through deleteMapping() using delete myMapping[msg.sender]

Image description

Nested Mapping

Nested mapping is a mapping within another mapping; that's a mapping that maps to another mapping and we access the inner mapping through the outer mapping.

Syntax : mapping(address => mapping(address => uint)) name;

Code Sample: In the code sample below, a nested outer mapping myNestedMapping is created mapping from one address to another mapping, mapping to a uint. We add value to the mapping through the function addNestedMapping(), get the value of the nested mapping through the function getNestedMapping() and also delete value with the function deleteNestedMapping()

Image description

Iterable Mapping

We cannot iterate over mapping, meaning that their keys cannot be enumerated.

However, it's possible to iterate mapping only if we implement a data structure on top of them and iterate over that.

Image description

Access the code here Solidity By Example

Example : Creating a mapping that transfers and approves transactions.

In the code sample below, a contract mappingExample is created and a mapping balances and nested mapping allowances, mapping from address to uint are created respectively.

Image description

Copy code below to run on your server.

contract MappingExample {
mapping (address => uint256) private _balances;
    mapping (address => mapping (address => uint256)) private _allowances;

    event Transfer(address indexed from, address indexed to, uint256 value);
    event Approval(address indexed owner, address indexed spender, uint256 value);

    function allowance(address owner, address spender) public view returns (uint256) {
        return _allowances[owner][spender];
    }

    function transferFrom(address sender, address recipient, uint256 amount) public returns (bool) {
        require(_allowances[sender][msg.sender] >= amount, "ERC20: Allowance not high enough.");
        _allowances[sender][msg.sender] -= amount;
        _transfer(sender, recipient, amount);
        return true;
    }

    function approve(address spender, uint256 amount) public returns (bool) {
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[msg.sender][spender] = amount;
        emit Approval(msg.sender, spender, amount);
        return true;
    }

    function _transfer(address sender, address recipient, uint256 amount) internal {
        require(sender != address(0), "ERC20: transfer from the zero address");
        require(recipient != address(0), "ERC20: transfer to the zero address");
        require(_balances[sender] >= amount, "ERC20: Not enough funds.");

        _balances[sender] -= amount;
        _balances[recipient] += amount;
        emit Transfer(sender, recipient, amount);
    }
}

CONCLUSION

That's a wrap guys!

I've tried to cover the basics of Mappings in solidity. It's up to you to do more research on this topic for deep knowledge. Expect more indepth research and resources on Web3, Smart Contracts, and Blockchain in my subsequent Blog posts.

I'm Sunington, you can connect with me on Twitter and on LinkedIn.

Until we meet again

#KeepSunning!