Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Bitcoin Protocol Specification

Bitcoin Protocol Specification cover

Bitcoin is the peer-to-peer electronic cash protocol and payment network introduced by Satoshi Nakamoto. This book is generated from the LaTeX specification in this repository.

Read

Scope

This specification covers consensus rules, primitive data structures, serialization, transactions, Script execution, blocks, proof of work, mempool behavior, peer networking, constants, and network parameters.

Introduction

Background

Bitcoin was introduced by Satoshi Nakamoto as a peer-to-peer electronic cash system: a network in which payments can be validated by participants directly, without requiring a financial intermediary to order transactions or prevent double spending (sources: nakamoto-bitcoin). Its core design combines digital signatures, a public append-only history, a proof-of-work timestamp chain, and local validation by independently operated nodes. Transactions spend previously created outputs and create new outputs; blocks commit ordered transaction sets; nodes accept the valid chain with the greatest accumulated proof of work.

The consequence is a protocol whose authority is operational rather than institutional. No server, committee, or publication grants validity to a transaction or block. A block is useful only if economically relevant validating nodes accept it under their consensus rules, and a transaction is final only to the extent that it remains in the accepted proof-of-work history. This makes Bitcoin unusually sensitive to precise definitions: serialization, hash preimages, script evaluation, subsidy, difficulty adjustment, lock-time, witness commitments, and deployment rules are not merely engineering details. They are the boundary between a node that follows the same network and a node that has forked into a different system.

Why this specification exists

Bitcoin does not have a single normative protocol specification in the style of an Internet RFC. Its design is distributed across the original paper, Bitcoin Improvement Proposals, Bitcoin Core source code, release notes, developer documentation, test vectors, and long-running network practice (sources: bitcoin-bips-repo,bitcoin-core,bitcoin-core-v31,bitcoin-developer-reference). That distribution has served Bitcoin well: it keeps proposals reviewable, lets implementations evolve conservatively, and avoids granting authority to a document detached from deployed validation behavior. It also leaves developers with a practical problem. To implement, audit, test, or reason about Bitcoin, they must assemble one protocol from many artifacts that use different levels of precision and often mix consensus, policy, wallet behavior, and operational guidance.

This specification is intended to be the consolidated technical reference for that protocol. It states Bitcoin as data structures, encodings, identifiers, state variables, validation predicates, state transitions, and peer messages. It is not a proposal to change Bitcoin, not a replacement for BIPs, and not an authority over consensus. Where this document conflicts with economically relevant node validation, node validation wins. Its purpose is to make the protocol easier to inspect: one place where the rules needed by independent implementers, reviewers, researchers, and protocol engineers are expressed coherently.

The original Bitcoin paper defines the motivating problem and the high-level mechanism: timestamped proof of work over a chain of transaction-containing blocks (sources: nakamoto-bitcoin). BIPs refine that design by documenting concrete changes, conventions, and interoperability standards, including consensus soft forks, peer services, wallet formats, and application-level conventions (sources: bip-0123,bitcoin-bips-repo). Bitcoin Core is the dominant full-node implementation and the principal executable reference for contemporary validation and relay behavior (sources: bitcoin-core,bitcoin-core-v31). Developer references and generated API documentation are valuable guides, but they are not a complete formal specification of the network protocol (sources: bitcoin-developer-reference).

Other cryptocurrency systems have benefited from standalone protocol specifications. The Zcash protocol specification separates high-level protocol concepts from concrete encodings and upgrade-specific consensus rules (sources: zcash-protocol-spec). Ethereum’s Yellow Paper presents Ethereum as a transaction-based state machine with explicit state-transition functions (sources: ethereum-yellowpaper). The JAM graypaper follows the same tradition of a single coherent formal model for an independently implementable protocol (sources: graypaper-repo). This document applies that style to Bitcoin while respecting Bitcoin’s different governance reality: no paper, repository, or committee has authority to redefine the deployed protocol.

Methodology

The baseline for this draft is Bitcoin Core source, its implemented-BIPs index, and the BIPs cited throughout this document are treated as evidence for contemporary full-node behavior (sources: bitcoin-core-v31). The specification separates three classes of behavior:

  1. Consensus rules: predicates that determine whether blocks and transactions can be accepted into the active chain.

  2. Peer and relay rules: network records and local admission behavior used by nodes to exchange blocks, transactions, addresses, and negotiation state.

  3. Local implementation behavior: storage layout, indexes, caches, RPC surfaces, wallet policy, user interface behavior, and performance choices that may explain Bitcoin Core but are not themselves protocol requirements.

Only the first two classes belong in the main specification. Implementation details are included only when they expose a protocol boundary or prevent an ambiguous reading of consensus or peer behavior. This keeps the document useful as a source-of-truth reference without turning it into a commentary on one code base.

Notation

This section fixes the symbols used across the specification. It defines only shared notation and reusable primitive relations; concrete record layouts, script execution, and signature-message construction are defined in their respective sections.

Types and values

NotationMeaning
$\mathbfBool$Truth values $\false,true$.
$\mathbfByte$The integers $\0,…,255$.
$\mathbfBytes$Finite byte strings.
$\mathbfBytes[n]$Byte strings of exactly $n$ bytes.
$\mathbfN$, $\mathbfZ$Nonnegative integers and integers.
$x:T$Value $x$ has type $T$.
$f:S \to T$Total function from $S$ to $T$.
$f(x)=false$$f$ is undefined, fails, or rejects input $x$.

Sequences and records

NotationMeaning
$[x_0,…,x_n-1]$Ordered sequence with zero-based indexing.
$x[i]$Element at index $i$.
$x
$x

Hex strings are written in display order. Sections that describe serialized fields state whether display order differs from wire order.

Record tables define field order, type, and meaning. Unless explicitly marked as logical state, a record table gives the order used by $E_T$.

Encoding and byte order

For a type or record $T$, $E_T(x)$ is the canonical byte encoding of $x$ as $T$. The partial inverse $E_T^-1(b)$ parses bytes $b$ as $T$ and is undefined for non-canonical or invalid encodings. When parsing succeeds, $E_T^-1(E_T(x))=x$.

$le(b)$ is the unsigned little-endian integer represented by byte string $b$. Fixed-width integer encodings and CompactSize are defined in Section Serialization.

Hashes

Hash values are protocol bytes. Human display strings often reverse the bytes of 256-bit hashes.

$$ \begin{aligned} \mathrm{H}(b) &= \operatorname{SHA256}(\operatorname{SHA256}(b)),\ \operatorname{HASH160}(b) &= \operatorname{RIPEMD160}(\operatorname{SHA256}(b)),\ \operatorname{TagHash}_{tag}(b) &= \operatorname{SHA256}(\operatorname{SHA256}(tag) || \operatorname{SHA256}(tag) || b). \end{aligned} $$

$H$ is hash256 in Bitcoin source material. Taproot and BIP340 Schnorr signatures use $TagHash$ (sources: nakamoto-bitcoin,bip-0340,bip-0341).

For a nonempty list of 32-byte hashes $L$, $MR(L)$ is the Merkle root obtained by repeatedly replacing adjacent pairs $(a,b)$ with $H(a||b)$. If a level has odd length, the final hash is duplicated for that level. $MR([])=false$.

Identifiers

$$ \begin{aligned} txid(tx) &= \mathrm{H}(\mathrm{E}{0}(tx)),\ wtxid(tx) &= \begin{cases} \mathrm{H}(\mathrm{E}{w}(tx)), & \text{witness serialization is used},\ txid(tx), & \text{otherwise}, \end{cases}\ \mathrm{bh}(h) &= \mathrm{H}(\mathrm{E}_{\mathrm{BlockHeader}}(h)). \end{aligned} $$

Chain context

For a chain $C$, $C[k]$ is the block at height $k$, with $C[0]$ as genesis. $height(B)$ is the height of block $B$, and $tip(C)=C[|C|-1]$. $MTP(C,k)$ is the median timestamp of $C[k]$ and its ten nearest ancestors, or all available ancestors when $k<10$.

Cryptographic relations

All public-key signature relations use the secp256k1 group. $ECDSAVerify(Q,m,\sigma)$ is true iff ECDSA signature $\sigma$ verifies digest $m$ under public key $Q$, subject to active script encoding rules. $SchnorrVerify(Q,m,\sigma)$ is the BIP340 verification relation (sources: bip-0066,bip-0340).

Serialization

Bitcoin protocol objects are byte strings with fixed field order. Unless a field table states otherwise, $E_T$ serializes integers in little-endian byte order, vectors with a CompactSize element count, and byte vectors with a CompactSize byte length followed by exactly that many bytes.

Fixed-width primitives

PrimitiveWidthSerialization rule
uint8 / int81 byteByte value as stored.
uint16 / int162 bytesLeast significant byte first.
uint32 / int324 bytesLeast significant byte first.
uint64 / int648 bytesLeast significant byte first.
byte[n]$n$ bytesExactly the given bytes, in index order.
bool1 byteZero is false; nonzero is true unless a field table restricts the value.
uint16020 bytes160-bit hash value.
uint25632 bytes256-bit hash value. Display hex commonly reverses these bytes.

Fixed-width integer fields are serialized in little-endian byte order unless a field table explicitly states otherwise (sources: bitcoin-core-v31).

CompactSize

Bitcoin transaction and block structures use CompactSize integers to encode counts and byte-vector lengths. CompactSize is canonical: a decoder rejects a value encoded with a longer form than necessary.

Value rangeEncodingCanonicality rule
$0 <= n < 253$one byte: $n$First byte is less than 0xfd.
$253 <= n <= 0xffff$0xfd followed by uint16Decoded value must be at least 253.
$2^16 <= n <= 2^32-1$0xfe followed by uint32Decoded value must be at least 0x10000.
$2^32 <= n <= 2^64-1$0xff followed by uint64Decoded value must be at least 0x100000000.

A parser rejects non-canonical CompactSize encodings and any decoded count or length that exceeds the enclosing field’s rule.

Constructors

ConstructorSerialized formUsed for
vector<T>`compactSize count
varbytes`compactSize length
string`compactSize length
witnessStack`compactSize itemCount

Scripts, signatures, public keys, witness items, and network payload fields reuse varbytes in different contexts. Parsing bytes into opcodes, signatures, keys, or scripts is a later semantic step.

For transactions and blocks, $E_0(x)$ is the serialization with witness data stripped, and $E_w(x)$ is the serialization including witness data where such data is defined. Define:

$$ strippedSize(x) = |\mathrm{E}{0}(x)|, \qquad totalSize(x) = |\mathrm{E}{w}(x)|. $$

The consensus weight formula is:

$$ weight(x) = 3 \cdot strippedSize(x) + totalSize(x). $$

For relay and fee accounting, virtual transaction size is the integer ceiling of weight divided by witness scale:

$$ vsize(tx) = \left\lfloor \frac{weight(tx) + \text{\code{WITNESS_SCALE_FACTOR}} - 1} {\text{\code{WITNESS_SCALE_FACTOR}}} \right\rfloor. $$

Block consensus enforces MAX_BLOCK_WEIGHT against weight(block) (sources: bip-0141,bitcoin-core-v31).

Ledger Model

Bitcoin validation is modeled as deterministic state transition over a proof-of-work header graph, available block data, and the active UTXO set. This section fixes the shared relations used by later sections.

State

A full-validation node’s protocol state is:

$$ S = (C,H,B,U,Q,\Pi) $$

SymbolTypeMeaning
$C$ActiveChainOrdered sequence of connected blocks from genesis to the active tip.
$H$HeaderIndexKnown block-header graph keyed by block hash, including height, predecessor, target, timestamp, and accumulated work.
$B$BlockDataSetFull block data known to the node, keyed by block hash.
$U$UTXOSetMap from unspent outpoints to coin records at the active-chain tip.
$Q$MempoolLocally accepted unconfirmed transactions. This is relay state, not consensus state.
$\Pi$PeerSetConnected-peer state and negotiated network capabilities.

Consensus validation reads $C,H,B,U$ and mutates only $C,H,B,U$. Mempool and peer transitions read consensus state but do not define block validity.

Coins

The UTXO set maps outpoints to coins:

$$ U[(txid,n)] = (value, scriptPubKey, height, coinbase). $$

Coin fieldTypeMeaning
valueAmountOutput amount in satoshis. Consensus-valid values are in the money range.
scriptPubKeyScriptLocking script committed by the creating transaction output.
heightuint32Active-chain height of the creating transaction.
coinbaseboolTrue iff the creating transaction is the block coinbase.

Rule context

Let $N$ be the selected network parameter set. For candidate height $h$, candidate block time $t$, and active chain $C$, define:

$$ R = \operatorname{Rules}(N,C,h,t). $$

$R$ is the set of consensus rules active for the candidate object. It includes network constants, buried activation heights, versionbits state, timestamp rules, and script flags. Later sections use $R$ rather than restating whether P2SH, BIP34, strict DER, locktime, sequence locks, SegWit, Taproot, Tapscript, or network-specific timewarp mitigations are active.

Validity classes

ClassMeaning
$DecodeValid_T(b)$$E_T^-1(b)$ succeeds and consumes a canonical encoding of type $T$.
$FormValid(x)$Object $x$ is internally well-formed independent of chain state.
$ContextValid_R(x,C)$Object $x$ satisfies height, time, and active-rule predicates under $R$.
$StateValid_R(x,U)$Object $x$ is valid against the current spendable coin set.
$RelayValid_P(x,Q,U)$Object $x$ is accepted by local relay policy. This is not a consensus predicate.

Transition relations

For a non-coinbase transaction, the transaction transition is:

$$ \operatorname{ApplyTx}(R,U,tx) = \begin{cases} U’, & \text{if } tx \text{ is valid against } U \text{ under } R,\ \bot, & \text{otherwise.} \end{cases} $$

For a block $B_h$ at height $h$, block connection is:

$$ \operatorname{ConnectBlock}(R,(C,U),B_h) = \begin{cases} (C’,U’), & \text{if every block and transaction predicate succeeds,}\ \bot, & \text{otherwise.} \end{cases} $$

Header acceptance, block-data acceptance, chain selection, and reorganization are the consensus transitions defined in Section Consensus. Mempool admission is the local transition defined in Section Mempool.

Invariants

Every accepted active-chain transition preserves:

InvariantStatement
DeterminismFor fixed $N,C,U,B_h$, successful connection produces a unique $C’,U’$.
Outpoint uniquenessAt any active tip, each outpoint appears at most once in $U$.
No double spendA connected transaction consumes each input outpoint at most once, and a connected block consumes each live outpoint at most once.
ConservationA non-coinbase transaction cannot create value: $\sum outputs(tx) <= \sum spent(tx)$.
Issuance boundFor each connected block, $\sum outputs(coinbase) <= subsidy(h)+\sum fees(B_h)$.
Work selectionThe active chain is selected from valid candidates by greatest accumulated work.

Transactions

A Bitcoin transaction consumes previously created outputs and creates new outputs. Consensus validation distinguishes the serialized transaction bytes, the identifiers derived from those bytes, and the contextual checks that depend on the UTXO set and block height.

Identifier and amount primitives

TypeEncodingMeaning
Txiduint256$txid(tx)$, as defined in Section Notation.
Wtxiduint256$wtxid(tx)$, as defined in Section Notation.
OutPoint`Txid
Amountint64Satoshis. Consensus-valid output amounts satisfy $0 <= value <=$ MAX_MONEY.

Transaction records

FieldTypeEncodingMeaning
valueAmountint64Output value in satoshis.
scriptPubKeyScriptvarbytesLocking script.
FieldTypeEncodingMeaning
previousOutputOutPoint36 bytesOutput spent by this input, or the null outpoint for coinbase.
scriptSigScriptvarbytesUnlocking script or coinbase data.
sequenceuint324 little-endian bytesFinality, replacement, and relative-lock field.
FieldTypeEncodingMeaning
versionint324 little-endian bytesTransaction version. Versions 1 and 2 are standard by default relay policy; consensus accepts the integer subject to contextual rules.
inputsvector<TxIn>CompactSize count, then inputsSpent outputs or coinbase input.
outputsvector<TxOut>CompactSize count, then outputsCreated outputs.
witnessesvector<Witness>witness serialization onlyOne witness stack per input when witness serialization is used.
lockTimeuint324 little-endian bytesAbsolute height or time lock.

Witness is vector<varbytes>. It is present only in witness serialization and has exactly one stack per input.

Legacy serialization

$E_0(tx)$, the legacy transaction serialization, is:

$$ version || inputs || outputs || lockTime. $$

PartEncodingMeaning
versionint32Transaction version.
inputCountcompactSizeNumber of inputs.
inputsTxIn[inputCount]Serialized inputs in order.
outputCountcompactSizeNumber of outputs.
outputsTxOut[outputCount]Serialized outputs in order.
lockTimeuint32Absolute lock field.

Witness serialization

$E_w(tx)$, the witness transaction serialization, is:

$$ version || marker || flag || inputs || outputs || witnesses || lockTime. $$

PartEncodingMeaning
marker0x00Distinguishes witness serialization from legacy serialization.
flag0x01Indicates witness data follows. Other nonzero flag bits are invalid.
witnessesWitness[inputCount]One witness stack per input.

The witness form is valid only when at least one witness stack is nonempty. A transaction with no witness data uses legacy serialization for both Txid and Wtxid (sources: bip-0141,bip-0144).

Transaction identifiers

IdentifierDefinition
txid(tx)Defined in Section Notation.
wtxid(tx)Defined in Section Notation.
GenTxidPair of identifier kind and hash used by relay to distinguish txid and wtxid announcements.

Context-free validity

A transaction is context-free valid only if:

  1. it has at least one input and at least one output;

  2. its stripped size satisfies $strippedSize(tx) * WITNESS_SCALE_FACTOR <= MAX_BLOCK_WEIGHT$;

  3. every output value is in range;

  4. the sum of output values is in range;

  5. no two inputs reference the same previous output;

  6. if it is coinbase, it has exactly one input whose previous output is the null outpoint and whose scriptSig length is between COINBASE_SCRIPTSIG_MIN and COINBASE_SCRIPTSIG_MAX bytes; and

  7. if it is not coinbase, no input uses the null outpoint.

Context-free validity does not prove the inputs exist or signatures are valid; those checks require the UTXO set and rule context (sources: bitcoin-core-v31).

Coinbase transaction

A coinbase transaction has exactly one input whose previous output is the null outpoint defined by NULL_TXID and NULL_INDEX. Its input does not spend a UTXO. Its outputs create the block subsidy and collect fees, subject to the coinbase amount rule during block connection.

Coinbase-created outputs require COINBASE_MATURITY confirmations before they may be spent.

Value conservation

For a non-coinbase transaction:

$$ fee(tx) = \sum value(spentInputs(tx)) - \sum value(outputs(tx)). $$

The transaction is invalid if any referenced input is absent, any spent coin is immature coinbase, any output is outside the money range, the output sum is outside the money range, or fee(tx) is negative (sources: bitcoin-core-v31).

Locktime and sequence

lockTime values below LOCKTIME_THRESHOLD are block heights; values at or above that threshold are Unix times. For a candidate block at height $h$ with rule context $R$ and locktime cutoff $t$, define the selected lock boundary:

$$ \ell(tx,h,t)= \begin{cases} h, & tx.\text{\code{lockTime}} < \text{\code{LOCKTIME_THRESHOLD}},\ t, & tx.\text{\code{lockTime}} \ge \text{\code{LOCKTIME_THRESHOLD}}, \end{cases} $$

$$ \begin{aligned} \operatorname{AbsFinal}(tx,h,t) \Longleftrightarrow;& tx.\text{\code{lockTime}}=0 \vee tx.\text{\code{lockTime}} < \ell(tx,h,t) \vee {}\ &\forall i:\ tx.\text{\code{inputs}}[i].\text{\code{sequence}} = \text{\code{SEQUENCE_FINAL}}. \end{aligned} $$

If $R$ includes BIP113, $t=MTP(C,h-1)$; otherwise $t$ is the candidate block timestamp.

If $R$ includes BIP68, relative locks apply only to version-2-or-higher transactions and only to inputs whose sequence does not set SEQUENCE_LOCKTIME_DISABLE_FLAG. For validation view $V$, define $SeqFinal(tx,C,V,h)$ as follows. If $tx.version < 2$, it is true. Otherwise, for each applicable input $i$, let $s_i$ be its sequence value, $v_i=s_i \mathbin& SEQUENCE_LOCKTIME_MASK$, and $c_i$ be the height of the coin spent by input $i$ in $V$. Height locks require:

$$ h > c_i + v_i - 1. $$

When $s_i$ sets SEQUENCE_LOCKTIME_TYPE_FLAG, the input is time locked instead. Let $\tau_i=MTP(C,c_i-1)$. Time locks require:

$$ \operatorname{MTP}(C,h-1) > \tau_i + v_i \cdot \text{\code{SEQUENCE_LOCKTIME_GRANULARITY}} - 1. $$

The transaction satisfies relative locks iff every applicable input satisfies its selected height or time constraint; disabled inputs impose no constraint. If $R$ does not include BIP68, $SeqFinal$ is true (sources: bip-0068,bip-0112,bip-0113,bitcoin-core-v31).

Signature hashes

Signature validation signs a digest derived from the transaction, input index, spent output, hash type, and active script version. Legacy, SegWit v0, and Taproot/Tapscript spend paths use different digest algorithms, specified in Section Script. These digests are consensus-critical because the signature checks validate exactly those bytes.

Script Execution

For each non-coinbase input $i$, spend authorization is the predicate:

$$ \operatorname{Authorize}_{R}(tx,i,coin,u,H) \in {\top,\bot}, $$

where $u=(scriptSig,witness)$ is the unlocking data, $coin$ is the spent UTXO, $R$ is the active rule context, and $H$ is the candidate height and median-time context. Authorization chooses a spend form, constructs a script machine state, and evaluates the committed program.

Spend forms

FormRequired relation
Legacy$Eval_R(scriptSig,BASE)$ then $Eval_R(scriptPubKey,BASE)$; witness empty; final stack top is true.
P2SH$R$ includes P2SH; scriptSig is push-only; final pushed item is redeemScript; $HASH160(redeemScript)$ matches; $Eval_R(redeemScript,BASE)$ succeeds on the pushed stack.
Witness v0 key hashNative witness program length 20; scriptSig empty unless P2SH-wrapped; witness stack is $(signature,pubkey)$; $HASH160(pubkey)$ matches; ECDSA verifies $M_wit0$.
Witness v0 script hashNative witness program length 32; final witness item is witnessScript; $SHA256(witnessScript)$ matches; $Eval_R(witnessScript,WITNESS_V0)$ succeeds on the remaining witness stack.
Taproot key path$R$ includes Taproot; witness stack, after optional annex removal, contains one Schnorr signature; BIP340 verifies $M_tr$ under the output key.
Taproot script pathControl block commits a tapleaf to the output key. Leaf version 0xc0 evaluates as Tapscript; unknown leaf versions succeed after commitment validation.
Unknown witness versionA syntactically valid witness program with no assigned meaning succeeds without execution.

Native witness spends require empty scriptSig; P2SH-wrapped witness spends require scriptSig to push exactly the witness program (sources: bip-0016,bip-0141,bip-0143,bip-0340,bip-0341,bip-0342).

Machine state

Script evaluation is a deterministic transition over:

$$ X=(tx,i,coin,script,pc,S,A,C,R,\sigma,k,\alpha,\beta). $$

FieldMeaning
script, pcProgram bytes and instruction cursor.
$S,A,C$Main stack, altstack, and conditional-execution stack.
$R,\sigma$Active rule context and signature version: $BASE$, $WITNESS_V0$, or $TAPSCRIPT$.
$k$Last executed code-separator position for signature-message construction.
$\alpha$Taproot annex, if present.
$\beta$Tapscript validation-weight budget.

Legacy and witness-v0 execution enforce the script limits named in Appendix Constants. Tapscript removes the script-size and per-script-opcode limits, keeps the stack-item and stack-size limits, and sets:

$$ \beta = \text{\code{TAPSCRIPT_SIGOPS_BUDGET_BASE}}+ \operatorname{serializedWitnessSize}(input). $$

Each executed signature opcode with a nonempty signature subtracts TAPSCRIPT_SIGOPS_COST; negative $\beta$ fails.

Evaluation

$$ \operatorname{Eval}_{R}(script,\sigma,S_0)= \begin{cases} \top, & \text{execution halts successfully with required final stack,}\ \bot, & \text{parsing, execution, resource, or final-stack validation fails.} \end{cases} $$

If $\sigma=TAPSCRIPT$, the script is scanned for any OP_SUCCESSx index before ordinary execution; encountering one succeeds. Otherwise, instructions are decoded left to right and $Step$ is applied while all entries of $C$ are true. Non-control opcodes in inactive branches do not mutate $S$, but parse-stage failures and Tapscript OP_SUCCESSx detection still apply.

Successful termination requires an empty $C$. Legacy and witness-v0 require a nonempty $S$ whose top element casts to true. Tapscript requires exactly one stack element, and that element must cast to true.

Primitive relations

RelationDefinition
$CastToBool(x)$False iff $x$ is empty, zero, or negative zero; true otherwise.
$Num(x,n,min)$Signed-magnitude little-endian integer from byte vector $x$, length at most $n$; if $min$, nonzero encodings must be minimal.
$MinimalPush(op,x)$True iff $op$ is the shortest permitted push form for $x$.
$LockTime(X,n)$Units match tx.lockTime, $n<= tx.lockTime$, and the input sequence is nonfinal.
$Sequence(X,n)$BIP68 is active in $R$, disable/type bits permit comparison, and the input sequence satisfies $n$.
$CheckSig(X,sig,key,h)$Empty signatures return false. Legacy and witness-v0 use ECDSA over secp256k1; Taproot and Tapscript use BIP340 Schnorr. Tapscript key size 0 fails, size 32 verifies, and other nonzero key sizes are unknown key types that pass current consensus.

Signature messages

Signature checks verify exactly one digest:

$$ \begin{aligned} M_{\mathrm{legacy}} &= \operatorname{SigMsg}{\mathrm{legacy}}(tx,i,k,h),\ M{\mathrm{wit0}} &= \operatorname{SigMsg}{\mathrm{wit0}}(tx,i,coin,k,h),\ M{\mathrm{tr}} &= \operatorname{SigMsg}_{\mathrm{tr}}(tx,i,coin,\alpha,k,h). \end{aligned} $$

Hash type bytes are 0x00 DEFAULT for Taproot, 0x01 ALL, 0x02 NONE, 0x03 SINGLE, and 0x80 ANYONECANPAY ORed with non-default forms. ALL, NONE, and SINGLE select the output commitment set; ANYONECANPAY restricts input commitment to the signed input. Legacy out-of-range SINGLE signs uint256::ONE; Taproot out-of-range SINGLE fails (sources: bip-0143,bip-0341,bip-0342).

Opcode classes

Effects use (before -- after) for stack transitions, with the rightmost item at the top of $S$. Parameterized direct byte pushes are represented as a single family; every named opcode is listed separately.

IndexOpcodeEffect
0OP_0 / OP_FALSEPush empty vector.
1-75OP_PUSHBYTES_nPush the next $n$ script bytes.
76OP_PUSHDATA1Next uint8 gives pushed byte length.
77OP_PUSHDATA2Next little-endian uint16 gives pushed byte length.
78OP_PUSHDATA4Next little-endian uint32 gives pushed byte length.
79OP_1NEGATEPush $-1$.
81OP_1Push integer $1$.
82OP_2Push integer $2$.
83OP_3Push integer $3$.
84OP_4Push integer $4$.
85OP_5Push integer $5$.
86OP_6Push integer $6$.
87OP_7Push integer $7$.
88OP_8Push integer $8$.
89OP_9Push integer $9$.
90OP_10Push integer $10$.
91OP_11Push integer $11$.
92OP_12Push integer $12$.
93OP_13Push integer $13$.
94OP_14Push integer $14$.
95OP_15Push integer $15$.
96OP_16Push integer $16$.
IndexOpcodeEffect
97OP_NOPNo effect.
99OP_IF(v --); push $CastToBool(v)$ to $C$.
100OP_NOTIF(v --); push negated condition to $C$.
101OP_VERIFFail.
102OP_VERNOTIFFail.
103OP_ELSEToggle top of $C$; unmatched ELSE fails.
104OP_ENDIFPop top of $C$; unmatched ENDIF fails.
105OP_VERIFY(v --) if true; otherwise fail.
106OP_RETURNFail.
IndexOpcodeEffect
107OP_TOALTSTACKMove top of $S$ to $A$.
108OP_FROMALTSTACKMove top of $A$ to $S$.
109OP_2DROP(x1 x2 --).
110OP_2DUP(x1 x2 -- x1 x2 x1 x2).
111OP_3DUP(x1 x2 x3 -- x1 x2 x3 x1 x2 x3).
112OP_2OVER(x1 x2 x3 x4 -- x1 x2 x3 x4 x1 x2).
113OP_2ROT(x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2).
114OP_2SWAP(x1 x2 x3 x4 -- x3 x4 x1 x2).
115OP_IFDUPDuplicate top item iff it casts true.
116OP_DEPTHPush stack depth.
117OP_DROP(x --).
118OP_DUP(x -- x x).
119OP_NIP(x1 x2 -- x2).
120OP_OVER(x1 x2 -- x1 x2 x1).
121OP_PICK(n -- x); copy stack item $n$ to the top.
122OP_ROLL(n -- x); move stack item $n$ to the top.
123OP_ROT(x1 x2 x3 -- x2 x3 x1).
124OP_SWAP(x1 x2 -- x2 x1).
125OP_TUCK(x1 x2 -- x2 x1 x2).
130OP_SIZE(x -- x len(x)).
IndexOpcodeEffect
135OP_EQUALByte-vector equality.
136OP_EQUALVERIFYEquality followed by VERIFY.
139OP_1ADD(x -- x+1) over $Num(x,4,min)$.
140OP_1SUB(x -- x-1) over $Num(x,4,min)$.
143OP_NEGATE(x -- -x) over $Num(x,4,min)$.
144OP_ABS`(x –
145OP_NOTPush $1$ iff numeric input is zero; otherwise push $0$.
146OP_0NOTEQUALPush $0$ iff numeric input is zero; otherwise push $1$.
147OP_ADD(x y -- x+y) over script numbers.
148OP_SUB(x y -- x-y) over script numbers.
154OP_BOOLANDPush $1$ iff both numeric inputs are nonzero.
155OP_BOOLORPush $1$ iff at least one numeric input is nonzero.
156OP_NUMEQUALNumeric equality.
157OP_NUMEQUALVERIFYNumeric equality followed by VERIFY.
158OP_NUMNOTEQUALNumeric inequality.
159OP_LESSTHANNumeric less-than comparison.
160OP_GREATERTHANNumeric greater-than comparison.
161OP_LESSTHANOREQUALNumeric less-than-or-equal comparison.
162OP_GREATERTHANOREQUALNumeric greater-than-or-equal comparison.
163OP_MINPush the smaller numeric input.
164OP_MAXPush the larger numeric input.
165OP_WITHIN(x min max -- ok) where $min <= x < max$.
IndexOpcodeEffect
166OP_RIPEMD160(x -- RIPEMD160(x)).
167OP_SHA1(x -- SHA1(x)).
168OP_SHA256(x -- SHA256(x)).
169OP_HASH160(x -- HASH160(x)).
170OP_HASH256(x -- H(x)).
171OP_CODESEPARATORSet $k$ to this opcode position.
172OP_CHECKSIG(sig key -- ok) using $CheckSig$.
173OP_CHECKSIGVERIFYCHECKSIG followed by VERIFY.
174OP_CHECKMULTISIG(dummy sig[m] m key[n] n -- ok); enforces historical dummy rule when active; disabled in Tapscript.
175OP_CHECKMULTISIGVERIFYCHECKMULTISIG followed by VERIFY; disabled in Tapscript.
186OP_CHECKSIGADDTapscript only: (sig n key -- n+ok).
IndexOpcodeEffect
176OP_NOP1No effect.
177OP_CHECKLOCKTIMEVERIFY / OP_NOP2If active in $R$, require $LockTime(X,n)$; otherwise no effect.
178OP_CHECKSEQUENCEVERIFY / OP_NOP3If active in $R$, require $Sequence(X,n)$; otherwise no effect.
179OP_NOP4No effect unless redefined by active soft-fork rules.
180OP_NOP5No effect unless redefined by active soft-fork rules.
181OP_NOP6No effect unless redefined by active soft-fork rules.
182OP_NOP7No effect unless redefined by active soft-fork rules.
183OP_NOP8No effect unless redefined by active soft-fork rules.
184OP_NOP9No effect unless redefined by active soft-fork rules.
185OP_NOP10No effect unless redefined by active soft-fork rules.
IndexOpcodeEffect
80OP_RESERVED / OP_SUCCESS80Reserved failure if executed outside Tapscript; Tapscript success.
98OP_VER / OP_SUCCESS98Reserved failure if executed outside Tapscript; Tapscript success.
126OP_CAT / OP_SUCCESS126Disabled failure outside Tapscript; Tapscript success.
127OP_SUBSTR / OP_SUCCESS127Disabled failure outside Tapscript; Tapscript success.
128OP_LEFT / OP_SUCCESS128Disabled failure outside Tapscript; Tapscript success.
129OP_RIGHT / OP_SUCCESS129Disabled failure outside Tapscript; Tapscript success.
131OP_INVERT / OP_SUCCESS131Disabled failure outside Tapscript; Tapscript success.
132OP_AND / OP_SUCCESS132Disabled failure outside Tapscript; Tapscript success.
133OP_OR / OP_SUCCESS133Disabled failure outside Tapscript; Tapscript success.
134OP_XOR / OP_SUCCESS134Disabled failure outside Tapscript; Tapscript success.
137OP_RESERVED1 / OP_SUCCESS137Reserved failure if executed outside Tapscript; Tapscript success.
138OP_RESERVED2 / OP_SUCCESS138Reserved failure if executed outside Tapscript; Tapscript success.
141OP_2MUL / OP_SUCCESS141Disabled failure outside Tapscript; Tapscript success.
142OP_2DIV / OP_SUCCESS142Disabled failure outside Tapscript; Tapscript success.
149OP_MUL / OP_SUCCESS149Disabled failure outside Tapscript; Tapscript success.
150OP_DIV / OP_SUCCESS150Disabled failure outside Tapscript; Tapscript success.
151OP_MOD / OP_SUCCESS151Disabled failure outside Tapscript; Tapscript success.
152OP_LSHIFT / OP_SUCCESS152Disabled failure outside Tapscript; Tapscript success.
153OP_RSHIFT / OP_SUCCESS153Disabled failure outside Tapscript; Tapscript success.
187OP_SUCCESS187Tapscript success; invalid outside Tapscript.
188OP_SUCCESS188Tapscript success; invalid outside Tapscript.
189OP_SUCCESS189Tapscript success; invalid outside Tapscript.
190OP_SUCCESS190Tapscript success; invalid outside Tapscript.
191OP_SUCCESS191Tapscript success; invalid outside Tapscript.
192OP_SUCCESS192Tapscript success; invalid outside Tapscript.
193OP_SUCCESS193Tapscript success; invalid outside Tapscript.
194OP_SUCCESS194Tapscript success; invalid outside Tapscript.
195OP_SUCCESS195Tapscript success; invalid outside Tapscript.
196OP_SUCCESS196Tapscript success; invalid outside Tapscript.
197OP_SUCCESS197Tapscript success; invalid outside Tapscript.
198OP_SUCCESS198Tapscript success; invalid outside Tapscript.
199OP_SUCCESS199Tapscript success; invalid outside Tapscript.
200OP_SUCCESS200Tapscript success; invalid outside Tapscript.
201OP_SUCCESS201Tapscript success; invalid outside Tapscript.
202OP_SUCCESS202Tapscript success; invalid outside Tapscript.
203OP_SUCCESS203Tapscript success; invalid outside Tapscript.
204OP_SUCCESS204Tapscript success; invalid outside Tapscript.
205OP_SUCCESS205Tapscript success; invalid outside Tapscript.
206OP_SUCCESS206Tapscript success; invalid outside Tapscript.
207OP_SUCCESS207Tapscript success; invalid outside Tapscript.
208OP_SUCCESS208Tapscript success; invalid outside Tapscript.
209OP_SUCCESS209Tapscript success; invalid outside Tapscript.
210OP_SUCCESS210Tapscript success; invalid outside Tapscript.
211OP_SUCCESS211Tapscript success; invalid outside Tapscript.
212OP_SUCCESS212Tapscript success; invalid outside Tapscript.
213OP_SUCCESS213Tapscript success; invalid outside Tapscript.
214OP_SUCCESS214Tapscript success; invalid outside Tapscript.
215OP_SUCCESS215Tapscript success; invalid outside Tapscript.
216OP_SUCCESS216Tapscript success; invalid outside Tapscript.
217OP_SUCCESS217Tapscript success; invalid outside Tapscript.
218OP_SUCCESS218Tapscript success; invalid outside Tapscript.
219OP_SUCCESS219Tapscript success; invalid outside Tapscript.
220OP_SUCCESS220Tapscript success; invalid outside Tapscript.
221OP_SUCCESS221Tapscript success; invalid outside Tapscript.
222OP_SUCCESS222Tapscript success; invalid outside Tapscript.
223OP_SUCCESS223Tapscript success; invalid outside Tapscript.
224OP_SUCCESS224Tapscript success; invalid outside Tapscript.
225OP_SUCCESS225Tapscript success; invalid outside Tapscript.
226OP_SUCCESS226Tapscript success; invalid outside Tapscript.
227OP_SUCCESS227Tapscript success; invalid outside Tapscript.
228OP_SUCCESS228Tapscript success; invalid outside Tapscript.
229OP_SUCCESS229Tapscript success; invalid outside Tapscript.
230OP_SUCCESS230Tapscript success; invalid outside Tapscript.
231OP_SUCCESS231Tapscript success; invalid outside Tapscript.
232OP_SUCCESS232Tapscript success; invalid outside Tapscript.
233OP_SUCCESS233Tapscript success; invalid outside Tapscript.
234OP_SUCCESS234Tapscript success; invalid outside Tapscript.
235OP_SUCCESS235Tapscript success; invalid outside Tapscript.
236OP_SUCCESS236Tapscript success; invalid outside Tapscript.
237OP_SUCCESS237Tapscript success; invalid outside Tapscript.
238OP_SUCCESS238Tapscript success; invalid outside Tapscript.
239OP_SUCCESS239Tapscript success; invalid outside Tapscript.
240OP_SUCCESS240Tapscript success; invalid outside Tapscript.
241OP_SUCCESS241Tapscript success; invalid outside Tapscript.
242OP_SUCCESS242Tapscript success; invalid outside Tapscript.
243OP_SUCCESS243Tapscript success; invalid outside Tapscript.
244OP_SUCCESS244Tapscript success; invalid outside Tapscript.
245OP_SUCCESS245Tapscript success; invalid outside Tapscript.
246OP_SUCCESS246Tapscript success; invalid outside Tapscript.
247OP_SUCCESS247Tapscript success; invalid outside Tapscript.
248OP_SUCCESS248Tapscript success; invalid outside Tapscript.
249OP_SUCCESS249Tapscript success; invalid outside Tapscript.
250OP_SUCCESS250Tapscript success; invalid outside Tapscript.
251OP_SUCCESS251Tapscript success; invalid outside Tapscript.
252OP_SUCCESS252Tapscript success; invalid outside Tapscript.
253OP_SUCCESS253Tapscript success; invalid outside Tapscript.
254OP_SUCCESS254Tapscript success; invalid outside Tapscript.
255OP_INVALIDOPCODEFail.

Consensus script behavior is defined by the active P2SH, DER, locktime, sequence, NULLDUMMY, SegWit, Taproot, and Tapscript rules (sources: bip-0065,bip-0066,bip-0068,bip-0112,bip-0113,bip-0147,bip-0341,bip-0342,bitcoin-core-v31).

Blocks

A block is a header plus an ordered transaction vector. The header commits to the previous block header, transaction Merkle root, timestamp, target encoding, and nonce. The transaction vector begins with exactly one coinbase transaction.

Block header

A serialized BlockHeader is exactly 80 bytes in the field order shown:

FieldTypeEncodingMeaning
versionint324 little-endian bytesBlock version. Version bits use the high-bit pattern defined by BIP 9.
previous BlockHashuint25632 bytesDouble-SHA256 hash of the previous block header in protocol byte order.
merkleRootuint25632 bytesMerkle root of transaction identifiers. Witness data is committed separately.
timeuint324 little-endian bytesMiner-supplied Unix timestamp.
bitsuint324 little-endian bytesCompact proof-of-work target encoding.
nonceuint324 little-endian bytesNonce varied during proof-of-work search.

For a block $B$, $bh(B)=bh(B.header)$.

Block record

FieldTypeEncodingMeaning
headerBlockHeader80 bytesSerialized block header.
txCountcompactSizeCompactSizeNumber of serialized transactions.
transactionsvector< Transaction>transaction encodings in orderFirst transaction must be coinbase; all later transactions must not be coinbase.

When witness data is present, block serialization includes each transaction’s witness serialization for relay and block-weight computation. The transaction identifier Merkle root continues to use txid, not wtxid.

Merkle root

For a block transaction vector $[tx_0,…,tx_n-1]$, define:

$$ L = [txid(tx_0), txid(tx_1), \ldots, txid(tx_{n-1})]. $$

A block commits to $MR(L)$. A block with empty $L$ is invalid.

During root computation, a node rejects the duplicated-subtree mutation case: if two identical hashes are paired at a level before an odd-last duplication step, the block is invalid as mutated (sources: bitcoin-core-v31).

Coinbase transaction

The first transaction in each block is the coinbase transaction. It is the only transaction permitted to have a null prevout. No other transaction in a block may be coinbase. The coinbase creates the block subsidy and collects transaction fees; its total output value must not exceed subsidy plus fees when the block is connected.

$Rules(N,C,h,t)$ determines whether the candidate height must be serialized at the beginning of the coinbase scriptSig (sources: bip-0034,bitcoin-core-v31).

Witness commitment

If $R=Rules(N,C,h,t)$ includes SegWit and any transaction has witness data, the coinbase must commit to the witness Merkle root. The witness tree leaves are:

$$ W = [0^{256}, wtxid(tx_1), \ldots, wtxid(tx_{n-1})]. $$

The coinbase input witness contains a 32-byte reserved value $r$. The witness commitment is:

$$ wc = \mathrm{H}(\mathrm{MR}(W) || r). $$

The commitment appears in a coinbase output whose script begins with the SegWit commitment header. If multiple outputs match, the highest-index matching output is used (sources: bip-0141).

Context-free block checks

CheckRule
Transaction countThe block contains at least one transaction.
Transaction count weighttxCount * WITNESS_SCALE_FACTOR <= MAX_BLOCK_WEIGHT.
Coinbase positionTransaction zero is coinbase; no later transaction is coinbase.
Merkle rootHeader merkleRoot equals $MR(L)$ and is not mutated.
Stripped sizestrippedSize(block) * WITNESS_SCALE_FACTOR <= MAX_BLOCK_WEIGHT.
Transaction validityEvery transaction passes context-free transaction checks.
Legacy sigopslegacySigOps(block) * WITNESS_SCALE_FACTOR <= MAX_BLOCK_SIGOPS_COST.

Contextual block checks

For a candidate block at height $h$ extending chain $C$, the previous block is $C[h-1]$, and $R=Rules(N,C,h,time)$.

CheckRule
Previous headerThe previous header exists and is valid for extension.
Median timetime is greater than $MTP(C,h-1)$.
Future timeA node does not accept the block while time is more than MAX_FUTURE_BLOCK_TIME after the node’s current clock time; this is temporary future status, not permanent consensus invalidity.
BIP94 timewarpOn networks enforcing BIP94, the first block of each difficulty-adjustment interval except genesis must have time >= previous.time - BIP94_TIMEWARP_GRACE.
Difficultybits encodes the target required for the height and network.
FinalityAll transactions satisfy $AbsFinal(tx,h,t)$, where $t=MTP(C,h-1)$ if $R$ includes BIP113 and the candidate block time otherwise.
Coinbase heightIf $R$ includes BIP34, the block commits to the correct height in the coinbase.
Witness commitmentIf $R$ includes SegWit and the block has witness data, the block contains the correct coinbase witness commitment.
WeightBlock weight is at most MAX_BLOCK_WEIGHT.

The timestamp checks above follow the active validation predicates for median time past, future-time acceptance, and BIP94 timewarp mitigation (sources: bitcoin-core-v31,bip-0094).

Proof of Work and Chain Selection

Bitcoin blocks commit to proof of work through the block header hash. A block is valid only if its header hash satisfies the target encoded by the header’s nBits field.

Target encoding

The nBits field is a 32-bit compact target. For compact value $c$, let:

$$ e = c \gg 24,\qquad m = c \mathbin{&} 0x007fffff,\qquad s = c \mathbin{&} 0x00800000. $$

The decoded target $C^-1(c)$ is:

$$ \mathrm{C}^{-1}(c) = \begin{cases} m \gg 8(3-e), & e \le 3,\ m \ll 8(e-3), & e > 3. \end{cases} $$

The sign bit is inherited from an older multiple-precision integer format and is not permitted for proof-of-work targets. A decoded target is invalid if any of the following conditions holds:

  • $s$ is set and $m != 0$;

  • $C^-1(c)=0$;

  • decoding overflows 256 bits, which occurs when $m != 0$ and either $e > 34$, or $m > 0xff$ and $e > 33$, or $m > 0xffff$ and $e > 32$;

  • $C^-1(c)$ is greater than the network’s proof-of-work limit.

This compact-target decoding matches contemporary Bitcoin Core consensus validation (sources: bitcoin-core-v31).

The compact encoding $C(T)$ of target $T$ is computed as follows. Let size = ceil(bitLength(T) / 8). If size <= 3, set word = T << 8(3 - size); otherwise set word = T >> 8(size - 3). If word has bit 0x00800000 set, right-shift word by 8 and increment size. Then:

$$ \mathrm{C}(T) = (size \ll 24) \mathbin{|} (word \mathbin{&} 0x007fffff). $$

Consensus proof-of-work targets are nonnegative, so the sign bit is not set in valid block targets.

Proof-of-work check

For header $h$, let:

$$ T_h = \mathrm{C}^{-1}(h.\text{\code{bits}}),\qquad p_h = \mathrm{le}(\mathrm{bh}(h)). $$

A candidate block satisfies proof of work iff $T_h$ is a valid target and:

$$ p_h \le T_h. $$

A node rejects the block header if target decoding fails or if the hash integer is greater than the target. The network-specific proof-of-work limit is part of the chain parameters, not a value inferred from the genesis block (sources: bitcoin-core-v31).

Difficulty adjustment

Mainnet difficulty adjusts over fixed-height intervals. Test networks can have different adjustment behavior. Network-specific exceptions must be cited from chain parameter sources rather than inferred from mainnet behavior.

For mainnet:

$$ \text{\code{DIFFICULTY_ADJUSTMENT_INTERVAL}} = \frac{\text{\code{TARGET_TIMESPAN}}}{\text{\code{TARGET_SPACING}}}. $$

A candidate block’s nBits must equal the value returned by the network’s difficulty-adjustment function for the previous block and candidate timestamp (sources: bitcoin-core-v31).

For networks without the minimum-difficulty exception, the algorithm is:

  1. If the candidate height is not an exact difficulty-adjustment interval, return the previous block’s nBits.

  2. Otherwise, identify the first block in the previous adjustment period. For mainnet this is the ancestor DIFFICULTY_ADJUSTMENT_INTERVAL - 1 blocks before previous.

  3. Compute $\Delta = time(previous) - time(first)$.

  4. Clamp $\Delta$ to the range $$ \frac{\text{\code{TARGET_TIMESPAN}}}{\text{\code{MAX_RETARGET_FACTOR}}} \le \Delta \le \text{\code{TARGET_TIMESPAN}} \cdot \text{\code{MAX_RETARGET_FACTOR}}. $$

  5. Decode the previous period’s base target. On testnet4-like networks with BIP94 enforcement, the base target is taken from the first block of the period; otherwise it is taken from the previous block.

  6. Set: $$ T’ = \frac{baseTarget \cdot \Delta}{\text{\code{TARGET_TIMESPAN}}}. $$

  7. If $T’$ exceeds the network proof-of-work limit, use the proof-of-work limit.

  8. Return $C(T’)$.

On no-retarget networks, the function returns the previous block’s nBits. On networks that allow special minimum-difficulty blocks, the function may return the proof-of-work limit when the candidate timestamp is more than $2 * TARGET_SPACING$ after the previous block; otherwise it searches backward for the most recent non-special difficulty in the current adjustment period (sources: bitcoin-core-v31).

Accumulated work

Nodes compare competing valid chains by accumulated work rather than by block count. This follows the proof-of-work security model described in the Bitcoin whitepaper (sources: nakamoto-bitcoin).

For each accepted header, the node adds the work implied by that header’s target to the predecessor’s accumulated work. Headers and blocks with invalid proof of work are rejected before they can contribute to active-chain selection.

For a valid compact target, Bitcoin Core computes the work represented by a header as:

$$ work(c) = \left\lfloor \frac{2^{256}-\mathrm{C}^{-1}(c)-1}{\mathrm{C}^{-1}(c)+1} \right\rfloor + 1. $$

This is algebraically equivalent to $\lfloor 2^256/(C^-1(c)+1) \rfloor$ while avoiding construction of the unrepresentable integer $2^256$ in a 256-bit integer type (sources: bitcoin-core-v31). The active chain is selected from valid candidates by greatest accumulated work, not by height.

Consensus Validation

Consensus validation determines whether a node may accept a chain history as valid. It instantiates the transition relations from Section Ledger Model for headers, block data, active-chain connection, and reorganization.

Validation relation

Let $N$ be the network parameter set. For candidate block $b$, candidate height $h$, candidate block time $t$, active chain $C$, and UTXO set $U$, let $R=Rules(N,C,h,t)$. A successful connection produces:

$$ (C, U) \xrightarrow{b} (C’, U’) $$

where $C’$ extends or reorganizes $C$ to include $b$, and $U’$ is the UTXO set obtained after applying every transaction in the connected branch. If any consensus check fails, the active pair $(C,U)$ is unchanged.

Header acceptance

A header is accepted into the header graph only if all conditions below hold. Header acceptance does not imply that block transaction data is known or valid.

ConditionRequired rule
UniquenessIf $bh(h)$ is already known, the existing header state is reused.
Previous headerEvery non-genesis header references a known previous header.
Proof of work$le(bh(h)) <= C^-1(h.bits)$.
Target$C^-1(h.bits)$ is valid for the height, network, and difficulty-adjustment interval.
TimestampThe header time is greater than the median timestamp of the previous block and up to ten ancestors. A header whose time is more than MAX_FUTURE_BLOCK_TIME after the node’s current clock time is future-dated and not eligible for active validation until time advances.
BIP94 timewarpOn networks enforcing BIP94, a difficulty-adjustment block other than genesis has time at least previous.time - BIP94_TIMEWARP_GRACE.
Rule context$R$ permits the candidate height, time, version field, and network-specific activation state.
Invalid ancestryA header descending from a known-invalid header is not eligible for best-chain selection.

For each accepted header, the node records height, predecessor, $C^-1(h.bits)$, $bh(h)$, and accumulated work. Accumulated work is the sum of the work represented by each header from genesis through that header.

Block-data acceptance

Full block data is accepted only after the corresponding header is accepted. The following checks are performed before block data can become a candidate for active-chain connection:

CheckRequired rule
Block formThe block has at least one transaction, satisfies the stripped-size, transaction-count, and weight limits in Section Blocks, and the first transaction is the only coinbase transaction.
Merkle rootHeader merkleRoot equals $MR(L)$ for the block’s txid leaves, and the mutated-root condition is rejected.
Transaction formEvery transaction passes context-free transaction checks.
Legacy sigops limitlegacySigOps(block) * WITNESS_SCALE_FACTOR <= MAX_BLOCK_SIGOPS_COST before P2SH and witness sigops are counted during connection.
Contextual finalityEvery transaction satisfies $AbsFinal$ for the candidate block height and locktime cutoff.
Coinbase heightIf $R$ includes BIP34, the coinbase script begins with the candidate height.
Witness commitmentIf $R$ includes SegWit and the block has witness data, the coinbase witness commitment is present and correct.
WeightThe block weight is at most MAX_BLOCK_WEIGHT.

Best-chain selection

Among branches whose headers are valid and whose required block data is available, the selected branch is the valid branch with greatest accumulated work. A candidate branch is not eligible while any block on the path from the active fork to the candidate tip is missing block data or is known invalid.

  1. Choose the highest-work eligible candidate tip.
  2. Find the fork point with the current active chain.
  3. Disconnect active-chain blocks back to the fork.
  4. Connect candidate-branch blocks forward in height order.
  5. If a candidate block is consensus-invalid, exclude that block and its descendants from future selection and retry with the next candidate.

Block connection

Connecting a non-genesis block applies the block’s transactions to a temporary UTXO view whose best block is the previous block hash. The view becomes active only after all checks below pass.

RuleRequired behavior
BIP30 no-overwriteA transaction output must not overwrite an existing unspent outpoint except for the historical BIP30 exceptions and buried rules that make the check unnecessary after BIP34.
Input availabilityEvery non-coinbase input references an unspent coin in the candidate view.
Duplicate spendsA transaction must not spend the same outpoint more than once.
Coinbase maturityCoinbase-created outputs may be spent only after COINBASE_MATURITY confirmations.
Sequence locksEvery non-coinbase transaction satisfies the BIP68 relative-lock predicate from Section Transactions.
Value rangeEvery output and every sum used during validation remains in the money range.
Value conservationFor each non-coinbase transaction, input value is at least output value; the difference is the transaction fee.
Script validityEach input satisfies the previous output’s locking script under the script flags active for the block.
Sigops costTotal block signature-operation cost is at most MAX_BLOCK_SIGOPS_COST.
SubsidyCoinbase output value is at most block subsidy plus total fees.

The genesis block is special: its coinbase transaction is part of the block history but is not connected as a spendable coin by normal block-connection rules.

UTXO transition

For a valid non-coinbase transaction $tx$, let $I(tx)$ be its input outpoints and $O(tx)$ be its outputs indexed by output number. The candidate UTXO set is updated as follows:

$$ U_{after} = (U_{before} \setminus I(tx)) \cup {((txid(tx), n), coin(out_n, height, false)) : out_n \in O(tx)}. $$

For the coinbase transaction, there are no spent inputs, and created outputs are inserted with coinbase = true. Outputs whose value is zero are still outputs and are inserted unless another consensus rule rejects the transaction.

Rule context

$Rules(N,C,h,t)$ determines the script flags and contextual block predicates used for connection. Mainnet consensus rule context includes the buried and deployed rules for P2SH, strict DER signatures, locktime and sequence verification, SegWit, Taproot, and Tapscript when included in $R$ (sources: bip-0016,bip-0065,bip-0066,bip-0068,bip-0112,bip-0113,bip-0141,bip-0143,bip-0147,bip-0341,bip-0342).

Policy-only flags may be stricter for mempool relay, but policy failure is not block invalidity.

Subsidy and fees

The block subsidy is determined by height and network parameters. For mainnet, the subsidy starts at 50 BTC and halves every 210,000 blocks until it reaches zero by integer right shift (sources: bip-0042). The consensus rule for a connected block is:

$$ \sum outputs(coinbase) \le subsidy(height) + \sum fees(noncoinbase). $$

Fees are computed from connected inputs and outputs. A transaction whose output sum exceeds its input sum is invalid.

Undo

Before applying a non-coinbase transaction, a node records the spent coin for each input in input order. The undo record for a block is the ordered sequence of those per-transaction records, excluding the coinbase. Undo is sufficient to restore the previous UTXO set when the block is disconnected; the byte encoding of undo data is not a consensus rule.

Reorganization correctness

A reorganization from old tip $o$ to new tip $n$ is valid only if:

  1. the branch ending at $n$ has greater accumulated work than the current active branch or is otherwise selected by the same greatest-work rule;

  2. every disconnected block is reversed exactly using the UTXO state that existed after that block was connected;

  3. every connected block on the new branch passes normal block connection; and

  4. after the transition, the active UTXO set equals the result of applying the active chain from genesis to $n$.

Transactions removed from disconnected blocks reenter relay only under current mempool policy.

Mempool

The mempool is local, non-consensus state. It is a node’s current set of unconfirmed transactions that the node is willing to keep, relay, and consider for block-template construction. A transaction can be valid in a block and absent from a node’s mempool.

Let $U$ be the active UTXO set. A mempool is:

$$ Q = (M,G,I), $$

where $M$ is a finite map from transaction identifier to mempool entry, $G$ is the dependency graph induced by unconfirmed spends, and $I$ is the set of indexes needed to query entries by transaction identifier, witness transaction identifier, spent outpoint, created outpoint, feerate, and entry time. In equations, $t \in M$ ranges over transactions in the entry map, and $Q \cup \tx$ denotes the mempool obtained by adding $tx$ to $M$ and recomputing $G$ and $I$. For validation against mempool ancestors, define:

$$ \operatorname{View}(Q,U)=U \cup \bigcup_{t \in M}\operatorname{Out}(t). $$

Entry

FieldTypeMeaning
txTransactionSerialized transaction accepted into the mempool.
txid, wtxiduint256Transaction identifiers from Section Transactions.
feeint64Input value minus output value under $View(Q,U)$.
weight, vsizeint64Weight and virtual size from Section Serialization.
sigopsCostint64Signature-operation cost under the selected script rules.
spendsOutPoint setPrevious outputs consumed by tx.
createsOutPoint setOutputs created by tx.
parentsTxid setMempool transactions directly spent by tx.
childrenTxid setMempool transactions that directly spend tx.
entryTime, entryHeightlocal clock, heightAdmission time and active-chain height at admission.

The entry fields are logical fields: an implementation may derive, cache, or index them differently, but externally observable mempool behavior must be equivalent.

Graph Invariants

For a transaction $t$, let $In(t)$ be its spent outpoints and $Out(t)$ be its created outpoints. Direct mempool dependencies are:

$$ \begin{aligned} \operatorname{parents}{Q}(t) &= {u \in M : \operatorname{In}(t) \cap \operatorname{Out}(u) \ne \emptyset},\ \operatorname{children}{Q}(t) &= {u \in M : \operatorname{In}(u) \cap \operatorname{Out}(t) \ne \emptyset}. \end{aligned} $$

A mempool is well-formed relative to $U$ iff:

$$ \begin{aligned} \operatorname{TxAvailable}{Q}(t,U) \Longleftrightarrow;& \forall x \in \operatorname{In}(t): x \in U \cup \bigcup{u \in M \setminus {t}}\operatorname{Out}(u). \end{aligned} $$

$$ \begin{aligned} \operatorname{WellFormed}(Q,U) \Longleftrightarrow;& \forall t \in M:\neg\operatorname{Coinbase}(t) \wedge \operatorname{ContextFreeValid}(t) \wedge \operatorname{TxAvailable}{Q}(t,U) \wedge \ & \forall a,b \in M,\ a\ne b: \operatorname{In}(a) \cap \operatorname{In}(b)=\emptyset \wedge \ & G={(u,t):u \in \operatorname{parents}{Q}(t)} \wedge \operatorname{Acyclic}(G). \end{aligned} $$

The graph order is the spend order: a parent precedes every child. Any block template or package derived from $Q$ must include transactions in a topological order of $G$.

Admission

Admission is a local transition:

$$ Q \xrightarrow[P]{tx,U,H} Q’, $$

where $P$ is the node’s local policy parameter set and $H$ is the next-block height and median-time context. Write $H=(C,h,t)$, where $C$ is the active chain, $h$ is the next block height, and $t$ is the next block locktime cutoff. Let $V_Q=View(Q,U)$. A single transaction admission succeeds iff:

$$ \begin{aligned} \operatorname{Admit}{P}(Q,U,H,tx) \Longleftrightarrow;& tx \notin M \wedge \operatorname{WellFormed}(Q \cup {tx},U) \wedge \ & \operatorname{ConsensusValid}(V_Q,tx,H) \wedge \operatorname{AbsFinal}(tx,h,t) \wedge \operatorname{SeqFinal}(tx,C,V_Q,h) \wedge \ & \operatorname{Policy}{P}(Q,U,tx,H),\ Q’ = Q \cup {tx} \Longleftrightarrow;& \operatorname{Admit}_{P}(Q,U,H,tx). \end{aligned} $$

$Policy_P$ includes node-local standardness, feerate, resource, replacement, package, and denial-of-service rules. Those rules do not define consensus validity; when they are specified, they belong with the transaction, script, package, or relay behavior they constrain.

A package $\pi$ is admitted atomically by applying the same transition to a topologically sorted sequence of transactions. If any member fails, the package transition fails and $Q$ is unchanged.

Removal

Let $B$ be a connected block and $U’$ the UTXO set after connecting it. Let $H’$ be the next-block context after connecting $B$. Connecting $B$ removes every included transaction and every mempool transaction that conflicts with the block:

$$ \begin{aligned} \operatorname{ConnectBlock}(Q,B,U’) = {t \in M:;&t \notin B.\text{\code{txs}} \wedge \ &\operatorname{In}(t) \cap \operatorname{Spent}(B)=\emptyset \wedge \ &\operatorname{ConsensusValid}(\operatorname{View}(Q,U’),t,H’)}. \end{aligned} $$

After removal, all entry indexes and dependency edges are recomputed so that $WellFormed(Q,U’)$ holds.

Disconnecting a block does not automatically restore its transactions to the mempool. The disconnected transactions become admission candidates and may reenter only through the current admission relation under the post-disconnect chain state.

Orphans and Relay View

A transaction with unavailable inputs is not a mempool entry. A node may keep an orphan cache $O$ of such transactions and retry admission when parents become available, but $O$ is local resource state and has no consensus meaning.

Transaction relay announces transactions from $Q$ by txid or wtxid, serves requested transactions if still present, and may filter, delay, or suppress announcements according to local policy. Relay choices do not change the definition of $Q$ (sources: bitcoin-core-v31).

Peer-to-Peer Network Protocol

The P2P protocol transports blocks, transactions, headers, addresses, filters, and relay-control messages between nodes. This section specifies interoperable wire behavior.

Message envelope

Legacy unencrypted Bitcoin P2P messages use a 24-byte header followed by a payload:

FieldTypeMeaning
startbyte[4]Network magic identifying mainnet, testnet, signet, or regtest.
commandbyte[12]ASCII command name padded with zero bytes.
payloadSizeuint32Number of payload bytes.
checksumbyte[4]First four bytes of $H(payload)$.
payloadbyte[]Command-specific serialized payload of length payloadSize.

BIP324 defines an encrypted v2 transport that changes transport framing after negotiation, but command payload semantics remain command-specific (sources: bip-0324,bitcoin-core-v31).

Handshake

A connection becomes usable after version negotiation:

  1. each side sends version;

  2. each side validates network, protocol version, services, timestamp, nonce, and user-agent limits;

  3. each side sends verack; and

  4. optional relay, compact-block, address-relay, filter, and transport features are negotiated by later messages.

version fieldTypeMeaning
versionint32Protocol version offered by the sender.
servicesuint64Service bits offered by the sender.
timestampint64Sender Unix time in seconds.
addrRecvnetwork addressAddress of the receiving peer as understood by the sender.
addrFromnetwork addressAddress of the sender.
nonceuint64Random connection nonce used to detect self-connections.
userAgentstringBIP14 user-agent string.
startHeightint32Sender’s current best height estimate.
relaybool, optionalBIP37 transaction-inventory relay preference when present.

Control and negotiation payloads

MessagePayloadMeaning
verackemptyCompletes version negotiation.
sendheadersemptyRequests direct headers announcements instead of block inventory announcements.
wtxidrelayemptyNegotiates transaction relay by witness transaction identifier.
sendaddrv2emptyNegotiates BIP155 address relay.
pinguint64 nonceLiveness probe.
ponguint64 nonceResponse echoing the received ping nonce.
feefilteruint64 feerateAsks the peer not to announce transactions below the feerate in satoshis per 1000 virtual bytes.

Service flags

FlagBitMeaning
NODE_NETWORK0Peer can serve the full block chain.
NODE_BLOOM2Peer supports BIP37 bloom-filter service.
NODE_WITNESS3Peer supports witness transaction and block relay.
NODE_COMPACT_FILTERS6Peer supports BIP157 compact block filter service.
NODE_NETWORK_LIMITED10Peer can serve at least a limited recent block window.

Service flags advertise capability. A node must still validate responses and apply local resource limits.

Inventory and object retrieval

Inventory relay announces objects by type and hash. A peer requests announced objects with getdata; the responder sends the corresponding object or a notfound response when unavailable.

RecordFieldsMeaning
InventoryVectortype:uint32, hash:uint256Identifies a transaction, block, filtered block, compact block, witness transaction, or witness block.
invvector< InventoryVector>Announces available objects.
getdatavector< InventoryVector>Requests announced objects.
notfoundvector< InventoryVector>Reports requested objects not available from the responder.

Witness inventory types request serialization that includes witness data. A peer that has not negotiated witness support must not rely on receiving witness objects from that connection (sources: bip-0144).

Inventory typeValueObject requested or announced
MSG_TX1Transaction by txid.
MSG_BLOCK2Block without requiring witness serialization.
MSG_FILTERED_BLOCK3BIP37 filtered block.
MSG_CMPCT_BLOCK4BIP152 compact block.
MSG_WITNESS_TX$2^30 + 1$Transaction including witness data, identified by txid request type with witness flag.
MSG_WITNESS_BLOCK$2^30 + 2$Block including witness data.
MSG_FILTERED _WITNESS_BLOCK$2^30 + 3$Filtered block including witness data.

Header and block synchronization

Headers synchronize chain work before full block data. A locator is a sequence of block hashes, newest first, stepping back from a known tip toward genesis.

Messages getheaders and getblocks carry a locator and stop hash. Message headers returns block headers in forward order, each followed by CompactSize zero. Message block carries serialized full block data. A node must validate proof of work, linkage, target, timestamp, and deployment context for received headers before using them for chain selection.

RecordFieldsEncoding rule
BlockLocatorversion, hashesint32 version followed by vector<uint256> locator hashes.
getheaders/ getblocksversion, locator, stopHashint32, locator vector, then uint256 stop hash.
headers itemheader, txCount80-byte block header followed by CompactSize zero. A nonzero count is invalid for headers.

Compact block relay

BIP152 compact blocks reduce block-relay bandwidth by sending a header, short transaction identifiers, selected prefilled transactions, and requesting any missing transactions (sources: bip-0152).

Message sendcmpct negotiates compact-block mode and announcement preference. Messages cmpctblock, getblocktxn, and blocktxn carry the compact block and missing-transaction exchange. Compact reconstruction is an optimization only. The reconstructed full block must pass the same block validation rules as any received block message.

RecordFieldsEncoding rule
Compact Blockheader, nonce, shortIds, prefilledTxHeader, uint64 nonce, CompactSize count plus 6-byte short ids, then vector<PrefilledTx>.
PrefilledTxindexDelta, txCompactSize differential index from the previous prefilled transaction, then full transaction.
getblocktxnblockHash, indexesBlock hash followed by CompactSize differential transaction indexes.
blocktxnblockHash, transactionsBlock hash followed by transaction vector.

Address relay

Legacy address records and BIP155 address records use different encodings:

RecordFieldsEncoding rule
NetAddress NoTimeservices, address, portuint64 services, 16 address bytes, then uint16 port in big-endian network byte order. Used inside version.
NetAddress Legacytime, services, address, portuint32 time plus NetAddressNoTime. Used by addr.
AddrV2time, services, networkId, address, portuint32 time, CompactSize services, uint8 network id, CompactSize address length, address bytes, then big-endian port.

Messages addr and addrv2 relay legacy and BIP155 address records. Message sendaddrv2 announces BIP155 address-relay support, and getaddr requests known peer addresses subject to local rate limits. Address relay is unauthenticated gossip. Received addresses are hints, not validated reachability claims (sources: bip-0155).

Light-client services

Bitcoin P2P includes two optional light-client service families:

ServiceMessagesStatus
BIP37 bloom filtersfilterload, filteradd, filterclear, merkleblockOptional peer service; disabled unless a node chooses to provide bloom-filter support.
BIP157/158 compact filtersgetcfilters, cfilter, getcfheaders, cfheaders, getcfcheckpt, cfcheckptOptional compact-filter service for clients that verify filters against block-filter headers.

These services do not change block or transaction validity (sources: bip-0037,bip-0157,bip-0158).

MessagePayload fieldsEncoding rule
filterloadfilter, hashFuncs, tweak, flagsvarbytes, uint32, uint32, uint8.
filteradddatavarbytes.
filterclearemptyClears the peer’s BIP37 filter state.
merkleblockheader, total, hashes, flagsBlock header, uint32 total transactions, vector<uint256> hashes, and flag bytes.
getcfilterstype, startHeight, stopHashuint8, uint32, uint256.
cfiltertype, blockHash, filteruint8, uint256, varbytes.
getcfheaderstype, startHeight, stopHashuint8, uint32, uint256.
cfheaderstype, stopHash, prevHeader, filterHashesuint8, two uint256 values, then vector<uint256>.
getcfcheckpttype, stopHashuint8, uint256.
cfcheckpttype, stopHash, headersuint8, uint256, vector<uint256>.

Acknowledgements

Bitcoin protocol was invented by Satoshi Nakamoto and has been advanced, maintained, and secured by generations of Bitcoin Core developers, reviewers, maintainers, researchers, miners, node operators, and users; we thank them for their contributions. This specification is a derivative reference work over their protocol design, implementation, review, and maintenance.

Appendix A. Constants

ConstantValue
COIN100,000,000 satoshis
MAX_MONEY21,000,000 $*$ COIN
WITNESS_SCALE_FACTOR4
MAX_BLOCK_WEIGHT4,000,000 weight units
MAX_BLOCK_SIGOPS_COST80,000
COINBASE_MATURITY100 blocks
SUBSIDY_HALVING_INTERVAL210,000 blocks
NULL_TXID$0^256$
NULL_INDEX0xffffffff
COINBASE_SCRIPTSIG_MIN2 bytes
COINBASE_SCRIPTSIG_MAX100 bytes
LOCKTIME_THRESHOLD500,000,000
SEQUENCE_FINAL0xffffffff
SEQUENCE_LOCKTIME_DISABLE_FLAG$1 \ll 31$
SEQUENCE_LOCKTIME_TYPE_FLAG$1 \ll 22$
SEQUENCE_LOCKTIME_MASK0x0000ffff
SEQUENCE_LOCKTIME_GRANULARITY512 seconds
MAX_SCRIPT_ELEMENT_SIZE520 bytes
MAX_SCRIPT_SIZE10,000 bytes
MAX_OPS_PER_SCRIPT201
MAX_STACK_SIZE1,000 items
MAX_SCRIPT_NUM_SIZE4 bytes
MAX_LOCKTIME_NUM_SIZE5 bytes
MAX_PUBKEYS_PER_MULTISIG20
TAPSCRIPT_SIGOPS_BUDGET_BASE50
TAPSCRIPT_SIGOPS_COST50
TARGET_SPACING600 seconds
TARGET_TIMESPAN1,209,600 seconds
DIFFICULTY_ADJUSTMENT_INTERVAL2,016 blocks
MAX_RETARGET_FACTOR4
MAX_FUTURE_BLOCK_TIME7,200 seconds
BIP94_TIMEWARP_GRACE600 seconds

These constants are specified by deployed BIPs and Bitcoin Core consensus (sources: bip-0068,bip-0094,bip-0112,bip-0113,bip-0141,bip-0342,bitcoin-core-v31).

Appendix B. Mainnet Parameters

This appendix collects network parameters and historical consensus exceptions that are inputs to $Rules(N,C,h,t)$. Mainnet is the default network for this specification.

Mainnet parameters

ParameterValue
Genesis hash000000000019d6689c085ae165831e93 4ff763ae46a2a6c172b3f1b60a8ce26f
Genesis Merkle root4a5e1e4baab89f3a32518a88c31bc87f 618f76673e2cc77ab2127b7afdeda33b
Message startf9 be b4 d9
Subsidy halving intervalSUBSIDY_HALVING_INTERVAL
Proof-of-work target spacingTARGET_SPACING
Proof-of-work target timespanTARGET_TIMESPAN
Bech32 human-readable partbc

Other networks, including testnet, testnet4, signet, and regtest, have distinct genesis blocks, proof-of-work limits, retargeting exceptions, message-start bytes, ports, address prefixes, and activation parameters. Their rules are not inferred from mainnet.

Historical exceptions

ExceptionRule
Genesis coinbaseThe genesis block’s coinbase transaction is part of the block history but its output is not inserted into $U$ by normal block connection.
BIP30 duplicatesHistorical duplicate-transaction cases are handled by the BIP30 no-overwrite rule and its deployed exceptions. Outside those exceptions, creating an output whose outpoint is already unspent is invalid.
Buried activationsMainnet rules whose activation heights are buried in contemporary software are represented by $Rules(N,C,h,t)$, not by live versionbits state.
Future-dated blocksA block whose timestamp is more than MAX_FUTURE_BLOCK_TIME after the node’s current clock is temporarily ineligible for active validation, not permanently invalid.

Signet uses a block signature challenge in the witness commitment payload. Testnet4 and regtest can enforce BIP94 timewarp mitigation through network parameters; mainnet does not set that parameter in the Bitcoin Core 31.0 baseline (sources: bip-0030,bip-0034,bip-0094,bip-0325,bitcoin-core-v31).

Appendix C. Remote Procedure Calls (RPC)

TODO