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

# Accumulating Right-of-Sale Listings and Purchase Orders

Ty Everett (<ty@projectbabbage.com>)

## Abstract

An active listing is a reusable Bitcoin UTXO. A buyer adds exactly one price increment and creates a recipient-bound purchase receipt. Anyone can withdraw whole revenue quanta to the committed recipients without the seller's cooperation. The seller can split a listing or retire it early using a protected, publicly derived child signing key. After a committed block height, anyone can retire it and distribute its entire value. The identity root private key never signs a Bitcoin transaction or receives a payment.

This pre-adoption replacement defines one exact family, `https://bsv.brc.dev/tokens/0197#revenue-listing-v1`. The two frozen, hand-authored Bitcoin Script programs are the conformance boundary. There is a reserve-only activation stage that verifies all public root-to-child links **once on chain** before a purchase can occur. The active routes are purchase (1), split (2), permissionless payout (4), and retirement (5). Routes 3 and 6 are invalid. Merge and revenue-schedule amendment are outside v1; a changed distribution requires a new descriptor and signed lineage. This family is one concrete exercise of the private-overlay design; separate future BRCs may define other revenue models.

Script does not prove asset authority, seller authorization, chain inclusion, unspentness or private fulfillment. Section 6 mandates domain and lineage validation in addition to Script.

## 1. Descriptor, derivation and genesis

Use [BRC-192](/brc/apps/0192.md) canonical JSON and primitives:

```typescript
type RevenueSchedule = { recipients: { identity: Identity; weight: U32 }[] };
type ListingDescriptor = {
  version: 1; chain: Chain; assetId: Hex32; seller: Identity;
  lineageAnchor: Outpoint; purchasePrice: U64; reserve: U64;
  expiryHeight: U32; termsDigest: Hex32; scriptFamily: string;
  metadataDigest: Hex32; initialRevenue: RevenueSchedule
};
```

`scriptFamily` equals the IRI above. Price and reserve are positive and at most 2100000000000000 satoshis. `expiryHeight` is in 1 through 499999999 and must be disclosed before a buyer funds a purchase. The anchor belongs to the configured chain. `assetId`, `termsDigest` and `metadataDigest` commit to the selected application's asset, offer terms and metadata. `listingId = digest("sale-listing", descriptor)`. A new price, seller, expiry, recipient or weight requires a new signed lineage.

The schedule contains one through eight **distinct** valid compressed secp256k1 identity keys, sorted by their 33 raw bytes. Every weight is 1 through 10000 and their sum `W` is at most 10000. A payout quantum pays recipient `i` exactly `weight[i]` satoshis. Unused metadata slots are zero. Descriptor validation checks order, uniqueness and ranges before genesis and again during lineage validation. The activation Script checks the key links, used weights, unused slots and weight sum; it does not replace descriptor validation.

This transparent profile gives each identity `R` **one reusable child `Q`** for every BRC-197 role and payout:

```
protocolID = [2, "3241645161d8"]
keyID = "brc197 authority"
counterparty = anyone (the generator public key G)
invoice = UTF8("2-3241645161d8-brc197 authority")
t = intBE(HMAC-SHA256(compressed(R), invoice)) mod n
Q = R + tG
```

The derivation follows [BRC-42](/brc/key-derivation/0042.md) and [BRC-29](/brc/payments/0029.md)'s invoice grammar, with `derivationPrefix="brc197"` and `derivationSuffix="authority"`. Repeating this fixed key ID is an explicit, narrow exception to BRC-29's ordinary unique-suffix privacy rule. Identity-to-child linkage is public; this profile makes **no privacy claim**. The seller's child signs split and early retirement. Each recipient's child is the sole destination of that recipient's P2PKH revenue outputs. Wallet remittance must identify both fixed derivation fields, the recipient identity, and `counterparty=anyone` (the generator public key as sender identity). The wallet must verify that the P2PKH hash equals `HASH160(Q)` before crediting or spending the output. An ordinary per-output BRC-29 receiver is not presumed to support this profile.

**Private-key containment is mandatory.** Root and child scalars remain inside a protected wallet/signer and never appear in Script, unlocking data, remittance or an application process. A BRC-100-style signer/consumer boundary must return signatures, never private scalars. Since `t` is public, leakage of one child private scalar reveals the identity root scalar as `d_root = d_child − t mod n`. The activation witness contains only public points, public `t` and signatures computable from public values. Seller authorization of genesis uses [BRC-77](/brc/peer-to-peer/0077.md)'s protocol-derived message-signing child, not the root.

Genesis consumes `lineageAnchor` at input zero and creates exactly one **activation-stage** listing at output zero, valued at reserve. The seller signs a BRC-192 packet of type `sale-genesis`, body `{version:1,listingId:Hex32,genesis:Outpoint}`, authorizing that exact output. No active listing or purchase receipt occurs in genesis. Domain validation checks the anchor, stage bytes and packet. A copied stage or active Script is not an authorized listing.

Activation spends that stage at input zero with at least one external funding input. It creates one active listing at output zero with identical metadata and reserve, then optionally one P2PKH change output. External funding pays the fee. The stage Script verifies all root-to-child links and the exact active output hash. A direct active output that bypasses activation fails lineage validation.

## 2. Frozen Script and linkage proof

Each locking Script is exactly:

```
4d cd 02 || metadata[717] || 75 || program
```

The prefix pushes 717 metadata bytes, then OP\_DROP. The stage program is [activation.hex](https://github.com/bsv-blockchain/BRCs/tree/master/tokens/media/0197/activation.hex) and the active program is [active.hex](https://github.com/bsv-blockchain/BRCs/tree/master/tokens/media/0197/active.hex), decoded without trailing newline. Their literal opcode listings are [activation.asm](https://github.com/bsv-blockchain/BRCs/tree/master/tokens/media/0197/activation.asm) and [active.asm](https://github.com/bsv-blockchain/BRCs/tree/master/tokens/media/0197/active.asm). The [component guide](https://github.com/bsv-blockchain/BRCs/tree/master/tokens/media/0197/COMPONENTS.md) specifies the ordered, reusable opcode fragments, byte offsets and size profile; their concatenation must reproduce the full listings. Independent assemblers must reproduce these bytes exactly. No compiler or contract language is part of the family. The [artifact manifest](https://github.com/bsv-blockchain/BRCs/tree/master/tokens/media/0197/artifact.json) pins component and complete-program lengths and SHA-256 digests.

The activation program is 33406 bytes, SHA-256 `5152517f75ac4159aa5d34211f45ce12cd85386a8d1414169886b0d64dac1dea`; its complete lock is 34127 bytes. The active program is 4906 bytes, SHA-256 `5aff350548d3b420bf1a47b48b38af34bb5ecf28be5c797921c4e2a2cddd8dea`; its complete lock is 5627 bytes. Any byte change requires a new family IRI after adoption.

| Offset          | Field                    | Encoding                                                      |
| --------------- | ------------------------ | ------------------------------------------------------------- |
| 0–5             | marker, version, profile | ASCII `ROSL`, `01`, `01`                                      |
| 6–37; 38–69     | listingId; termsDigest   | raw 32-byte digests                                           |
| 70–77; 78–85    | price; reserve           | uint64le                                                      |
| 86–89           | expiryHeight             | uint32le                                                      |
| 90–122; 123–155 | seller root; child       | compressed points                                             |
| 156             | recipient count          | one byte, 1–8                                                 |
| 157–716         | eight 70-byte slots      | root\[33], child\[33], weight:uint32le; unused slots all zero |

The profile byte is `01` in both stages; **program bytes** identify the stage. Exact inverse parsing checks the full program, metadata, descriptor commitments and padding. Recognizing only a data prefix is insufficient.

Both programs authenticate the caller-supplied full SIGHASH\_ALL | SIGHASH\_FORKID (`0x41`) BIP143 preimage against the actual transaction before using it for introspection. They compare its SHA-256d to the supplied scalar `z`, then check two fixed-nonce ECDSA binders under the public generator `G`. They check the canonical 0x41 hash type, listing input at index zero, the complete 2–8 input prevout vector against authenticated hashPrevouts, scriptCode length, input amount, sequence, locktime and hashOutputs. The Script reconstructs every required output, including amounts, scripts and optional final change, and compares SHA-256d of their exact serialization with hashOutputs. Bitcoin independently enforces input/output conservation. SIGHASH\_SINGLE, NONE and ANYONECANPAY cannot satisfy these checks.

For the linkage proof, let `r2=x(2G)` and `r3=x(3G)` reduced modulo curve order `n`. For claimed scalar `d` and authenticated digest scalar `z`, Script checks low-S DER witnesses `s_i = ±(z+r_i d)/i mod n` and executes OP\_CHECKSIGVERIFY under the claimed point. The two binders use `d=1`, point `G`; activation repeats the pair using `d=t`, point `D=Q−R`. A bounded slope witness proves that `D` is the curve difference of valid compressed `Q` and `R`. Script recomputes the exact public HMAC to check `t`. Thus it verifies `Q=R+tG` without on-chain scalar multiplication or a secret signature. The two distinct `r_i` remove the single-signature ECDSA sign ambiguity; `z=0`, zero signature numerators and the two binder exceptional digest values are rejected. Both `r_i>p−n`, so an alternative curve x-coordinate `r_i+n` is impossible. The [family proof note](https://github.com/bsv-blockchain/BRCs/tree/master/tokens/media/0197/README.md#linkage-proof-boundary) gives the algebra and limits.

An activation builder must precompute and independently execute the complete stage transaction before funding genesis. An exceptional digest can be changed by rebuilding the transaction; a degenerate child requires a new descriptor. Neither permits omitting verification. The family bytes cannot be optimized in place after adoption.

## 3. Purchase and receipts

Operation 1 needs no seller signature. Output zero has the identical active script and `oldValue + purchasePrice`. Output one has value one satoshi and this exact 171-byte locking Script:

```
00 6a 4c a7 || ASCII("ROSL") || 01 || 01
 || listingId[32] || acquisitionId[32] || requestDigest[32]
 || buyerRecipient[33] || termsDigest[32]
```

Script verifies the buyer recipient's curve point against supplied coordinates and commits to the exact receipt. The domain validator also checks that this is the prepared BRC-196 buyer and that the acquisition and request digests match. A different real buyer's valid Script receipt cannot fulfill someone else's acquisition. External funding pays the price increase, receipt and fee; existing listing value is not deducted.

A provider must reject a new preparation once its current chain view is at or beyond expiryHeight and must disclose the height in the standing Offer. A purchase prepared before that cutoff remains subject to its signed BRC-196 delivery and recovery terms even if expiry occurs before confirmation or a later third party retires the successor. Expiry is not a refund or retroactive invalidation of an already valid purchase receipt.

The one-satoshi administrative receipt has exactly 90 script bytes: `00 6a 4c 56` and this 86-byte payload:

```
ASCII("ROSL") || 01 || operation[1] || listingId[32]
 || m:uint32le || n:uint32le || payout:uint64le || commitment[32]
```

It follows all continuing listings. Split's commitment is 32 zero bytes. Payout and retirement commit SHA-256 of all serialized recipient outputs in schedule order. An administrative receipt never creates a purchase right.

## 4. Value-preserving routes

**Split (2)** checks a seller-child transaction signature ending in `41`. Outputs zero and one are identical active scripts with values at least reserve whose sum is **exactly** the old listing value. The receipt has `m=1,n=2,payout=0`. External funding pays receipt and fee. Both successors remain independent branches of the same lineage.

**Payout (4)** needs **no seller or recipient signature**. Any caller chooses positive integer `q`. With `P=qW`, output zero retains the identical active Script and `oldValue−P >= reserve`. Output one is the receipt with `m=n=1,payout=P`. Then exactly one P2PKH output per recipient pays `q×weight[i]` to `HASH160(compressed(child[i]))`. A sub-quantum remainder stays in the listing. The caller funds receipt and fee externally. No alternate destination or seller-only bypass exists.

**Retirement (5)** has no continuing listing. A seller-child `0x41` signature permits early retirement. Without it, anyone may retire with authenticated `nLockTime >= expiryHeight`, `nLockTime < 500000000` and nonfinal sequence on the listing input. Under the pinned BSV node's strict IsFinalTx height comparison, the earliest block for `nLockTime=expiryHeight` is **expiryHeight+1**; post-Genesis OP\_CHECKLOCKTIMEVERIFY is a NOP and is not used. Set `q=ceil(oldValue/W)`, `P=qW`; after the receipt, pay every recipient `q×weight[i]`. External funding supplies the exact top-up `P−oldValue` (0 through `W−1` satoshis), receipt and fee. The full balance, including reserve and remainder, is distributed. Buyers and issuers must resolve purchase/retirement races by exact outpoint.

Finality follows Bitcoin's applicable rules and BRC-192 section 10; it is not an additional zero-locktime/all-final-sequence domain restriction. Constructors SHOULD normally use `nLockTime=0` and `0xffffffff` on every input for activation (0), purchase (1), split (2), payout (4) and seller-signed early retirement (5). Validators MUST also accept other locktime/sequence combinations that satisfy the frozen Script and the applicable Bitcoin finality rules, subject to the remaining domain checks. A nonzero locktime or an input sequence below `0xffffffff` alone does not make a transaction non-final. In particular, a Script-valid payout with `nLockTime=1` and all-final sequences, or with zero locktime and a nonfinal listing or funding sequence, preserves domain lineage when selected as a final spend. Rejecting its successor solely for that construction choice would let a permissionless caller consume a genuine listing into a domain-ineligible successor.

Permissionless expiry retirement (5, empty seller signature) still requires the Script-enforced height `nLockTime` at least `expiryHeight` and below `500000000`, with the listing input's sequence below `0xffffffff`. Every route may otherwise be observed before its locktime matures. Such an otherwise valid candidate is pending finality, not permanently domain-invalid: `nonFinal=false` retains it without provisional selection, while `nonFinal=true` may select it only as nonfinal intent, without consuming the listing, creating a spendable successor or authorizing a wallet action. Once final, either setting may select it under the normal dependency, conflict and selected-chain rules. Verified inclusion is evaluated in the containing block's applicable finality context; a valid settled transition cannot be excluded from lineage merely because it was non-final when first observed or differs from the recommended construction. Genesis authorization, activation, asset authority, exact route outputs and all other domain checks remain required. Neither provisional selection nor later maturation by itself constitutes BRC-196 release evidence.

Every operation consumes one listing at input zero and at least one external funding input, with at most eight total inputs and at most one final standard P2PKH change output. Undeclared outputs fail the hashOutputs comparison. Concurrent consumption of another listing is outside this family. The listing balance cannot pay transaction fees.

## 5. Unlocking ABI

The active program takes fifteen pushed values in this exact order:

```
preimage, prevouts, operation, acquisitionId, requestDigest,
 buyerKey, buyerX, buyerY, units, changeHash, changeAmount,
 adminSignature, z, binderSignature2, binderSignature3
```

The stage program takes 99 public proof values first: seller then eight recipient slots, each with:

```
deltaKey, t, signature2, signature3, rootX, rootY,
 childX, childY, slope, deltaX, deltaY
```

It then takes the same fifteen common values with `operation=0`. At entry the active Script requires stack depth exactly 15 and the stage exactly 114. Unused recipient proof slots are empty stack items, checked by Script. Conforming constructors use push-only unlocking Scripts and minimal pushes/nonnegative Script numbers. Validators execute the actual Bitcoin Script and must not reject an otherwise valid, economically equivalent mined spend solely because a third party used a different unlocking syntax; exact scriptSig bytes are not an authenticated part of the purchase commitment. `preimage` is the complete input-zero 0x41 preimage; `prevouts` is the full serialized prevout vector; `z` is SHA-256d(preimage) interpreted as a big-endian scalar modulo `n`. Purchase supplies its 32-byte IDs and valid buyer key/coordinates, with empty `units` and `adminSignature`. Activation has empty `units` and `adminSignature`, zero 32-byte IDs, zero 33-byte buyer key, and empty buyer coordinates. Split and payout likewise require zero IDs/key and empty buyer coordinates; payout also requires empty `adminSignature`. Retirement requires those unused buyer fields and empty `units`. `units` is otherwise the split first amount or payout `q`. `adminSignature` is present only for seller-authorized split or early retirement. If there is no change, `changeHash` is 20 zero bytes and `changeAmount=0`; otherwise they describe one final P2PKH output. These exact stack and unused-field requirements are consensus checks in the frozen programs, not merely builder recommendations.

The entry checks remove the unused-push txid mutation from the earlier draft: changing a purchase's `units` from `OP_0` to `OP_1`, or inserting an unmatched listing-input push, now fails. They **cannot** make a Bitcoin transaction's txid unique. A valid extra push in an external P2PKH funding input changes its scriptSig and txid while leaving the authenticated listing-input preimage, outputs and payment unchanged. So does a `OP_0 OP_DROP` pair before the listing witness: it restores the required stack depth. The three complete transactions in [purchase-variant.json](https://github.com/bsv-blockchain/BRCs/tree/master/tokens/media/0197/purchase-variant.json) demonstrate both mutations in independent interpreters. A purchase is therefore identified for BRC-196 recovery by the full 32-byte `SHA256d(preimage)` purchase commitment, with verified txids tracked as aliases. The reduced Script scalar `z` is not that commitment. Every alias must independently satisfy all input Scripts, the receipt, outputs and lineage; equality of a claimed digest alone never authorizes release. The exact txid remains part of historical release evidence and chain-currentness assessment. A transaction can have two through eight inputs, but only input zero may consume the listing in this family; the others are externally funded. No two conflicting txids can both spend its input-zero outpoint on one selected chain.

BRC-100 construction is two phase: obtain final funded inputs and outputs using `signAndProcess:false` and `randomizeOutputs:false`; verify the layout; form preimages and covenant witnesses for those bytes; request the protected seller-child signature when required; then finalize through `signAction`. Recheck the final transaction, sequences, output order, change and locktime. If the wallet cannot preserve this layout or safely sign/internalize the fixed child, report unsupported before funding a listing. Test fixture scalars are not an integration method.

## 6. Lineage and domain checks

The purchase-domain IRI is `https://bsv.brc.dev/tokens/0197#listing-purchase-v1`. Its evidence schema is `https://bsv.brc.dev/tokens/0197#lineage-package-v1`, serialized as UTF-8 JCS:

```typescript
type LineagePackage = {
  version:1; descriptor:ListingDescriptor;
  genesis:{body:{version:1,listingId:Hex32,genesis:Outpoint},signature:Bytes};
  target:Outpoint; transactions:{txid:Hex32,beef:Bytes}[]
}
```

Entries are unique and sorted by txid. Each BEEF entry binds exact raw bytes and supplies verification dependencies or explicitly unresolved references. Collect the union before resolving dependencies; sorted order is not topological order. The graph includes genesis, activation and every active predecessor on the target's branch. Verify chain/Bitcoin validity, the exact input source and amount, both Script stages, seller genesis packet and anchor, route outputs and target. A copied active lock or stage-bypass output fails. Reject cycles, missing paths and unrelated copies. Limit the package to 256 distinct listing transactions and 2 MiB decoded bytes, subject to stricter local limits. Unresolved evidence is not valid purchase evidence. A verified cache may reuse immutable ancestors but must recheck current chain placement and unspentness.

The domain validator checks descriptor ordering, uniqueness and commitments, configured chain, asset authority, prepared BRC-196 acquisition/request/recipient association and currentness. It requires the listing at input zero and rejects another family listing among externally funded inputs; all inputs must verify as Bitcoin-valid. Script checks economic transitions, child links, payment destinations and transaction binding. Neither layer replaces the other. BRC-193 publishes coherent spent/created groups; public replay never releases private fulfillment. Reorganizations reassess current projections while preserving valid historical purchase records and the distinction between a historical release txid and a verified equivalent current alias.

## 7. Qualification and security boundary

The [family package](https://github.com/bsv-blockchain/BRCs/tree/master/tokens/media/0197/README.md) contains a connected reserve-stage activation, purchase, split, payout and retirement graph, a separate eight-recipient activation/purchase/payout graph, and fresh-preimage rejection vectors. Every complete transaction has signed external funding inputs. Independent BitcoinX and pinned BSV SDK interpreters execute the bytes. These tests validate examples, not a production wallet, miner policy, chain view, fair exchange or external security audit. Implementations must reproduce exact hashes and relevant acceptance/rejection vectors, then qualify the intended BRC-100 signer, fixed-child remittance, fee/resource policy and end-to-end lineage validation.

A leaked public-counterparty child scalar compromises its root; protected signer separation is a hard security assumption. Recipients must demonstrate ability to spend a fixed-child P2PKH payout before significant value is locked. A listing whose balance cannot fit another price increment remains withdrawable and may be retired, but cannot accept another purchase.


---

# 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 by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://hub.bsvblockchain.org/brc/tokens/0197.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

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.
