Beersy
BRC-144

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.

Jeff Harrischanged 2 Aug 20264 min read
header+countssubtrees+coinbheightpayload0

Summary

Why
A receiver needs every byte of a block, including its and , 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, 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 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-level counts, the ordered list of roots the block references, the full transaction, the block height, and the coinbase — 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 ) keep their native serialisation.

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:

OffsetSizeFieldEncoding
04Versionuint32 little-endian
432Previous block hashSHA256d, internal byte order
3632SHA256d of the tx tree, internal byte order
684Timestampuint32 little-endian (Unix seconds)
724nBitsuint32 little-endian (compact difficulty target)
764Nonceuint32 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

Constants Reference

NameValueDescription
BlockFramePrefix104Header + TransactionCount + SizeInBytes + SubtreeCount, in bytes
BlockHeaderSize80Block header, in bytes
Was this helpful?

Search Beersy

Search standards by number, title, author or topic