Understanding Mapping in Solidity (set, get, delete, iterate and nested mapping)
What is Mapping?
Creating a Mapping
Set, Add, Get, Updat and Delete Mapping
Nested Mapping
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) ;
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.
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().
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]
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]
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()
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.
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.
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!