Mappings in Blockchain / Solidity - Time & Space Complexity
When working with mappings in blockchain, it's important to know how fast we can find or store data.
We want to understand how the time to access or update a mapping changes as it grows.
Analyze the time complexity of the following code snippet.
mapping(address => uint) public balances;
function updateBalance(address user, uint amount) public {
balances[user] = amount;
}
function getBalance(address user) public view returns (uint) {
return balances[user];
}
This code stores and retrieves a user's balance using a mapping from addresses to numbers.
Identify the loops, recursion, array traversals that repeat.
- Primary operation: Direct access to mapping entries by key (address).
- How many times: Each access or update happens once per call, no loops involved.
Accessing or updating a mapping entry takes about the same time no matter how many entries exist.
| Input Size (n) | Approx. Operations |
|---|---|
| 10 | 1 |
| 100 | 1 |
| 1000 | 1 |
Pattern observation: The time stays constant even as the mapping grows larger.
Time Complexity: O(1)
This means accessing or updating a mapping entry takes the same short time no matter how many items are stored.
[X] Wrong: "Accessing a mapping gets slower as it stores more data."
[OK] Correct: Mappings use a hash-like structure that lets the program jump directly to the data, so size does not slow access.
Understanding that mappings provide quick access helps you explain efficient data handling in blockchain smart contracts.
"What if we replaced the mapping with an array and searched for the user each time? How would the time complexity change?"
Practice
mapping in blockchain smart contracts?Solution
Step 1: Understand the role of mapping
Mappings are used to link a key to a value, allowing quick access to data based on the key.Step 2: Compare options
Only To connect keys to values for fast data lookup correctly describes this purpose; others describe unrelated functions.Final Answer:
To connect keys to values for fast data lookup -> Option DQuick Check:
Mapping = key-value fast lookup [OK]
- Thinking mappings store all keys explicitly
- Confusing mappings with arrays or lists
- Assuming mappings perform calculations
address to uint in Solidity?Solution
Step 1: Recall Solidity mapping syntax
The correct syntax uses parentheses with key type, arrow, and value type: mapping(keyType => valueType) visibility name;Step 2: Check each option
mapping(address => uint) public balances; matches the correct syntax. Options A, C, and D have syntax errors like using commas instead of =>, wrong brackets, or function-like declaration.Final Answer:
mapping(address => uint) public balances; -> Option BQuick Check:
Correct mapping syntax uses (key => value) [OK]
- Using square brackets instead of parentheses
- Missing visibility keyword like public
- Using commas instead of =>
mapping(address => uint) public balances;
function setBalance(address user, uint amount) public {
balances[user] = amount;
}
function getBalance(address user) public view returns (uint) {
return balances[user];
}
// After calling setBalance(0x1234..., 50), what does getBalance(0x1234...) return?Solution
Step 1: Understand setBalance effect
The function sets the balance of the given address to the specified amount, here 50.Step 2: Understand getBalance output
Calling getBalance with the same address returns the stored value, which is 50.Final Answer:
50 -> Option AQuick Check:
Set then get returns stored value [OK]
- Assuming default zero is returned after setting
- Thinking mapping keys are enumerable
- Expecting an error for unset keys
mapping(address => uint) balances;
function addBalance(address user, uint amount) public {
balances[user] += amount;
}
function getBalance(address user) public view returns (uint) {
return balances[user];
}Solution
Step 1: Check mapping declaration
Mapping does not need explicit initialization; default values are zero.Step 2: Check function logic
addBalance adds amount to the current balance; getBalance returns it. Not declaring public means no automatic getter, but manual getter exists.Final Answer:
There is no error; the code works as expected -> Option CQuick Check:
Mapping defaults and manual getter work fine [OK]
- Assuming mapping must be public to read values
- Thinking mappings need explicit initialization
- Confusing mapping keys storage with values
Solution
Step 1: Understand ownership tracking needs
We need to check if a user owns a specific item ID, so a direct boolean check is best.Step 2: Analyze options
Only mapping(address => mapping(uint => bool)) ownsItem; // nested mapping user to item ID to ownership provides a nested mapping(address => mapping(uint => bool)) ownsItem, allowing direct ownsItem[user][itemID] lookup from the user address. A limits to one item per user; B requires starting from item ID; D requires searching an array.Final Answer:
mapping(address => mapping(uint => bool)) ownsItem; // nested mapping user to item ID to ownership -> Option AQuick Check:
Nested mapping allows direct ownership check [OK]
- Using single mapping limiting one item per user
- Using arrays which are not mappings
- Confusing item-to-owner with user-to-item ownership check
Ready to prove it?
Pass the test and this pattern moves unknown
