Skip to content

State_trie

Chapter 28: State & Merkle Trie Structures

Section titled “Chapter 28: State & Merkle Trie Structures”

Ethereum uses a Modified Merkle Patricia Trie (MPT) to store and commit to state. Understanding the trie explains why state queries are fast, why state is huge, why proofs work, and what “state root” in a block header actually means.


A blockchain needs to answer: “what is the canonical state at block N?” — without trusting anyone. The answer is a single 32-byte value, the state root, committed in every block header. Any node can recompute the root from the state database; any mismatch means state is corrupted or tampered with.

┌─────────────────────────────────────────────────────────────────┐
│ STATE COMMITMENT │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ~200M accounts State Root (32 bytes) │
│ ┌─────────────┐ ┌───────────────────┐ │
│ │ acct A: bal │────┐ │ 0x8f3a...c9d2 │ │
│ │ acct B: code│────┼────▶│ (in block header) │ │
│ │ acct C: stor│────┘ └───────────────────┘ │
│ │ ... │■ MPT Any change changes the root: │
│ └─────────────┘ cheap to verify, impossible to fake │
│ │
└─────────────────────────────────────────────────────────────────┘

MPT = Merkle tree (cryptographic hashing of children upward) + Patricia trie (common-key prefixes compressed into single nodes) — a radix tree over hex-prefixed keys.


Ethereum’s trie has exactly three node types (EIP-2106-era geth serializes them in RLP):

Node typeContentsWhen it appears
Leaf[path-suffix, value]End of a key path
Extension[shared-path, child-ref]Several keys share a prefix
Branch17 entries: [0..f, value]Keys split at this nibble
Root Node
│ (extension: shared nibbles "a7f…")
▼
┌──────────────┐
│ EXTENSION │ "a7f" (shared prefix compressed)
└──────┬───────┘
│
┌──────▼──────────────────────────┐
│ BRANCH (17 slots) │
│ 0 1 2 … f value? │
└──┬───────┬───────────┬──────────┘
│ │ │
┌──────▼──┐ ┌──▼─────┐ ┌───▼─────┐
│ LEAF │ │ LEAF │ │ LEAF │
│ suffix │ │ suffix │ │ suffix │
│ "c3" │ │ "d9" │ │ "e1" │
└─────────┘ └────────┘ └─────────┘

Because account addresses are random-looking 40-hex keys, Ethereum’s trie is deep and sparse — most branches have few children. That is why state is expensive: ~200M accounts ⇒ billions of leaf nodes.


Each block references four tries via hashes in the header:

TrieKey → ValuePurpose
State triekeccak(address) → {nonce, balance, storageRoot, codeHash}All account state
Storage triekeccak(slot) → slot valuePer-contract storage (storageRoot points here)
Transaction trieRLP(tx index) → txTransaction list commitment (transactionsRoot)
Receipt trieRLP(tx index) → receiptExecution outcomes (receiptsRoot)
BLOCK HEADER
┌───────────────────────────────┐
│ stateRoot ─────────────┼──▶ State Trie (accounts)
│ transactionsRoot ────────────┼──▶ Tx Trie
│ receiptsRoot ─────────────┼──▶ Receipt Trie
│ (storageRoot per account ────┼────▶ Storage Trie, via state trie leaf)
└───────────────────────────────┘

A Merkle proof is the path of sibling hashes from a leaf to the root. With it, a verifier holding only the state root can check exactly one key/value (eth_getProof produces these).

// Ask a full node for a proof
// eth_getProof(address, storageKeys, "latest")
// → {accountProof: [...hashes...], storageProof: [...hashes...],
// balance, nonce, codeHash, storageHash}

Verification cost grows with trie depth (~tens of hashes), not with the size of the chain — which is why light clients and bridges can verify single entries cheaply.


28.5 Why State Grows (and Why Root Is the Problem)

Section titled “28.5 Why State Grows (and Why Root Is the Problem)”
  • Every new account/contract/slot adds nodes; pruning deletes referenced-but-now-unreachable trie nodes only when they fall off the retained window (--history / ancient data).
  • A full (unpruned) node stores all retained trie changes; an archive node keeps every historical trie version.
  • Verkle Trees (EIP-2935/6800 family) replace MPTs with a vector-commitment structure — ~2 KB universal proofs and radically less witness data — which is on Ethereum’s roadmap specifically because MPT proofs are large.

“The state root is the chain’s fingerprint for ‘what is true right now’. Every account and every contract slot lives in the Ethereum MPT (state trie + storage tries, plus tx and receipt tries per block). Proofs let a verifier check one key against the root in a few dozen hashes. The trie’s size — not block size — is what makes Ethereum nodes heavy, and Verkle is the roadmap answer to that.”


  • Merkle Tries enable efficient state verification
  • MPT compresses sparse 40-hex keys via leaf/extension/branch nodes
  • Blocks commit four roots: state, transactions, receipts (+ per-account storage roots)
  • Proofs verify single entries against the root without full state
  • Trie size drives node storage requirements; Verkle is the planned successor

Last Updated: 2026-09-28