Programming the Blockchain in C#

Programming the Blockchain in C# cover

Programming the Blockchain in C#, by Nicolas Dorier, Bill Strait and Adam Ficsor, teaches Bitcoin development through NBitcoin, the open-source .NET library Dorier created. The authors maintain this Second (Community) Edition on GitHub under a Creative Commons Attribution-ShareAlike 3.0 license. Chapters cover transfers, keys, custom spending conditions, output-carried assets and wallet backends on Bitcoin's existing chain. It assumes some C# and comfort with object-oriented and functional programming, but no advanced mathematics. Its object model trains a useful habit: what the chain lets software verify and what a service or issuer must be trusted to do are separate questions.

In the transfer chapters, an OutPoint names a funding output by transaction id and index, and a TxOut holds an amount and the script that governs spending. A spend consumes a whole previous output, so the programmer accounts explicitly for payment, change and fee, which is whatever inputs exceed outputs. The blockchain chapter adds that satisfying a TxOut's script leaves open whether that TxOut exists. A transaction assembled in memory is data. Chain-validating software must also confirm that each input exists and remains unspent and that the spend follows consensus rules, which a local TxOut plus a signature cannot establish. APIs and proofs can report parts of that answer too. The book describes addresses as hashed public keys, a description that applies specifically to legacy P2PKH addresses.

The ownership chapters carry the habit from keys to policies. A two-of-three multisig script is awkward to hand to a payer, so P2SH puts its hash in the output and gives the payer an ordinary-looking address. The work shifts to the spenders: NBitcoin's ScriptCoin needs the redeem script at spend time. If a backup lacks the script and the cosigners' public keys, and neither can be recovered or rederived elsewhere, two willing signers can be unable to build the spend. Ownership here means a spending condition that signatures from particular keys can satisfy, separate from legal title and silent about identity.

The asset chapters hold the strongest material. To the chain, a colored coin is an ordinary output with a small bitcoin value; its meaning as an asset lives in clients that read Open Assets markers and trace transfers back to issuance. The unit tests chapter puts that design in code. After an exercise that hard-codes a ColoredCoin's properties, the authors state that real software must learn an output's color from somewhere and that asking a public API adds a trust dependency. FetchColors derives a transaction's color by loading its parents through a repository interface, computing each recursively and caching results. An in-memory repository lets tests exercise issuance and transfer logic against local fictional fixtures, keeping real funds and public APIs outside the test. The dependency injection also shows how much parent history a checking client must keep.

The same exercise throws NotEnoughFundsException when a transfer needs a second output. In the book's example, the colored input carries too little bitcoin for two small bitcoin outputs, so another bitcoin input covers the gap. Balancing asset quantities supplies no bitcoin for outputs or fees, though a colored input could hold enough in other cases. A wallet that ignores coloring can make a valid bitcoin spend that drops the Open Assets allocation. The transaction history stays on chain, yet under the colored protocol's interpretation those asset units are destroyed. Any external legal claim is a separate question.

The book also keeps the issuer in view: a company can withhold dividends, and a bank can refuse to redeem a bond. A Ricardian contract signed by the issuer fixes the terms a token refers to. Some on-chain breaches would be visible, but whether promised off-chain delivery or redemption happened rests on external facts that a hash and signature alone cannot supply. On proof of burn, the authors reason that a merchant who has destroyed far more bitcoin than any single sale is worth would find fraud unprofitable. Burned coins are a sunk cost, gone whether the merchant cheats or stays honest, so they work purely as a signal; any collateral a buyer might have claimed is already spent. The relevant comparison weighs expected future honest income against the aggregate gain from cheating many buyers at once and leaving, and it turns on whether a fresh identity costs less than the established one is worth. An OP_RETURN message ties the burn to a text label; connecting that label to a real bakery takes outside evidence.

The wallet chapter turns these distinctions into deployment choices. Its list of wallet duties pairs reorgs, conflicts and fee estimation with signing and broadcasting. A pruned node keeps full validation while discarding old blocks. An SPV client checks headers and inclusion proofs and delegates full validation; a hosted-explorer client relies on the server, which may validate fully. A third-party API returns the server's view of the chain and learns which addresses the client queries, and users can change backends. Self-hosting NBXplorer against your own node moves that exposure onto hardware you control, plus responsibility for endpoint security and uptime.

In the chapter's last example, two instances of a payment routine can pick the same outpoints, and the book answers with a retry loop around broadcast. The unspent-coin snapshot is loaded once before the loop, and every retry reuses that original snapshot. Coin selection may choose a different subset on a later attempt, but it draws from that stale snapshot, so conflicting outpoints can recur and the loop guarantees neither progress nor recovery. Reasoning beyond the book, a payment service would want fresh state, reservations on selected outputs, idempotent payment intents and reconciliation for broadcasts with unknown outcomes.

Much of the surrounding material has aged, including tooling recommendations, relay and fee figures, and claims about features NBitcoin then lacked, such as PSBT, now present in NBitcoin's source. The authors present the stealth-address chapter as history, and key-generation passages on mixing entropy and stretching passphrases fall short of current security advice. A chapter on protecting private keys, linked from the table of contents, is missing from this version. Some exercises encourage mainnet practice with real funds; regtest, a test network or the book's in-memory fixtures suit learning better. It best serves C# developers who want to know what each NBitcoin object represents and where trust enters. Check APIs against current NBitcoin source and documentation and the relevant BIPs, and keep Mastering Bitcoin nearby for broader protocol coverage.