bitcoin-kernel
A conformance specification for Bitcoin's consensus rules.
In plain terms
This is a standard, in the ordinary sense. It has the same parts a web or internet standard has.
- The rules
- What makes a Bitcoin header, block and payment valid. 34 of them, listed in §4.
- The specification
- This document. The rules in §4 are generated from the machine-readable ruleset, so the words here and the running code cannot drift apart.
- The test suite
- Real test vectors that exercise the rules, including Bitcoin Core's own script vectors (§5).
- Conformance
- An implementation conforms if it agrees with every vector. Pass them all and you conform (§3).
- Implementations
- bitcoin-kernel, a library that runs these rules on Node and in the browser (§6). Others may follow.
- The demo
- The whole suite, run live in your browser, on the home page.
1. Abstract
This document specifies the consensus rules a Bitcoin full node applies when deciding whether to accept a block, together with a conformance test suite. It exists so that independent implementations can be checked against a single, machine-readable definition of the rules. The normative rules in §4 are generated directly from the engine's source-of-truth ruleset (validate.jsonld); the test vectors in §5 are run, in full, by the live demo.
2. Status of this document
This is a living document, generated from source on each build. It is an independent community project and is not affiliated with, nor endorsed by, Bitcoin Core or the Bitcoin project. It describes the rules as implemented by bitcoin-kernel, an independent implementation, and is offered as a cross-check, not as a replacement for Bitcoin Core. Where this document and the Bitcoin network disagree, the network is correct and this document is in error.
3. Conformance
The key words MUST, MUST NOT, REQUIRED, SHALL, SHOULD, and MAY in this document are to be interpreted as described in RFC 2119.
An implementation conforms to this specification if and only if, for every test vector defined in §5, the verdict it computes (accept or reject) equals that vector's expected verdict.
A conforming validator MUST implement every rule in §4. It MUST reject any header, block, or transaction that a normative rule rejects, and MUST NOT reject one that every applicable rule accepts. A conforming validator SHOULD demonstrate conformance by running the test suite; the live demo does so in the browser and reports any divergence. Rules marked with a BIP MUST be enforced only at and after that BIP's activation height, as the corresponding rule records.
4. Rules
Each rule below is normative. A conforming validator MUST enforce it. Rules are grouped by the stage at which a node applies them, and each carries its originating BIP, where one exists, and the error code a node raises when the rule is violated.
4.1 Header rules
Constraints every block header must satisfy: it links to the previous block, its proof of work meets the target, its timestamp is within range, its version is allowed at that height, and its difficulty is correct, including the testnet4 timewarp fix.
| Rule | Requirement | BIP | Error code |
|---|---|---|---|
| rule-header-prev-link | The header's prevBlockHash must equal the hash of the preceding header, extending a known chain. | bad-prevblk | |
| rule-header-pow | The header's hash, interpreted as a 256-bit number, must not exceed the target encoded by its bits field. | high-hash | |
| rule-header-difficulty | The bits field must equal the expected target: unchanged within a difficulty epoch; at each 2016-block boundary, retargeted by the previous epoch's actual timespan (clamped to [targetTimespan/4, targetTimespan*4]), never easier than powLimit. | bad-diffbits | |
| rule-header-mtp | The header's timestamp must be strictly greater than the median timestamp of the previous 11 blocks. | time-too-old | |
| rule-header-time-future | The header's timestamp must be no more than maxFutureBlockTime (2 hours) ahead of network-adjusted time. | time-too-new | |
| rule-header-version | Obsolete block versions are rejected once the corresponding deployment is buried: version >= 2 from params.bip34Height, >= 3 from params.bip66Height, >= 4 from params.bip65Height. | BIP 34, 66, 65 | bad-version |
| rule-header-timewarp | On networks with the timewarp fix (testnet4), the first block of a difficulty epoch may not be timestamped more than params.maxTimewarp (600s) before its predecessor, closing the timewarp difficulty exploit. Skipped on networks without the fix. | BIP 94 | time-timewarp-attack |
4.2 Transaction rules
Standalone validity of a transaction: it has at least one input and one output, no value exceeds the 21 million coin limit, and it never spends the same output twice.
| Rule | Requirement | BIP | Error code |
|---|---|---|---|
| rule-tx-inputs-nonempty | inputs-nonempty | bad-txns-vin-empty | |
| rule-tx-outputs-nonempty | outputs-nonempty | bad-txns-vout-empty | |
| rule-tx-size | A single transaction may not exceed the block weight limit. | bad-txns-oversize | |
| rule-tx-output-values | Each output value must be in [0, maxMoney], and so must their sum. | bad-txns-vout-toolarge | |
| rule-tx-inputs-unique | No two inputs of a transaction may spend the same outpoint. | bad-txns-inputs-duplicate | |
| rule-tx-prevouts | A coinbase has exactly one input with the null outpoint; a non-coinbase transaction must have no null outpoints. | bad-txns-prevout-null | |
| rule-tx-coinbase-script | A coinbase scriptSig must be between 2 and 100 bytes. Skipped for non-coinbase transactions. | bad-cb-length |
4.3 Block rules
Internal consistency of a block: exactly one coinbase, placed first; the merkle root commits to every transaction; no duplicate transaction ids; and the size and signature-operation budgets are respected.
| Rule | Requirement | BIP | Error code |
|---|---|---|---|
| rule-block-coinbase-first | The block must be non-empty and its first transaction must be the coinbase. | bad-cb-missing | |
| rule-block-coinbase-single | No transaction after the first may be a coinbase. | bad-cb-multiple | |
| rule-block-merkle-root | The merkle root recomputed from the transactions' txids must equal the header's. | bad-txnmrklroot | |
| rule-block-tx-duplicates | No two transactions in the block may share a txid (guards the merkle mutation of CVE-2012-2459). | bad-txns-duplicate | |
| rule-block-sigops | Total legacy signature operations (CHECKSIG counts 1, CHECKMULTISIG counts 20, over all scriptSigs and scriptPubKeys) times the witness scale factor (4) may not exceed params.maxBlockSigopsCost. | bad-blk-sigops | |
| rule-block-weight | weight-limit | bad-blk-weight | |
| rule-block-transactions | Every transaction in the block passes the transaction phase. | bad-txns |
4.4 Contextual block rules
Validity of a block against the chain state it extends: coinbase height and maturity, timelocks and sequence locks, every input unspent and available, non-negative fees, the witness commitment, and successful execution of every input script.
| Rule | Requirement | BIP | Error code |
|---|---|---|---|
| rule-blockctx-bip34-height | The coinbase scriptSig must begin with a push of the block height. Active from params.bip34Height. | BIP 34 | bad-cb-height |
| rule-blockctx-finality | Every transaction must be final at this block: lockTime of zero, or lockTime below the block height (if < 500,000,000) or below the median-time-past (otherwise), or all input sequences final (0xffffffff). | BIP 113 | bad-txns-nonfinal |
| rule-blockctx-sequence-locks | BIP68 relative lock-time (enforced via BIP112). For a transaction of version >= 2, each input whose nSequence leaves the disable flag (bit 31) clear imposes a relative lock on the coin it spends. Height-based locks (type flag, bit 22, clear) require spendingHeight >= coinHeight + (nSequence & 0xffff). Time-based locks (bit 22 set) require (nSequence & 0xffff) << 9 seconds to have elapsed since the spent coin's median-time-past; that per-coin time context is not available to a light or pruned validator, so time-based locks are skipped honestly rather than guessed. A height-based lock whose coin height is unknown (out-of-window) is likewise skipped. Coinbase transactions and version-1 transactions are exempt. | BIP 68, 112 | bad-txns-nonfinal |
| rule-blockctx-inputs-available | Every non-coinbase input must spend a coin that exists and is unspent at this point in the block's execution (no double spends within or across the block's transactions). | bad-txns-inputs-missingorspent | |
| rule-blockctx-coinbase-maturity | A coinbase coin may be spent only at least params.coinbaseMaturity (100) blocks after its creation. In a pruned window the rule fails on a provably premature spend of a window coinbase; spends of out-of-window coinbase coins, whose height is unknowable, skip. | bad-txns-premature-spend-of-coinbase | |
| rule-blockctx-fees | For every non-coinbase transaction, the sum of input values must be at least the sum of output values. | bad-txns-in-belowout | |
| rule-blockctx-coinbase-amount | The coinbase outputs may not exceed the block subsidy plus the block's total fees. | bad-cb-amount | |
| rule-blockctx-witness-commitment | If any transaction has witness data, the coinbase must carry a commitment output (OP_RETURN 0xaa21a9ed…) equal to dsha256(witnessMerkleRoot || witnessReservedValue). Active from params.segwitHeight. | BIP 141 | bad-witness-merkle-match |
| rule-blockctx-scripts | Every resolvable non-coinbase input's unlocking script (and witness) must satisfy its prevout's locking script, with real signature verification: ECDSA for legacy/segwit-v0 paths (legacy and BIP 143 sighash) and Schnorr for taproot key and script paths (BIP 340/341/342). The only honest skips remaining are pruned-away prevouts (taproot additionally needs every input's prevout, as its sighash commits to all of them) and unknown future witness/leaf versions. | mandatory-script-verify-flag-failed |
4.5 Light client (SPV) rules
Verification of a merkle inclusion proof: a light client can confirm that a transaction is committed to by a block header without possessing the whole block.
| Rule | Requirement | BIP | Error code |
|---|---|---|---|
| rule-spv-pow | The embedded header's hash must satisfy its own target. (Chain membership and cumulative work are established by the header phase.) | high-hash | |
| rule-spv-tree | The partial merkle tree must be well-formed: every hash and every flag bit consumed exactly once (modulo byte padding), no identical left/right branches (CVE-2012-2459), and a non-zero transaction count. | bad-merkle-tree | |
| rule-spv-merkle-root | The root reconstructed from the partial tree must equal the header's merkleRoot. | bad-txnmrklroot | |
| rule-spv-inclusion | The transaction being verified must appear among the proof's matched txids. Skipped when no target transaction is specified. | tx-not-included |
5. Test vectors
The test suite is the set of vectors below. They are vendored into this repository under engine/vectors/ and are run, in full, by the live demo. An implementation conforms (§3) if it produces each vector's expected verdict.
| Vector set | Description | Rules |
|---|---|---|
| script_tests.json | Bitcoin Core's own script test vectors: valid and invalid spends, with the expected verdict for each. About 1,191 are run. | §4.2, §4.4 |
| genesis-block.json | The Bitcoin genesis block: its header, proof of work, merkle root and coinbase. | §4.1, §4.3 |
| retarget-32256.json | The first difficulty retarget in Bitcoin history (block 32,256). | §4.1 |
| retarget-modern.json | A modern difficulty retarget (block 951,552). | §4.1 |
| header-chain-100k.json | Consecutive mainnet headers around height 100,000, validated in sequence. | §4.1 |
| pruned-window-100000.json | A real mainnet block with its transactions, for structural and contextual checks. | §4.3, §4.4 |
| merkleblock-block100000.json | A merkle inclusion proof for a transaction in block 100,000. | §4.5 |
| merkleblock-first-segwit.json | A deeper merkle inclusion proof (the first-ever SegWit transaction). | §4.5 |
The script vectors are Bitcoin Core's own script_tests.json, used unmodified. The remaining vectors are real mainnet data, independently verifiable on any block explorer.
6. Implementations
bitcoin-kernel is the reference implementation: a JavaScript library, with no runtime dependencies, that implements every rule in §4. The same code runs on a Node server and in a browser tab; the demo runs it client-side. The interpreter and engine are at engine/codec/ and developed in the open at github.com/bitcoin-desktop/schema.
An implementation in any language conforms to this specification (§3) if it produces the expected verdict for every vector in §5. Reporting partial conformance (for example, the script rules only) is RECOMMENDED where full conformance is not yet reached.
7. References
- S. Bradner, RFC 2119: Key words for use in RFCs to Indicate Requirement Levels.
- Bitcoin Core,
src/test/data/script_tests.json(the script test vectors). - Bitcoin Improvement Proposals referenced by the rules above: