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.
Reference for an AI
Everything an assistant needs to answer questions about BRC-144 accurately, including what it depends on.
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.
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 |