💾 Contract Storage: How Data Lives On-Chain
Understand storage slots, state variables, and persistent data
Your Progress
0 / 5 completed💾 Understanding Contract Storage
Storage is the permanent memory of smart contracts—where state lives between transactions. Understanding how the EVM manages storage is crucial for writing efficient, cost-effective contracts.
🎯 Interactive: Storage Hierarchy Explorer
Explore the 4 data locations in the EVM:
Storage
PermanentPersistent data stored on-chain between function calls and transactions
What Is Contract Storage?
Contract storage is permanent key-value data that persists on the blockchain. Unlike memory (temporary) or calldata (read-only), storage is where your contract's state lives—balances, mappings, arrays, and all state variables.
Key Characteristics:
Why Storage Matters
Storage is the most expensive operation in smart contracts. Poor optimization can make your contract unusable due to high gas fees.
Multiple variables can share a single 32-byte slot, reducing gas costs by up to 75% with proper optimization.
Understanding how Solidity assigns slots is critical for upgradeable contracts and avoiding storage collisions.
Reading from storage (SLOAD) costs 2,100 gas vs. 3 gas for memory—caching strategies can save thousands.
Storage vs. Other Data Locations
| Location | Persistence | Gas Cost | Use Case |
|---|---|---|---|
| Storage | Permanent | 20,000 gas (new) | State variables |
| Memory | Function scope | ~3 gas/word | Temp calculations |
| Calldata | Read-only | 16 gas/byte | Function args |
| Stack | Operation-level | ~3 gas | Primitives only |
Real-World Example
User Profile Contract
contract UserProfile {
// Storage variables (expensive!)
mapping(address => string) public names; // Slot 0
mapping(address => uint256) public ages; // Slot 1
mapping(address => bool) public verified; // Slot 2
uint256 public totalUsers; // Slot 3
function updateProfile(string memory _name, uint256 _age) public {
// Memory variable (cheap, temporary)
string memory tempName = _name;
// Writing to storage (20,000 gas for new slot!)
names[msg.sender] = tempName;
ages[msg.sender] = _age;
verified[msg.sender] = true;
totalUsers++; // Update storage (5,000 gas)
}
}💡 Gas Analysis:
- • First call: ~65,000 gas (3 new mappings + counter)
- • Update call: ~20,000 gas (updating existing values)
- • Reading name: ~2,100 gas (SLOAD)
- • Using memory for temp: Only ~3 gas/word
💡 Key Insight
Storage is like a hard drive for your contract—permanent but slow and expensive. The key to efficient contracts is:
- •Minimize writes: Only store what must persist between transactions
- •Pack variables: Fit multiple variables in one 32-byte slot
- •Cache reads: Load storage once into memory, reuse it
- •Use memory: Temporary calculations should never touch storage