ποΈ Storage Slots: 32-Byte Data Layout
Learn how Ethereum packs variables into 256-bit storage slots
Your Progress
0 / 5 completedπ¦ Storage Slots Explained
The EVM organizes storage as an array of 2^256 slots, each exactly 32 bytes (256 bits). Understanding how variables map to these slots is essential for optimization and avoiding storage collisions.
π― Interactive: Storage Slot Calculator
Calculate how many slots your variables will use:
110
Variable Size
256 bits
32 bytes
Per Slot
1x
variables fit
Slots Needed
1
32 bytes
Efficiency
100.0%
0B wasted
Visual Layout:
Slot 0:
1
32/32B
How Storage Slots Work
Every state variable in Solidity is assigned a storage slot starting from slot 0. The EVM packs smaller variables into the same slot when possible, reading/writing entire 32-byte slots at once.
Storage Layout Rules:
1
Sequential Assignment
Variables are assigned slots in declaration order (0, 1, 2...)
2
Automatic Packing
Variables β€32 bytes can share a slot if they fit together
3
No Splitting
Variables never span multiple slotsβnew slot starts if can't fit
4
Special Structures
Arrays/mappings use hash-based addressing for dynamic sizing
Layout Visualizer
Example Contract:
contract StorageExample {
uint256 a; // Slot 0 (32 bytes, fills entire slot)
uint128 b; // Slot 1 (16 bytes, leaves 16 bytes free)
uint128 c; // Slot 1 (16 bytes, packs with b)
uint64 d; // Slot 2 (8 bytes, new slot)
uint64 e; // Slot 2 (8 bytes, packs with d)
uint64 f; // Slot 2 (8 bytes, packs with d & e)
address owner; // Slot 2 (20 bytes, but won't fitβgoes to Slot 3)
bool active; // Slot 3 (1 byte, packs with owner)
}Slot 0:
uint256 a (32 bytes)
Slot 1:
uint128 b
uint128 c
Slot 2:
uint64 d
uint64 e
uint64 f
unused (8B)
Slot 3:
address owner (20 bytes)
bool
unused (11B)
π‘ Key Observations:
- β’
bandcpack together (both uint128 = 32 bytes total) - β’
d,e,fpack together (3Γuint64 = 24 bytes, leaving 8 unused) - β’
owner(address = 20 bytes) can't fit in Slot 2, starts Slot 3 - β’
active(bool = 1 byte) packs withownerin Slot 3 - β’ Total: 4 slots used, 19 bytes wasted
Dynamic Data Structures
πΊοΈ
Mappings
Values stored at: keccak256(key . slotNumber)
mapping(address => uint) balances; // Slot 0// User balance at: keccak256(userAddr . 0)π
Arrays
Length at slot, elements at: keccak256(slotNumber) + index
uint[] items; // Slot 0 = length// items[0] at: keccak256(0) + 0β οΈ Storage Collision Warning
In upgradeable contracts, changing storage layout can cause catastrophic bugs:
β Wrong (V2):
uint256 newVar; // Slot 0
uint256 balance; // Slot 1 (was 0!)Balance data now points to wrong slot!
β
Correct (V2):
uint256 balance; // Slot 0 (unchanged)
uint256 newVar; // Slot 1 (added)Always append new variables!