Overview — Project 5: Bitcoin Mini-Chain
Project 4 · askr closed Phase 1: you called someone else’s network, streamed untrusted bytes, and made the borrow checker prove they were safe to hold. Phase 2 turns the question inward — instead of trusting a server, you build a system where nobody has to be trusted. Project 5 is a Bitcoin-style mini-chain: a ledger that lets strangers who have never met agree on who owns what, with no bank, no admin, and no central database. By the end you’ll have built — and understood from the inside — the one invention that made digital money possible.
The problem Bitcoin actually solved
Section titled “The problem Bitcoin actually solved”Digital cash sounds easy until you try it. A coin is just data, and data copies for free. So what stops me from spending the same coin twice — sending it to you, then sending the identical bytes to someone else before anyone notices? That’s the double-spend problem, and for decades the only fix was a trusted third party: a bank whose ledger is the single source of truth. Everyone trusts the bank not to lie, not to get hacked, not to freeze your account.
Bitcoin’s 2008 insight was a way to get a single agreed-upon ledger without that trusted party — using cryptography to prove ownership and Proof-of-Work to make rewriting history prohibitively expensive. This project builds the smallest version that still teaches the whole idea:
double-spend without a bank? │ ├── prove ownership → ECDSA signatures over secp256k1 (day 18) ├── track who owns what → the UTXO set: spend = remove a coin (day 17) ├── one tamper-evident order → blocks chained by hash (day 16) ├── make history costly → Proof-of-Work + the most-work rule (day 19) └── agree with no server → a P2P node; peers converge (day 20)What you’re building
Section titled “What you’re building”A real, runnable crate at rust/btcmini/. It is pure Rust — secp256k1 comes from the
k256 crate with no C dependency — and the only concurrency is
std threads, exactly like kvlite in Project 2. By Day 20 it mines blocks,
moves coins between keypairs, rejects double-spends and forged signatures, and runs a TCP node where two
processes sync to the same chain:
$ cargo run -- demo genesis mined: 000075699d81c057 block 1 mined (nonce 3673); the work is the search for it alice balance = 50 block 2 mined: alice paid bob 30 (fee 1) alice balance = 70 bob balance = 30 double-spend rejected: double-spend or unknown output: 7d5a81eb…:0 chain valid: height 3, total work 12288The five days
Section titled “The five days”| Day | Page | You build | The Rust / the chain idea it forces |
|---|---|---|---|
| 16 | Blocks & hashing | block headers chained by hash | double-SHA-256, newtypes, why tampering is detectable |
| 17 | The UTXO model | transactions + the UTXO set | enums, HashMap, conservation; double-spend = a missing row |
| 18 | Keys & signatures | keypairs that sign & verify | k256/ECDSA, addresses as pubkey hashes; ownership = a signature |
| 19 | Proof-of-Work | mining + the most-work rule | targets, the mining loop, how strangers agree on one history |
| 20 | A P2P node | a std::net node + mempool | thread-per-connection, broadcasting, two peers converging |
Each day teaches its idea, then has you build that slice into the companion crate. Type the code, run it, and break it on purpose — a rejected double-spend and a failed signature are not errors, they’re the lesson landing.
Why a mini-chain is the right teacher
Section titled “Why a mini-chain is the right teacher”A blockchain is the rare program where a bug is not an inconvenience but a theft. That raises the stakes on exactly the things Rust is built to protect: an unchecked integer overflow can mint money from nothing (it actually happened to Bitcoin in 2010), a data race in the node can corrupt the ledger, a reused signature nonce can leak a private key. Holding all of that correct at once is what makes the domain such a good forcing function for the language.
The thread, doubled
Section titled “The thread, doubled”This project weaves two questions on every page. The playbook’s recurring one — what does building this force you to understand, and what is Rust’s compiler protecting you from? — meets the chain’s: what problem did Bitcoin actually solve? They turn out to be the same shape of question. Bitcoin replaces trust in a person with trust in rules that are expensive to break; Rust replaces trust in a programmer with rules that are impossible to break (memory safety, data-race freedom), checked at compile time. Both are systems for getting safety without having to trust anyone. Building one in the other is the point.
Begin with Day 16 · Blocks & Hashing →