Block Frame Format
A block pushed over a stream connection needs an agreed layout for its header, its parts and its first transaction. This defines it.
Summary
- Why
- A receiver needs every byte of a block, including its coinbase and merkle path, delivered in one pass without a separate fetch, and needs to parse it using fixed-width fields rather than variable-length integers.
- What
- BRC-144 is a wire format for pushing a complete block, header through coinbase merkle path, as a single self-contained byte stream frame.
- How
- A sender writes the 80-byte header, then transaction count, size, subtree count, the ordered 32-byte subtree hashes, the full coinbase transaction, the block height, and finally the coinbase merkle path, so a receiver can parse the stream in that fixed order and assemble the block.
What this lets you do
- Send a whole block over a byte stream with nothing left to fetch afterward
- Parse fixed-width big-endian counts instead of variable-length integers for block metadata
- Carry the coinbase transaction inline since it can't travel as a standalone transaction
- Rebuild the block merkle root from ordered subtree hashes plus the coinbase
- Recover block height without digging it out of the coinbase script
Written by claude-sonnet-5 from the specification text. Where the two differ, the original is correct.
Reference for an AI
Everything an assistant needs to answer questions about BRC-144 accurately, including what it depends on.
The specification
Abstract
This BRC specifies the push wire form of a block — the 80-byte block header, block-level counts, the ordered list of subtree roots the block references, the full coinbase transaction, the block height, and the coinbase merkle path — for delivery and ingest over a byte stream. It carries everything a receiver needs to assemble and validate the block without a follow-up fetch. All frame integers are fixed-width big-endian; consensus-defined payloads (the header, the coinbase transaction, the BUMP) keep their native serialisation.
Copyright
This BRC is licensed under the Open BSV License.
Motivation
A block commits to its transactions through a header and names the subtrees it references in order — the block↔subtree association that binds independently delivered subtrees (BRC-143) into a block and fixes their order for merkle assembly.
In an announce/pull system a node is notified of a block (hash, height, a fetch URL) and then pulls the full block on demand. A push delivery has no fetch URL: the block arrives whole and unsolicited, so the frame carries the complete block body inline. Its field sequence mirrors the block serialisation a node already ingests — header, counts, subtree roots, the full coinbase, height, and the coinbase BUMP — with each variable-length integer replaced by a fixed-width big-endian field. The coinbase is carried in-band because it cannot be delivered as a loose transaction (a node rejects a standalone coinbase on its transaction path) and the block assembly needs its bytes.
Specification
Frame layout
All frame integers are big-endian. Hashes are in internal byte order. The embedded block header, coinbase transaction, and coinbase BUMP keep their native serialisations.
| Size | Field | Notes |
|--------|-------------------|--------------------------------------------------------------------|
| 80 | BlockHeader | Standard 80-byte block header (below). |
| 8 | TransactionCount | uint64 BE. Total transactions committed by the block. |
| 8 | SizeInBytes | uint64 BE. Total serialized block size. |
| 8 | SubtreeCount (M) | uint64 BE. Number of subtree roots that follow. |
| 32 × M | SubtreeHashes | Ordered subtree merkle roots, each 32 bytes. |
| * | Coinbase | Full coinbase transaction (BRC-12), self-delimiting by structure. |
| 8 | Height | uint64 BE. Block height. |
| 8 | CoinbaseBUMPLen | uint64 BE. Byte length of the coinbase BUMP that follows. |
| * | CoinbaseBUMP | BRC-74 merkle path of the coinbase; present only when `CoinbaseBUMPLen > 0`. |
Fixed prefix through SubtreeCount is 104 bytes; SubtreeHashes, Coinbase,
and CoinbaseBUMP are variable. The Coinbase has no length prefix — it is
self-delimiting by transaction structure (version, input/output vectors,
locktime), so a reader parses it and resumes at Height.
The field order and semantics mirror the block body a node serialises natively; this frame is that body with fixed-width big-endian counts in place of variable integers.
Block header (80 bytes)
The standard block header, consensus byte layout:
| Offset | Size | Field | Encoding |
|---|---|---|---|
| 0 | 4 | Version | uint32 little-endian |
| 4 | 32 | Previous block hash | SHA256d, internal byte order |
| 36 | 32 | Merkle root | SHA256d of the tx tree, internal byte order |
| 68 | 4 | Timestamp | uint32 little-endian (Unix seconds) |
| 72 | 4 | nBits | uint32 little-endian (compact difficulty target) |
| 76 | 4 | Nonce | uint32 little-endian |
BlockHash = SHA256d(BlockHeader) — the receiver computes it from the 80 bytes;
there is no separate block-hash field. The previous-block hash (bytes 4–35) gives
chain context intrinsically. Block height is not present in a block header (it
appears in the coinbase per BIP-34) and is carried explicitly as the Height
field so the receiver need not extract it.
Coinbase and subtree association
SubtreeHashes is ordered to match the producer's subtree enumeration — the order
used to assemble the block merkle root from the subtree roots. A block's first
subtree (BRC-143) carries the 0xFF × 32 coinbase placeholder at its
first node; the receiver substitutes the coinbase transaction carried here into
that slot when it reconstructs the block.
The coinbase is the full transaction, not just its identifier: a node rejects a loose coinbase on its transaction-ingest path, so it is delivered only here, and block assembly consumes its bytes directly.
Identity
Block identity is BlockHash = SHA256d(BlockHeader). The block's committed merkle
root (header bytes 36–67) is the value a receiver reproduces from the ordered
subtree roots and the coinbase; there is no separate identifier field.
References
- BRC-143: Subtree Data Frame Format — the subtrees this block orders; the block↔subtree association lives here, not in the subtree frame
- BRC-74: BSV Unified Merkle Path (BUMP) Format — the
CoinbaseBUMPpayload - BRC-12: Raw Transaction Format — the coinbase transaction body
Constants Reference
| Name | Value | Description |
|---|---|---|
| BlockFramePrefix | 104 | Header + TransactionCount + SizeInBytes + SubtreeCount, in bytes |
| BlockHeaderSize | 80 | Block header, in bytes |