Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Part II · Retracing the ancestors This chapter contains one line of cryptography. Everything else is systems design. The prologue’s claim starts getting cashed here.

In 1991 Stuart Haber and Scott Stornetta were trying to solve a modest problem:

How do you prove a document existed at a particular moment and has not been altered since?

Their answer is the first brick in this book that is not cryptography.

(Satoshi cites them more often in the whitepaper than he cites anyone else.)


4.1 A block is two things

genesis hash: eb7eb7c66dfeb692 ...

Open up Block and there is nothing mysterious in it:

blk.data      = "Alice pays Bob"     # a string
blk.prev_hash = "eb7eb7c66d...4a1f"  # another string, 64 characters
blk.hash()    = h(data + prev_hash)  # concatenate them, hash once

Two fields and one method.

All of the cleverness in this chapter lives in that one line of hash(): it hashes not just this block’s data, but the previous block’s fingerprint as well.

That single move makes every block’s fingerprint contain the entire history behind it.

(The first block has no predecessor, so prev_hash is 64 zeros. That is the genesis block — real Bitcoin’s works the same way, except Satoshi stuffed that newspaper headline into its data.)


block0: data=genesis block    prev=0000000000... hash=eb7eb7c66d...
block1: data=Alice pays Bob   prev=eb7eb7c66d... hash=073bc9e1df...
block2: data=Bob pays Carol   prev=073bc9e1df... hash=0a5190f7bc...
block3: data=Carol pays Dave  prev=0a5190f7bc... hash=220b015c68...

Do not let the word “chain” become abstract. It is a Python list:

[block0, block1, block2, block3]

Every element is a Block object, and every object’s prev_hash field holds the hash of the one before it. That is what strings them together.

Once it runs, check one thing in the output: each row’s prev= is exactly the previous row’s hash=.

block0: data=genesis block    prev=0000000000... hash=eb7eb7c66d...
block1: data=Alice pays Bob   prev=eb7eb7c66d... hash=073bc9e1df...
                                   ^^^^^^^^^^ identical to the line above
block2: data=Bob pays Carol   prev=073bc9e1df... hash=0a5190f7bc...
                                   ^^^^^^^^^^ again
block3: data=Carol pays Dave  prev=0a5190f7bc... hash=220b015c68...

“Chain” is not a magic word. It means: each block writes the previous block’s fingerprint into its own body.


4.3 Why it can’t be edited

Now write the checker. It asks exactly one question: does each block’s stored prev-hash still equal the real hash of the block before it?

is the chain valid?: (True, None)

Prints (True, None).

Four lines, and not one of them requires any cryptographic knowledge — it compares two strings for equality. It works entirely because of chapter 1’s avalanche effect.

Play the attacker

before: Alice pays Bob
after : Alice pays Bob one million
still valid?: (False, 2)

Prints (False, 2) — the break was detected at block 2.

Walk through what happened, one step at a time:

  1. You changed block 1’s data

  2. Block 1’s hash() is computed on demand, so it changed immediately (avalanche, chapter 1)

  3. But block 2’s prev_hash was recorded earlier. It did not change.

  4. At i=2, check finds chain[2].prev_hash != chain[1].hash() → break

This is what “immutable” actually means: not that you can’t change it, but that you can’t change it without it showing.

That distinction deserves insisting on. The chain has no mechanism that prevents editing — the line chain[1].data = ... executed perfectly well and Python did not object. What it achieves is: once you’ve done it, anyone can detect it in four lines of code.

This is the first appearance of a pattern that repeats through the whole book:

Bitcoin almost never forbids anything. It makes cheating detectable, or unprofitable.


4.4 Pull one thread and the whole thing unravels

The attacker will not give up there. He’ll try to patch it.

after patching block 2: (False, 3)

Question 1 prints (False, 3) — the break moved from block 2 to block 3.

Why? Because patching block 2’s prev_hash also changed block 2’s hash() (hash() covers data + prev_hash, so touching either one changes the fingerprint). Now block 3’s stored prev_hash no longer matches.

Plug one hole and the next one opens. All the way to the end of the chain.

Question 2’s rebuild_from does make check return True again — the attacker wins.

But notice what it cost him: he had to recompute every single block from the edit point to the tip.

Editing block 1 meant redoing 3 blocks. If the chain were a hundred thousand blocks long and he edited block 5, he would have to redo more than 99,000 of them.

Here is Bitcoin’s central intuition in embryo: Editing one old block forces you to recompute every block after it. Now suppose recomputing a single block is expensive. Then rewriting older history costs more and more. The older the record, the safer it is.

And making “recompute one block” expensive is exactly what the next chapter does.

Haber and Stornetta built the chain. Adam Back built the expense. Satoshi put them together.


4.5 The ledger

What you wroteField
h() — SHA-256Cryptography (chapter 1’s, one line, nothing new)
class Block — data plus the previous hashSystems design
“each block writes the previous fingerprint into itself”Systems design
check() — tamper detectionSystems design
rebuild_from() — the attacker’s repairThe attacker’s view

For the first time, the ledger tips to the right.

The only cryptography in this chapter is h(), and even that was imported from chapter 1. Everything else — linking blocks, detecting tampering, understanding the cascading cost — is systems design.

This is the prologue’s claim showing up as code for the first time:

The genuinely original part is not the cryptography. It is everything else.

Hashing was a brick somebody else made. “Use hash pointers to turn data into a self-verifying history” is an idea, and it required no new mathematics whatsoever.


Next

Proof-of-work.

You will build the expense described above: a puzzle that is hard to solve and trivial to check.

Then you get to be a miner, and watch the number of attempts climb as you add difficulty.

Along the way you’ll find something that surprises most people: mining is far luckier than you’d think. That fact explains why real Bitcoin sometimes produces two blocks in two minutes and sometimes makes you wait forty.