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)
146 | [Miner-Enforced Resale-Royalty Covenant Tokens (OP_PUSH_TX)](./tokens/0146.md)

## License

Expand Down
1 change: 1 addition & 0 deletions SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@
* [Merkle Proof Token](./tokens/0113.md)
* [Identity-Linked Deterministic Token Verification Framework](./tokens/0115.md)
* [Proof-of-Indexing Hash-to-Mint Tokens](./tokens/0117.md)
* [Miner-Enforced Resale-Royalty Covenant Tokens (OP_PUSH_TX)](./tokens/0146.md)

## Overlays

Expand Down
118 changes: 118 additions & 0 deletions tokens/0146.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# BRC-146: Miner-Enforced Resale-Royalty Covenant Tokens (OP_PUSH_TX)

<!-- Author line: a handle + a contact link. Email is optional in a BRC; the PR/issue thread is the real discussion channel. -->
sun-dive (https://github.com/sun-dive)

## Abstract

This BRC specifies a class of **self-replicating covenant tokens** whose spending rules are enforced by miners at consensus, not by any platform. Using **OP_PUSH_TX** transaction introspection, each token's locking script forces the transaction that spends it to (a) **re-create the token** for its new holder and (b) **pay fixed royalty/creator outputs** to immutable addresses. A resale that omits, reorders, underpays, or redirects any required payout is simply an **invalid transaction** — so the resale terms are *unstrippable* and travel with the coin.

One mechanism carries two profiles:

- **Single-payee** — every transfer or permissionless purchase pays a fixed **publisher fee** and **holder fee**. *Deployed and mainnet-validated.*
- **Multi-payee** — every resale pays **N fixed creator payouts**, each bound to an immutable address (e.g. an on-chain split sheet, or paying the original creators of referenced/bundled components). *Validated against the reference Script interpreter; ready for deployment.*

Tokens are **self-verifying**: identity binds to a genesis transaction and is confirmed by a single Merkle proof, with **no lineage walk** — the same principle as the Merkle Proof Token protocol<sup>[1](#footnote-1)</sup>.

> The Abstract section should concisely describe your proposal at a high-level.

## Motivation

On-chain assets can express resale royalties and creator splits, but as a *convention* those payments are strippable — a reseller can simply omit them — and enforcing them at a marketplace requires trust and is bypassed by trading elsewhere. BSV Script's transaction-introspection capability lets a token enforce **its own** resale terms at consensus: any spend that fails to carry the required outputs is rejected by miners. This yields:

1. **Unstrippable resale royalties.** The creator payout is a *validity condition* of the spend, not a courtesy.
2. **Multi-party splits and reuse royalties.** A single covenant can force **N** payouts — a music split sheet (songwriter / producer / label), or paying the original creators of the components a composition reuses<sup>[4](#footnote-4)</sup> — each bound to an immutable address.
3. **Platform independence.** No marketplace, escrow, or trusted intermediary; the rules are in the coin.
4. **A recognized transaction class.** A documented, uniform format so *any* wallet can recognize, validate, transfer, and display these tokens interoperably — rather than every implementation being bespoke. Standardizing the format is the purpose of this BRC: one implementation already produces and validates these tokens on mainnet; this lets others support the same class.

> The Motivation section should let people know the context for your proposal, and why it was written.

## Specification

### 1. Overview

A covenant token is a Bitcoin output whose locking script, on every spend, verifies the spending transaction against itself (OP_PUSH_TX) and forces a specific ordered output layout: **output 0** re-creates the token (re-locked to the new holder), followed by one or more **fixed payout outputs**, followed by spender-controlled change. The immutable terms (payout addresses and amounts) are committed at mint and propagate unchanged forever.

### 2. Transaction introspection (OP_PUSH_TX)

BSV has no native "push the sighash" opcode, so a locking script inspects its spending transaction using the **Push TX** construction (BRC-21<sup>[5](#footnote-5)</sup>):

1. The **unlocking** script pushes the BIP-143/FORKID **sighash preimage** of the spending input.
2. The **locking** script computes `e = HASH256(preimage)` and, using a **fixed, PUBLIC** keypair `(a, k)`, derives a valid ECDSA signature `s = k⁻¹·(e + r·a) mod n` (with `r = (k·G).x mod n`), assembles it as minimal DER, and verifies it with `OP_CHECKSIG` against `Q = a·G`.

Because `OP_CHECKSIG` independently recomputes the sighash from the **actual** transaction, the spend validates only when `HASH256(pushed preimage) == actual sighash` — i.e. the spender is *forced* to reveal the genuine preimage. `(a, k)` are public constants and protect nothing; the covenant's security rests entirely on this binding, not on key secrecy. Having proven the preimage genuine, the covenant `OP_SPLIT`s it to read fields such as `hashOutputs` and enforces rules on the spending transaction.

**Requirements:** transaction version MUST be `> 1` (so low-S is not enforced and big-integer arithmetic is available); DER minimality of `s` is obtained by `OP_NUM2BIN` to a fixed width followed by fixed-length reversal. Implementations MUST use a consistent sighash scope so that `hashOutputs` commits to the full ordered output list.

### 3. Token model

Tokens are carried in **PushDrop** outputs (Pay to Push Drop, BRC-48<sup>[6](#footnote-6)</sup>): a sequence of pushed data fields followed by a `<lockKey> OP_CHECKSIG`-style authentication of the current holder. A **record-type** byte distinguishes token kinds; this BRC concerns the **covenant token** record, whose immutable field prefix is:

```
[ P (protocol byte), version, recordType, genesisRef (32-byte txid), ownerPubKey (33 bytes), <profile fields…> ]
```

- **`genesisRef`** — the txid of the **genesis transaction** that minted the covenant and committed its immutable terms (payout address(es) and amounts). It is the token's identity and is identical across every replicated copy.
- **`ownerPubKey`** — the current holder's public key; this is the **only** field that changes across a transfer.
- Immutable terms are committed by the genesis transaction and/or baked as constants in the covenant script.

### 4. Self-replicating covenant (the quine)

On any spend the covenant reconstructs **its own** locking script for output 0 directly from the preimage's `scriptCode` — it never embeds a second copy of itself. It extracts the `scriptCode` field, splits it at the `ownerPubKey` offset into `(prefix ‖ ownerPubKey ‖ suffix)`, substitutes the new holder's key, and requires output 0 to equal `value ‖ prefix ‖ newOwnerPubKey ‖ suffix`. Because `prefix`/`suffix` are reproduced verbatim, the immutable terms propagate unchanged; only the holder changes.

### 5. Enforced outputs

The covenant assembles the **expected** output serialization `out0 ‖ <fixed payout outputs> ‖ <spender change>` and asserts `HASH256(expected) == hashOutputs`. Each payout output is a fixed-value P2PKH to an immutable address. Any spend that omits, reorders, alters an amount, or redirects a payout produces a different `hashOutputs` and fails. Outputs after the forced set are spender-controlled (change, buyer funding return, etc.). Because enforcement is on outputs only, additional **inputs** MAY be added by a buyer to fund the spend.

### 6. Profile A — single-payee (deployed)

The genesis transaction commits a covenant template (publisher address + fee schedule) and, optionally, content. Covenant tokens are three-way spendable via an unlock selector:

- **Transfer** (holder-authorized): out0 = token re-locked to `newOwnerPubKey`; the current holder MUST sign (`OP_CHECKSIGVERIFY` against the extracted `ownerPubKey`).
- **Purchase / replicate** (permissionless): out0 = token returned to the holder (verbatim), out1 = replica to the buyer (owner = buyer), out2 = **publisher fee** (fixed sats → the immutable publisher address), out3 = **holder fee** (fixed sats → `HASH160(ownerPubKey)`), out4+ = buyer change. **No holder signature is required** — anyone may buy, but the two fees are compulsory.
- **Burn** (holder-authorized): reclaim the token's refundable bond.

Result: every sale pays the publisher (creator royalty) and the current holder, enforced by consensus. **Status: deployed on BSV mainnet.**

### 7. Profile B — multi-payee (ready)

Identical mechanism; the forced-output tail generalizes from one publisher fee to **N** fixed payouts:

```
out0 = token re-locked to newOwnerPubKey (self-replica)
out1 … outN = feeSats_i → P2PKH(creatorAddr_i) (N fixed, genesis-bound payouts)
out(N+1)… = spender change
```

The current holder signs to sell. The N payees SHOULD be **genesis-bound**: each `creatorAddr_i` is the immutable publisher address of a referenced component's own genesis mint, so a verifier can confirm the covenant pays the real creators (fetch each component's genesis, compare) and the minter cannot substitute addresses. **Percentages are a UI concern** — an interface displays "50 / 30 / 20" and computes the fixed sat amounts at the chosen price; the covenant only ever enforces fixed amounts. Uses: enforced **reuse royalties** (a composition pays each referenced component's creator on resale) and **multi-party splits** (a single work's collaborators). **Status: validated against the reference `@bsv/sdk` Script interpreter (transaction version 2); not yet deployed.**

### 8. Self-verification (no lineage walk)

A token is genuine if and only if its covenant's immutable portion matches the terms committed by its genesis transaction (`genesisRef`), confirmed by a **single Merkle proof** (BUMP<sup>[2](#footnote-2)</sup>) of that genesis transaction to a block header. There is **no need to trace the token's transfer history**: identity binds to genesis, and the covenant guarantees the terms propagated unchanged. This is the "genuine-penny" / MPT principle<sup>[1](#footnote-1)</sup> — *bind to genesis, don't trace every hop* — and it makes verification **O(1)** in the number of transfers. No ancestor/lineage chain (e.g. BRC-62 BEEF<sup>[3](#footnote-3)</sup>) is required.

### 9. Conformant wallet requirements

A wallet claiming support for this class:

1. MUST construct spends that satisfy the active profile's forced output layout (OP_PUSH_TX preimage in the unlock; correct out0 self-replica; all payout outputs present, exact, and in order).
2. MUST validate a received token by matching its covenant against `genesisRef`'s committed terms plus a single Merkle proof to a header (Section 8).
3. SHOULD recognize the record-type byte and display the enforced payouts (creator royalties / splits) to the user.
4. MAY add buyer funding inputs when purchasing (Section 5).

> The Specification section of your proposal should stipulate all information needed to implement the standard, and make up the bulk of the document. Generally, people should be able to create a compatible implementation with only the specification.

## Implementations

1. **Phar Lap** — an open-source (Open BSV License) smart-NFT wallet that mints, transfers, purchases (permissionless), burns, and validates the **single-payee** covenant on **BSV mainnet**, and ships the **multi-payee** covenant (interpreter-proven). Repository: `https://github.com/sun-dive/PharLap`. Covenant sources: `src/pushtx.ts` (OP_PUSH_TX primitive), `src/covenant.ts` (single-payee edition covenant + quine), `src/bundleCovenant.ts` (multi-payee covenant).
2. **Reference validation** — both profiles are validated end-to-end against the `@bsv/sdk` `Spend` interpreter with `transactionVersion = 2`, including negative tests that reject a spend which skips, underpays, or redirects any payout.

> The Implementations section should contain information about places where the standard is implemented, or examples of its implementation.

## References

- <a name="footnote-1">1</a>: Merkle Proof Token (MPT) protocol — BRC-113, https://github.com/bitcoin-sv/BRCs (identity binds to genesis; self-verification without a lineage walk).
- <a name="footnote-2">2</a>: BSV Unified Merkle Path (BUMP) — BRC-74, https://github.com/bitcoin-sv/BRCs (single-proof SPV to a block header).
- <a name="footnote-3">3</a>: BEEF — BRC-62, https://github.com/bitcoin-sv/BRCs (ancestor-carrying format; explicitly NOT required by this class).
- <a name="footnote-4">4</a>: Block Media Format (BMF) — BRC-145 (composable on-chain audio/video; the multi-payee profile enforces payment to the creators of the components a BMF composition reuses).
- <a name="footnote-5">5</a>: Push TX — BRC-21, https://github.com/bitcoin-sv/BRCs (transaction introspection by pushing and verifying the sighash preimage).
- <a name="footnote-6">6</a>: Pay to Push Drop — BRC-48, https://github.com/bitcoin-sv/BRCs (data fields pushed then dropped ahead of a spendable locking script).