> For the complete documentation index, see [llms.txt](https://bsv.brc.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bsv.brc.dev/transactions/0143.md).

# Subtree Data Frame Format

Jeff Harris (<jeff@lightweb.net>)

## Abstract

This BRC specifies the push wire form of a **subtree** — an ordered list of transaction node hashes plus the merkle root that identifies it — for delivery and ingest over a byte stream. A subtree names its member transactions by hash; a receiver reconstructs the subtree and verifies it against the carried root. All frame integers are fixed-width big-endian; there is no length prefix beyond the node count.

## Copyright

This BRC is licensed under the Open BSV License.

## Motivation

A subtree is a batch of transactions committed by a merkle root, and a block references its subtrees in order. In an announce/pull system a receiver fetches a subtree **by its root hash** — the root is the request key, carried out-of-band in the request path — and the transferred bytes are a bare list of 32-byte node hashes.

A **push** delivery has no request path: the subtree arrives unsolicited, so the identifying root must travel **in-band**. BRC-143 is that frame — the merkle root followed by the ordered node hashes — and nothing a receiver recomputes locally. Per-node fee and size, the aggregate totals, and the conflict set are deliberately omitted: a receiver's transaction-meta store supplies fee and size, and validation does not consume the others on the ingest path, so carrying them would only inflate an already large object.

## Specification

### Frame layout

All frame integers are big-endian. Node hashes are carried in internal (`chainhash`) byte order — not display order.

```
| Offset | Size   | Field             | Notes                                                                    |
|--------|--------|-------------------|--------------------------------------------------------------------------|
| 0      | 32     | SubtreeMerkleRoot | Merkle root of the node hashes: the subtree identity and verify target.  |
| 32     | 8      | NodeCount (N)     | uint64 BE. Number of node hashes that follow. Delimits the body.         |
| 40     | 32 × N | NodeHashes        | Ordered node hashes, each 32 bytes. Includes the coinbase placeholder.   |
```

Total header: **40 bytes**. `NodeCount` is the sole delimiter — a reader consumes the 40-byte header, then exactly `NodeCount × 32` bytes.

### Coinbase placeholder

A block's **first** subtree begins with a coinbase placeholder: **32 bytes of `0xFF`** at `NodeHashes[0]`. This is *not* zeros — a zero hash is the merkle padding value, and placing zeros where the coinbase leaf belongs corrupts the root. The placeholder is self-describing and detected **by value**; there is no flag. A non-first subtree carries no placeholder.

### Reconstruction and verification

A receiver rebuilds the subtree through the subtree node API, then verifies:

* For each hash in order: if it equals `0xFF × 32`, insert it as the **coinbase node**; otherwise insert it as an ordinary node, sourcing fee and size from the local transaction-meta store (or zero when only the root is being checked).
* Assert the recomputed merkle root equals `SubtreeMerkleRoot`.

Tree height is derived as `ceil(log2(N))`; the merkle computation pads to the next power of two with zero-hash leaves, and an odd node is hashed with itself. No height or capacity field is carried — it would fight that derivation.

**Do not byte-splice.** This wire frame is not a storage serialization; a receiver rebuilds via the node API and never copies these bytes into a deserializer.

### Member transactions

A subtree references its members by hash and does **not** carry them. A receiver validating the subtree also needs the member transaction bytes (for script/UTXO/parent checks); those are supplied from the receiver's own transaction feed or fetched out of band. BRC-143 proper is hashes-only.

## Identity

Subtree identity is `SubtreeMerkleRoot` — the merkle root over `NodeHashes`, with the coinbase placeholder participating as the first leaf. A receiver recomputes it from the hashes to verify the frame; there is no separate identifier field.

## References

* [BRC-144: Block Frame Format](/transactions/0144.md) — carries the ordered subtree list (the block↔subtree association) that this frame deliberately omits
* [BRC-12: Raw Transaction Format](/transactions/0012.md) / [BRC-30: Transaction Extended Format (EF)](/transactions/0030.md) — the member transactions a subtree references by hash

## Constants Reference

| Name                | Value       | Description                               |
| ------------------- | ----------- | ----------------------------------------- |
| SubtreeHeaderSize   | 40          | Root + NodeCount, in bytes                |
| CoinbasePlaceholder | `0xFF` × 32 | Node-hash value marking the coinbase slot |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://bsv.brc.dev/transactions/0143.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
