Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@ BRC | Standard
138 | [Single-Use Signed Proofs for Request Authentication](./peer-to-peer/0138.md)
139 | [Multicast Shard Manifest Announcement Protocol](./transactions/0139.md)
140 | [Threshold Key Sharing and Backup via Shamir's Secret Sharing Scheme](./key-derivation/0140.md)
144 | [Block Frame Format](./transactions/0144.md)

## License

Expand Down
1 change: 1 addition & 0 deletions SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
* [Multicast Anchor Transaction Frame Format](./transactions/0134.md)
* [Multicast Block Header Format](./transactions/0135.md)
* [Multicast Shard Manifest Announcement Protocol](./transactions/0139.md)
* [Block Frame Format](./transactions/0144.md)

## Scripts

Expand Down
117 changes: 117 additions & 0 deletions transactions/0144.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# BRC-144: Block Frame Format

Jeff Harris (jeff@lightweb.net)

## 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](./0143.md)) 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.

```text
| 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](./0143.md)) 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](./0143.md) — the subtrees this block orders;
the block↔subtree association lives here, not in the subtree frame
- [BRC-74: BSV Unified Merkle Path (BUMP) Format](./0074.md) — the `CoinbaseBUMP`
payload
- [BRC-12: Raw Transaction Format](./0012.md) — the coinbase transaction body

## Constants Reference

| Name | Value | Description |
| ----------------- | ----- | ------------------------------------------------- |
| BlockFramePrefix | 104 | Header + TransactionCount + SizeInBytes + SubtreeCount, in bytes |
| BlockHeaderSize | 80 | Block header, in bytes |
1 change: 1 addition & 0 deletions transactions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@ BRC | Standard
134 | [Multicast Anchor Transaction Frame Format](./0134.md)
135 | [Multicast Block Header Format](./0135.md)
139 | [Multicast Shard Manifest Announcement Protocol](./0139.md)
144 | [Block Frame Format](./0144.md)