Programming Bitcoin, Jimmy Song's 2019 O'Reilly book, teaches the protocol by having the reader build a small Python library from the arithmetic upward. Its fourteen chapters run from finite fields and elliptic curves through signatures, serialization, transactions, Script and pay-to-script-hash, then on to blocks, the peer network, simplified payment verification, Bloom filters and Segwit. The exercises carry a practical argument: a Bitcoin user's security consists of specific computations, and a programmer who writes them can see which ones a wallet performs locally and which it borrows. That makes the book a strong choice for developers who want the protocol at the level of bytes and equations, provided they treat its code as a teaching instrument with stated boundaries.
The book expects a reader who can already write Python. This assessment rests on close reading of the elliptic curve cryptography, Script, transaction and closing chapters, with the rest described from the preface and table of contents. Each of the first three turns a word that wallet interfaces use loosely, such as signature or valid, into a procedure with defined failure conditions.
The elliptic curve cryptography chapter in the author's pinned repository derives ECDSA from point addition and scalar multiplication on secp256k1. A private key e defines the public point P = eG. In the chapter's classroom version, the signer picks a nonce k, takes the raw x coordinate of kG as r, and computes s from the digest z, r, e and k; verification recombines z, r, s and P into a point whose x coordinate must equal r. Standard ECDSA is stricter: r is that x coordinate reduced modulo the group order n, and the verifier rejects any r or s outside 1 to n minus 1, rejects a recombined point at infinity, and reduces that point's x coordinate modulo n before comparing it with r. Song's code keeps two moduli apart, placing coordinates in the field of the prime p and signing arithmetic modulo n. For real use, the derivation deserves more trust than the classroom implementation.
What a valid signature establishes is narrower than wallet language suggests. It binds one digest to the public key P, and under ECDSA's security assumptions nobody without e should be able to sign a new digest. It does not prove that whoever presents it holds the key today, since signatures can be copied and replayed, and legal ownership is a separate argument. The same algebra makes the nonce the operational center of key security. Anyone who learns k for a signature can solve for e, and one k used on two different digests yields e as well. Song warns that his random number source suits teaching only, then switches to deterministic nonces following RFC 6979, which derives k from the key and the digest. This shows why a weak random generator in a signing device can disclose the key, while a deterministic signer repeating the same signature for the same key and digest reveals nothing new.
Song's Script chapter applies the same habit to spending conditions. An output's locking script states a predicate, the spender supplies data meant to satisfy it, and every validating node runs the check. In pay-to-pubkey-hash, the output commits to a 20-byte hash160 of a public key; the spender reveals the key and a signature, and the script fails unless the key matches the hash and the signature verifies against the transaction digest. Because the hash hides the key until it appears in a spend or elsewhere, the transaction chapter links address reuse to lost privacy and to the end of that extra layer. Leaving loops out of Script reads as a cost argument as well: every full node executes every spend it validates, so bounded execution keeps the price of checking strangers' transactions predictable.
Its evaluator also shows the book's candor about abstraction. For readability the code joins the two scripts into one command list, and a warning box explains that consensus runs the spender's script first, then the output's script on the resulting stack, so the spender's commands cannot rewrite the lock. Bitcoin Core's interpreter keeps that separation and ties it in a comment to an early vulnerability. Noticing that gap teaches the library's most portable skill: locating the line between a model that explains a mechanism and the implementation that enforces it.
The transaction creation and validation chapter connects authorization to a concrete payment. Its P2PKH example uses the legacy SIGHASH_ALL digest for one input: the code empties every input's script field, places the previous output's locking script into the input being signed, appends a four-byte hash type and applies hash256. Other hash types and script forms follow different rules. For this example, the resulting z binds the signature to the outpoints being spent and to every output's destination script and amount, so changing a payee or amount after signing invalidates it. Song then signs a one-input, two-output payment, computing the fee in sats as inputs minus outputs. A note on quadratic hashing shows the cost side: each input needs a fresh hash over a transaction that grows with its inputs, a burden Segwit's digest later addresses.
Within the same chapter the trust map becomes visible. Input amounts appear nowhere in the spending transaction, and spentness cannot be read from it either. In the book's model, a full node answers both questions from its own UTXO set, while a light client depends on other nodes for the answers. That contrast is the chapter's simplification, not a survey of current light-client designs. Song states that his validator leaves out double-spend detection and other consensus rules, and his Python fee check relies on unbounded integers where Bitcoin Core also requires each output and the running total to stay within its money range. The 2019 testnet and faucet instructions are best read as historical scaffolding.
The closing chapter points to work the library leaves open: hierarchical deterministic wallets under BIP32, the BIP44 path convention, BIP39 mnemonic backups, Lightning payment channels, and open source projects. Readers pursuing those standards should note that a BIP39 phrase encodes entropy plus a checksum, and that a separate PBKDF2 step, with an optional passphrase, derives the seed. The suggested projects, from a testnet wallet to a block explorer, keep turning dependencies into code the builder can read.
Read Programming Bitcoin when the question is what a signature, a script and a transaction each commit to, and what a node must already hold to check them. Expect patience for modular arithmetic. Work through the opening chapters in order, since the signature derivation depends on the field and curve material before it, and leave real keys to maintained wallet software, as the author's warnings advise. O'Reilly lists the first edition on its Programming Bitcoin library page.
