Part III · The house: building a chain Economics takes the lead. This is the last piece that makes the machine run itself.
Seven chapters have produced a machine that resists forgery, resists double-spending, and reaches consensus.
And right now it is dead.
Because chapter 7’s longest-chain rule only functions if somebody is burning electricity.
With no miners, work() is all zeros, choose() has nothing to compare, and the entire
consensus mechanism collapses to nothing.
So one question remains, and it is not a technical one:
Why would a miner pay for electricity to maintain a chain that isn’t theirs?
The whitepaper’s answer is Satoshi’s cleverest move.
8.1 Where coins come from¶
Every time a miner produces a block, they may write themselves a fresh note out of nothing. This is the block reward.
INITIAL_REWARD = 50
def make_coinbase(miner, height, reward):
'''The coinbase transaction: coins from nothing, to the miner.'''
return f"[block reward] {reward} coins -> {miner} (block {height})"
print(make_coinbase("miner Alice", 0, INITIAL_REWARD))
print(make_coinbase("miner Bob", 1, INITIAL_REWARD))
[block reward] 50 coins -> miner Alice (block 0)
[block reward] 50 coins -> miner Bob (block 1)
This does two jobs at once:
It gives miners a reason to burn electricity — they are not doing charity, they are getting paid
It is the only way new coins are ever created — no central bank, no printing press
Point 2 deserves a pause. Back in chapter 6 we wrote a mint() function that created coins
from nothing, and at the time that was cheating — it bypassed every check.
The coinbase institutionalizes that cheat: you may create coins from nothing, but only by first producing a block. The right to issue money is welded to proof-of-work.
This is the second appearance of a recurring pattern: Bitcoin does not ban dangerous capabilities. It puts a price on them.
8.2 Halving: why supply has a ceiling¶
If every block paid 50 forever, the supply would inflate without limit. Satoshi’s design: the reward halves periodically.
50 → 25 → 12.5 → 6.25 → … → eventually zero.
def block_reward(height, initial=50, halving_interval=10):
'''Reward at a given height; halves every halving_interval blocks.'''
halvings = height // halving_interval
if halvings >= 64:
return 0 # down to zero
return initial / (2 ** halvings)
for hgt in [0, 5, 10, 15, 20, 25, 30, 35]:
print(f"block {hgt:>2}: reward {block_reward(hgt)} coins")
block 0: reward 50.0 coins
block 5: reward 50.0 coins
block 10: reward 25.0 coins
block 15: reward 25.0 coins
block 20: reward 12.5 coins
block 25: reward 12.5 coins
block 30: reward 6.25 coins
block 35: reward 6.25 coins
(The halving interval is 10 blocks here so you can watch it happen. Real Bitcoin uses 210,000 blocks — roughly four years.)
Now add up every block’s reward:
total = 0
for hgt in range(200):
total += block_reward(hgt)
print("total issued in the first 200 blocks:", round(total, 4))
print("theoretical ceiling (initial x interval x 2):", 50 * 10 * 2)
print("No matter how many blocks are mined, the total approaches this and never exceeds it.")
total issued in the first 200 blocks: 999.999
theoretical ceiling (initial x interval x 2): 1000
No matter how many blocks are mined, the total approaches this and never exceeds it.
This is a geometric series.
Each halving epoch issues 50 × 10 = 500 coins, the next 250, the next 125…
Summed: 500 × (1 + 1/2 + 1/4 + ...) = 500 × 2 = 1000.
Infinitely many blocks, a finite total. That is the arithmetic behind “approaches but never exceeds.”
The real 21 million¶
def bitcoin_total_supply():
'''Real Bitcoin's total supply.'''
total = 0
reward = 50 * 10**8 # work in satoshis to avoid float error
while reward > 0:
total += 210000 * reward # 210000 blocks per halving epoch
reward //= 2 # halve (integer division, eventually zero)
return total / 10**8 # back to coins
print("total bitcoin supply:", bitcoin_total_supply(), "coins")
total bitcoin supply: 20999999.9769 coins
Output: 20999999.9769.
That famous “21 million” is where this arithmetic lands. Nobody picked a round number. It is the consequence of the rule “start at 50, halve every 210,000 blocks.”
Note that reward //= 2 — integer division. That is a real implementation detail:
rewards are denominated in satoshis (one coin = 100 million), and integer division truncates
its way down until one halving produces zero, at which point issuance actually stops.
(So the total is not exactly 21,000,000. It is 20,999,999.9769. The missing fraction is precisely what integer truncation ate along the way.)
Scarcity is designed. No central bank can print one more. A few lines of halving logic lock in “there will only ever be 21 million.”
8.3 The climax: why honesty pays better¶
Chapter 7 showed that with enough hashpower, a 51% attack works. You performed one.
So why is it rare in practice?
Because the incentives make cheating a bad deal. Do the arithmetic.
REWARD = 50
def honest_income(blocks):
'''Honest mining: reward per block.'''
return blocks * REWARD
def attack_ledger(blocks_to_redo, double_spend_amount):
'''A 51% attack: forgo the rewards you could have mined, to steal one double-spend.'''
forgone_reward = blocks_to_redo * REWARD # opportunity cost
stolen = double_spend_amount
return forgone_reward, stolen
# Scenario: overtaking requires re-mining 10 blocks; the double-spend recovers 100.
forgone, stolen = attack_ledger(blocks_to_redo=10, double_spend_amount=100)
print(f"mining honestly for 10 blocks earns: {honest_income(10)} coins")
print(f"attacking: forgo {forgone} coins of honest reward to steal back {stolen}")
print(f"verdict: {'cheating loses money -- not worth it' if forgone > stolen else 'cheating pays -- warning'}")
mining honestly for 10 blocks earns: 500 coins
attacking: forgo 500 coins of honest reward to steal back 100
verdict: cheating loses money -- not worth it
The whole argument is in forgone_reward: opportunity cost.
The hashpower the attacker spends rewriting history could have been mining honestly for pay. Attacking doesn’t just cost electricity — it means giving up the 500 coins he would otherwise have earned.
And what he steals back is 100.
Got enormous hashpower? Mining honestly with it earns more than cheating with it. So rational actors stay honest — not out of morality, but because honesty pays better.
The system does not assume people are good. It arranges for good behaviour to be the most profitable behaviour.
This is the most important conceptual turn in the book. For seven chapters you have been asking “how do I make the bad thing impossible?” This chapter answers: you don’t have to. Making it unprofitable is enough.
YOUR TURN¶
# YOUR TURN:
# 1) When does attacking pay? Raise double_spend_amount and find the tipping point.
forgone, stolen = attack_ledger(10, 600)
print(forgone, stolen, "does attacking pay?:", stolen > forgone)
# Think: this is why large payments wait for more confirmations --
# more blocks to redo means a higher opportunity cost.
# 2) If the reward halves to 25, the attacker's opportunity cost halves too.
# What happens to security?
500 600 does attacking pay?: True
Question 1 tells you what confirmations are actually buying: they raise the attacker’s opportunity cost. A hundred-dollar payment is fine with one confirmation; a million-dollar payment needs you to wait until “the cost of redoing this many blocks” exceeds a million.
Confirmation count is not a safety threshold. It is an exchange rate.
Question 2 is Bitcoin’s genuine long-term worry, and it has no settled answer:
Rewards halve every four years and reach zero around 2140. At that point the opportunity cost approaches zero and miner income is transaction fees only. Can a fee market sustain a large enough security budget?
This is an open question the Bitcoin community has argued over for more than a decade. Chapter 10 has you write fees; chapter 12 shows the fee market forming. This book will not give you an answer, because nobody has one.
8.4 Assembly: a machine that runs itself¶
Put all eight chapters together and run it.
import hashlib
def H(s): return hashlib.sha256(s.encode()).hexdigest()
class Block:
def __init__(self, txs, prev_hash, height, difficulty=3):
self.txs = txs; self.prev_hash = prev_hash
self.height = height; self.difficulty = difficulty; self.nonce = None
def mine(self):
t = "0"*self.difficulty; n = 0
while not H(f"{self.txs}|{self.prev_hash}|{n}").startswith(t): n += 1
self.nonce = n; return self
def hash(self): return H(f"{self.txs}|{self.prev_hash}|{self.nonce}")
def mine_block(chain, miner, user_txs):
'''Mine a block: the first transaction is always the block reward.'''
height = len(chain)
reward = block_reward(height, initial=50, halving_interval=10)
coinbase = make_coinbase(miner, height, reward)
txs = [coinbase] + user_txs
prev = chain[-1].hash() if chain else "0"*64
blk = Block(txs, prev, height).mine()
return chain + [blk], reward
chain = []
miners = ["Alice", "Bob", "Carol"]
earned = {m: 0 for m in miners}
for round_i in range(6):
miner = miners[round_i % 3]
user_txs = [f"user transaction #{round_i}"]
chain, reward = mine_block(chain, miner, user_txs)
earned[miner] += reward
print(f"block {round_i} mined by {miner}, reward {reward} coins, nonce={chain[-1].nonce}")
print("\nminer earnings:", earned)
print("chain length:", len(chain), " -- entirely self-interested, nobody in charge.")
block 0 mined by Alice, reward 50.0 coins, nonce=105
block 1 mined by Bob, reward 50.0 coins, nonce=1456
block 2 mined by Carol, reward 50.0 coins, nonce=3846
block 3 mined by Alice, reward 50.0 coins, nonce=1180
block 4 mined by Bob, reward 50.0 coins, nonce=6839
block 5 mined by Carol, reward 50.0 coins, nonce=373
miner earnings: {'Alice': 100.0, 'Bob': 100.0, 'Carol': 100.0}
chain length: 6 -- entirely self-interested, nobody in charge.
Look at this line inside mine_block:
txs = [coinbase] + user_txsEvery block’s first transaction is always the miner paying themselves. Real Bitcoin works exactly this way — transaction 0 in every block is the coinbase, it has no inputs (coins from nothing), and its output goes to the miner’s address.
It runs. No boss, no central bank, no police.
Each miner mines for their own reward and, as a side effect, maintains the honest chain.
That is Satoshi’s final stitch: self-interest driving honesty.
8.5 The ledger — and an interim total¶
| What you wrote | Field |
|---|---|
make_coinbase() — coins from nothing, to the miner | Economic design |
block_reward() — halving | Monetary policy |
| Supply converging to a finite total | Mathematics (geometric series) |
attack_ledger() — opportunity cost | Game theory |
mine_block() — assembly | Systems design |
Not one line of cryptography in this chapter.
Now total up the first eight:
| Ch | What you built | Field |
|---|---|---|
| 1 | Hashing, commitments | Cryptography |
| 2 | Finite fields, elliptic curves, public keys | Cryptography |
| 3 | ECDSA signing and verification | Cryptography |
| 4 | The hash time-stamp chain | Systems |
| 5 | Proof-of-work | Systems |
| 6 | UTXOs, transactions, double-spend prevention | Systems |
| 7 | Blocks, longest-chain consensus | Systems + game theory |
| 8 | Block rewards, halving, incentives | Economics |
Cryptography occupies the first three chapters and nothing else.
The remaining five — the chain, mining, double-spends, consensus, incentives — are systems, game theory, and economics.
The prologue said:
“Cryptography was his brick supply. Building a bank with no manager out of those bricks was the invention.”
Eight chapters of code have now proved that sentence.
What you understand at this point is already the deepest part of Bitcoin. The remaining ten chapters push this toy toward real engineering — but the core ideas are all in your hands as of this page.
Next¶
Forks and upgrades.
So far every node runs identical rules, because you wrote them and you only wrote one copy.
In the real world there are hundreds of different Bitcoin implementations, in different languages, by different people, spread across tens of thousands of machines that answer to nobody.
With no boss, how do the rules ever change?
The next chapter shows you Bitcoin’s least intuitive and most underrated property: the software may differ; the rules must not. And changing the rules on tens of thousands of independent machines simultaneously, without any authority, turns out to be harder than consensus itself.