freecoding.school100% FREE · NO SIGNUP
Proof PeaksISSUE #11 of 38

merkle patricia tries · ethereum state deep

ZeekaVSThe Collision
Zeeka saysEthereum stores all state in a Merkle-Patricia trie: a hash tree keyed by hex nibbles whose single root commits to every account — change one balance and the root changes.

Ethereum's world state — every account balance, nonce, and contract storage slot — is held in a Merkle-Patricia trie. Keys are keccak-hashed and walked one hex nibble at a time through branch, extension, and leaf nodes, and the whole structure rolls up to a single 32-byte state root in the block header. That root is a cryptographic fingerprint of the entire state.

The payoff is verifiability: a light client that holds only the root can be handed a short Merkle proof and confirm any single account without the full database. And because hashing is one-way and bottom-up, editing one balance changes its leaf hash, which changes its parent, all the way to a new root. The demo (a simplified hash trie) shows that root-binding property directly.

Power-ups you unlock

The Collision attacks — common mistakes

Boss battleHash four accounts to a root, change one balance, and show the root changes.

Example code

<!doctype html><html><head><meta charset="utf-8"></head>
<body style="background:#06040d;color:#e6e0ff;font-family:monospace;padding:20px"><pre id="o"></pre>
<script>
// simplified state trie: accounts → leaf hashes → pairwise → one root.
// (real Ethereum uses a hex Merkle-Patricia trie; this shows root-binding.)
const H=(s)=>{ let h=2166136261>>>0; for(const c of (''+s)){ h^=c.charCodeAt(0); h=Math.imul(h,16777619); } return (h>>>0).toString(16).padStart(8,'0'); };
function root(state){
  let lvl = Object.entries(state).sort().map(([k,v])=>H(k+'='+v));
  while(lvl.length>1){ const nx=[]; for(let i=0;i<lvl.length;i+=2) nx.push(H(lvl[i]+(lvl[i+1]||''))); lvl=nx; }
  return lvl[0];
}
const s1 = { alice:100, bob:50, carol:75, dave:20 };
const s2 = { ...s1, bob:51 };                      // bob's balance changes by 1
const r1 = root(s1), r2 = root(s2);
document.getElementById('o').textContent = [
  'state root (bob=50) = ' + r1,
  'state root (bob=51) = ' + r2,
  'one balance changed → root changed? ' + (r1 !== r2),
  'a light client verifies the whole state from just this 8-char root'
].join('\n');
</script></body></html>
▶ Open the interactive comic issue
‹ Kzg Commitments · Polynomial OpeningsVerkle Trees · Stateless Witnesses ›