Ethereum Storage & Public Data Notes
I write to revisit topics I’m interested in or when I’m bored and curious.
1️⃣ Storage Basics
Ethereum storage is like a massive spreadsheet. Each variable gets a 32-byte (256-bit) row, called a slot.
Static types (
uint256,address,bool,bytes32) → stored directly in their slot.Dynamic types (
string,bytes, arrays, mappings) → handled differently (pointers, packing).
2️⃣ Slots & Offsets
Every variable has:
Slot → the “row” in storage
Offset → byte position inside the slot
Example – generic contract:
| Slot | Variable | Type | Notes |
| 0 | owner | address | static, straightforward |
| 1 | name | string | dynamic, inline or pointer |
| 2 | balances | mapping | pointer to hashed keys |
| 3 | data | bytes | dynamic, depends on length |
3️⃣ Dynamic Types & Strings
Short strings / bytes (≤31 bytes) → packed directly into their slot. Solidity uses the last byte of the slot to store the length.
Long strings / bytes (>31 bytes) → slot stores a pointer:
Pointer =
keccak256(slot_number)Actual bytes stored consecutively starting at that pointer
Examples:
name = "Alice";
// short string → inline in slot 1
data = hex"1234567890abcdef1234567890abcdef1234567890abcdef1234567890abcdef";
// long bytes → slot 3 points to keccak256(3)
Arrays and mappings follow similar pointer rules:
uint256[] numbers→ slot stores length, elements atkeccak256(slot)+ indexmapping(address => uint256) balances→ element stored atkeccak256(abi.encode(key, slot))
4️⃣ Private ≠ Secret
private only blocks other contracts from direct access. All storage is public on-chain.
Read via
vm.load()in FoundryOr
eth_getStorageAtvia RPC /ethers.js/web3.js
Public storage leaks are a goldmine for vulnerabilities. Never trust
privatefor secrecy.
5️⃣ Reading Storage in Tests
Forge test pattern for exposing storage:
Deploy the contract & set sensitive data
Read static variables directly:
vm.load(contract, slot_number)For short dynamic variables: decode bytes from slot, read length from last byte
For long dynamic variables: compute base =
keccak256(slot_number)and read consecutive slots
Arrays, mappings, and long bytes require looping or hashing to reconstruct.



