# Overstory Protocol, version 1 (draft)

Status: draft, validated on a private Zcash regtest chain. Not deployed on mainnet.

Overstory is a metaprotocol on the Zcash transparent pool. It defines how an inscription
is written, who owns it, how a collection is declared, how a mint joins a collection, how
the artwork of a mint is derived, and how an item is sold without escrow. Every rule below
can be evaluated by anyone replaying the chain; nothing depends on a server.

## 1. Networks and scope

Zcash mainnet, testnet and regtest, transparent pool only. Value that enters a shielded
pool ends protocol tracking permanently (section 3.3).

Transaction versions 5 and 6 are valid carriers. Builders derive the consensus branch id,
version group id and expiry height from the chain they target.

## 2. Inscriptions

An inscription is content bytes plus a content type, written through a commit
transaction and one or more reveal transactions. The envelope is byte-compatible with the
ord-style scriptSig envelope already used on Zcash, with a content commitment in the
redeem script.

### 2.1 Commit

The commit transaction creates one P2SH output. Its redeem script is

```
PUSH <33-byte compressed pubkey>
OP_CHECKSIGVERIFY
PUSH <32-byte C>
OP_DROP
OP_DROP  (repeated 3 + 2 * piecesInThisReveal times)
OP_1
```

with `C = SHA256("UZRD1" || contentType || 0x00 || content)`, where `contentType` is the
exact ASCII bytes pushed in the envelope and `content` is the complete content.

### 2.2 Reveal

Input 0 of a reveal transaction spends a commit output. Its scriptSig is push-only:

```
PUSH "ord"
PUSHNUM totalPieces          1..255
PUSH contentType             3..96 ASCII bytes containing "/"
repeated for each piece in this transaction, at most 4, indexes descending:
  PUSHNUM pieceIndex
  PUSH piece                 240 bytes; the final piece (index 0) may be shorter
PUSH signature
PUSH redeemScript
```

`PUSHNUM n` encodes 0 as OP_0, 1..16 as OP_1..OP_16, 17..255 as a one-byte data push.

Content is split into pieces of 240 bytes. Piece `totalPieces - 1` is pushed first, piece 0
last. Reassembly concatenates pieces by ascending index. Maximum content size is
255 * 240 = 61,200 bytes.

### 2.3 Chains

When more than four pieces are needed, reveals are chained:

- the genesis reveal spends the commit output and carries the highest indexes;
- each continuation reveal spends output 0 of the previous reveal, which pays a P2SH
  output built with the same rules as a commit (same `C`, `OP_DROP` count for that
  reveal's piece count);
- the completion reveal carries piece 0.

Every reveal repeats the full header. Every redeem script in a chain commits to the same `C`.

### 2.4 Validity

An inscription is valid when all of these hold: every piece index is unique and within
range, pieces reassemble to exactly `totalPieces` pieces, and `C` in every redeem script
equals the commitment computed over the reassembled content. An inscription whose
redeem scripts do not carry a verifiable commitment is indexed as `legacy` and is never a
member of a collection. Incomplete chains are indexed as incomplete and their content is
not served.

### 2.5 Identity

Inscription id: `<genesis txid>i0` (display-order hex). One inscription per genesis
transaction. The completion transaction is the reveal that carries piece 0; for a single
reveal it is the genesis transaction.

## 3. Ownership

### 3.1 Genesis

At completion, the inscription is owned by output 0 of the completion transaction, which
must be a transparent, non-data output. Its value is the postage (546 zatoshis by
convention).

### 3.2 Transfer

When the carrying output is spent, the inscription moves to the first transparent,
non-`OP_RETURN` output of the spending transaction, in output-index order.

### 3.3 Terminal states

If the spending transaction has no transparent non-data output, tracking ends. If that
transaction carries any shielded bundle the state is `shielded`, otherwise `burned`. Both
are permanent; later transactions never revive an inscription.

## 4. Collections

Declarations are inscriptions with content type `application/json` whose content is a
JSON object with `"p": "overstory"`. Any other content is an ordinary inscription.

### 4.1 Deploy

```json
{"p":"overstory","v":1,"op":"deploy",
 "name":"...","supply":3000,"max_per_addr":2,"price":200000,
 "pay":"t1...","start":3500000,"renderer":"<inscription id>"}
```

| Field | Meaning |
|---|---|
| `name` | display name, informational |
| `supply` | maximum number of valid mints, 1..100000 |
| `max_per_addr` | maximum valid mints per destination address; 0 = unlimited |
| `price` | zatoshis that a mint must pay to `pay`; 0 = free |
| `pay` | transparent address receiving mint payments |
| `start` | first height at which mints are valid (never below the deploy's completion height + 1) |
| `renderer` | inscription id of the renderer specification and reference source |

The collection id is the deploy inscription id. Names are not unique and carry no
authority. A deploy is valid if it parses, `supply` is in range and `pay` is a transparent
address. Invalid deploys are ignored.

### 4.2 Mint

```json
{"p":"overstory","op":"mint","d":"<deploy inscription id>"}
```

A mint inscription is a valid member of collection `d` if, evaluated in chain order
(block height, then transaction index within the block), all of the following hold at the
moment its completion transaction is processed:

1. `d` names a valid deploy;
2. the completion height is at least the collection's `start`;
3. fewer than `supply` valid mints exist;
4. the destination address (owner of output 0 at completion) has fewer than
   `max_per_addr` valid mints, when `max_per_addr` is nonzero;
5. when `price` is nonzero, the completion transaction pays at least `price` zatoshis in
   total to `pay`.

A valid mint receives `number = (previous valid mint count) + 1`. A mint that fails any
rule is an ordinary inscription: it keeps its content and ownership but is not a member,
and its fees are not refunded. Membership is decided once and never changes.

### 4.3 Seed

```
seed = SHA256( genesis_txid || completion_block_hash )
```

Both values are the 32-byte identifiers in display order (the byte order of the hex shown
by explorers). The seed is the only input to the renderer.

## 5. Rendering

The renderer specification is published as an inscription (the `renderer` field of the
deploy). Its output for a seed is a 64x64 matrix of palette indexes; the SHA-256 of that
matrix, row-major, is the canonical image hash. PNG or any other encoding is presentation
only.

The renderer is required to be deterministic across implementations: integer-only
arithmetic, a frozen 1024-entry sine table, and xoshiro256** streams seeded through
splitmix64 from `SHA256(seed || streamTag)`. The reference implementation is the
inscribed source; an independent implementation must reproduce the matrix hash of the
published test vectors exactly.

## 6. Listings and sales

A listing is a signature by the current owner over the carrying output with
`SIGHASH_SINGLE | SIGHASH_ANYONECANPAY` (0x83, ZIP 244 semantics). It commits to the
carrier input and to the output at the same index, the seller payout.

A listing document carries: carrier outpoint, value and scriptPubKey; seller public key;
payout address; price; expiry height; the DER signature. Because the signature commits to
the transaction's expiry height, the listing expires by consensus.

A purchase is one transaction assembled by the buyer:

```
inputs : [buyer funds, carrier]
outputs: [destination (postage), seller payout (price), buyer change]
```

The buyer verifies the seller signature against the sighash of the assembled transaction,
signs its own inputs and broadcasts. Either the whole transaction confirms or nothing
happens; no party holds anything for the other. A listing stops being usable when the
carrier is spent (sale, transfer to self, or any other spend) or when the expiry height
passes.

## 7. Indexer requirements

- Process blocks in height order and transactions in block order.
- Parsers impose hard bounds: scriptSig at most 1,650 bytes, chain length at most 64
  reveals, content at most 61,200 bytes; malformed data is recorded, never served as content.
- Two independent indexers replaying the same chain must produce the same set of
  inscriptions, owners, collections, members, numbers and seeds. Replay from genesis must
  equal incremental indexing.

## 8. Reference behaviour (regtest, 2026-09-23)

- 54-byte declaration: one reveal, 362 bytes. 1,276-byte PNG: two reveals of 1,079 and
  755 bytes; a four-piece reveal keeps the scriptSig near 1,000 bytes.
- Reveal fees follow ZIP 317: 5,000 zatoshis per logical action, at least two actions;
  the four-piece reveal costs 35,000 zatoshis.
- A collection with `supply 3, max_per_addr 2, price 100000` accepted three mints and
  rejected one per-address overflow, one underpayment (50,000 < 100,000), one mint after
  supply was exhausted, and one mint naming an unknown collection.
