# QINS-1: Quantus Inscriptions QINS-1 is an Ordinals-style inscription protocol for the Quantus Network (QTC). Files, collections, tokens and every action on them (inscribe, send, list, buy) are written on chain as `System.remark` data, signed with the account's ML-DSA (Dilithium) key, so provenance and ownership are quantum-resistant. Payments use Quantus' native reversible transfers as escrow. As with Ordinals, the chain doesn't know about QINS; it only stores the data. Ownership comes from an **indexer** that reads the chain and applies the rules below. Every honest indexer that follows these rules computes exactly the same state, so the rules are the protocol. --- ## 1. Inputs An indexer reads two kinds of chain data, in chain order. ### 1.1 Operations (remarks) A QINS **operation** is a remark whose bytes are UTF-8 text starting with `qins1:`, followed by one JSON object: ``` qins1:{"op":"insc","h":"9f86d0…","mime":"image/png","d":"iVBORw0KGgo…"} ``` It counts only if all of these hold: - It's the call of a **top-level, signed** extrinsic. - The call is `System.remark` or `System.remark_with_event`. - The signer address is `MultiAddress::Id` (a 32-byte account). Remarks nested inside `Utility.batch*`, multisig proposals or scheduled calls are ignored. Inclusion in a block is enough: a signed `remark` can't fail at dispatch. The **signer** is the account in the extrinsic's signature, the only identity QINS trusts. ### 1.2 Escrow events Native-QTC events of the `ReversibleTransfers` pallet: | event | QINS reads | |---|---| | `TransactionScheduled { from, to, asset_id: None, amount, tx_id, execute_at }` | an escrow opens. `execute_at = At(block)` gives its execution block; `After(…)` (time-based) escrows have no block and can't be used to buy. | | `TransactionCancelled { tx_id }` | the escrow closed without paying. | | `TransactionExecuted { tx_id, result }` | the escrow paid out if `result` is `Ok`; `Err` counts like a cancellation. | A buyer creates an escrow with `schedule_transfer_with_delay(dest, amount, BlockNumber(n))`, which pays `dest` at block `now + n` unless the buyer cancels it first. Only the sender (or, for high-security accounts, their guardian) can cancel. ### 1.3 Ordering and IDs Inputs are applied by block number, then position in the block: events from block initialization first (this is where the scheduler executes escrows), then each extrinsic in index order (its remark or its events), then finalization events. Every operation gets a **location** `"-"`, e.g. `"48213-2"`. An inscription's ID is the location of the operation that created it. ### 1.4 Time Some rules take effect at a later block (§3.8). Before applying a block's inputs, an indexer first applies every deadline that falls at or before that block, oldest deadline first (ties by inscription ID). ### 1.5 Activation block and finality Each deployment publishes an **activation block**; inputs below it are ignored. Quantus is proof-of-work, so indexers only treat blocks at or below the node's finalized head (`chain_getFinalizedHead`) as permanent. Unfinalized blocks may be shown provisionally. ### 1.6 Malformed data If the JSON is invalid, the `op` is unknown, a required field is missing or a rule fails, the operation is a **no-op**: recorded as rejected, with a reason, and changes nothing. Unknown extra fields are ignored. --- ## 2. Addresses and amounts An address field (`to`) is a Quantus SS58 address (prefix **189**, `qz…`) with a valid checksum, or `0x` plus 64 hex characters. Indexers normalise to SS58. Amounts are **decimal strings** (`"12.5"`), never JSON numbers. QTC prices have up to 12 decimals (1 QTC = 10¹² planck). --- ## 3. Operations ### 3.0 `commit`: claiming a name Collection and token names are claimed in two steps so that nobody can see a name in the mempool and claim it first. ```json {"op":"commit","c":"<64 lowercase hex>"} ``` `c = sha256("qins1:" + kind + ":" + lowercase(tick) + ":" + salt + ":" + signer)`, where `kind` is `collection` or `token`, `salt` is 8–64 characters of `[A-Za-z0-9]`, and `signer` is the committer's SS58 address. A commitment can be posted once. The later `deploy` / `token-deploy` carries the `salt`. It is valid only if a commitment matching it **from the same signer** exists, posted at least **10** and at most **100,800** blocks (≈14 days) earlier. A reveal uses up its commitment. Because the commitment includes the signer, copying someone's revealed salt is useless. ### 3.1 `deploy`: create a collection ```json {"op":"deploy","tick":"qpunks","name":"Quantum Punks","max":1000,"desc":"optional","salt":"…"} ``` | field | rule | |---|---| | `tick` | 1–16 characters `[A-Za-z0-9_-]`, case-insensitive (stored lowercase) | | `name` | 1–64 characters | | `max` | integer 1 to 1,000,000 | | `desc` | optional, ≤ 1024 characters | | `salt` | the commitment's salt (§3.0) | The first valid deploy of a tick wins. The signer becomes the **issuer**; only the issuer can mint into the collection or lock it. ### 3.2 `data`: one content chunk ```json {"op":"data","h":"","i":0,"n":3,"d":""} ``` `h` 64 lowercase hex; `n` 1–4096; `i` 0…n−1; `d` standard base64 with padding. Anyone can post chunks; the hash makes them trustworthy (§4). ### 3.3 `insc` and `mint`: create an inscription `insc` creates a **standalone** inscription. Anyone can post one: ```json {"op":"insc","h":"","mime":"image/png","d":"","name":"optional","attrs":{},"to":"optional address"} ``` `mint` creates one inside a collection and is valid only for its issuer, while the collection is unlocked and below `max`, and if no earlier mint in that collection used the same `h`: ```json {"op":"mint","tick":"qpunks","h":"","mime":"image/png","d":"…","name":"…","attrs":{},"to":"…"} ``` | field | rule | |---|---| | `h` | sha256 of the content | | `mime` | `type/subtype`, ≤ 100 characters | | `d` | optional inline content; `sha256(base64decode(d))` must equal `h`. Without `d`, content comes from `data` chunks (§4). | | `name` | optional, ≤ 128 characters | | `attrs` | optional object, ≤ 4096 bytes serialized | | `to` | optional initial owner (default: signer); an invalid address rejects the whole operation | **Numbering.** Every valid `insc` or `mint` gets the next **global number**, starting at 1, in chain order: one sequence across all collections and standalone inscriptions. A `mint` also gets a collection **number** (1, 2, …). A number is permanent once its block is final. ### 3.4 `send`, `burn` ```json {"op":"send","id":"48213-2","to":"qz…"} {"op":"burn","id":"48213-2"} ``` The signer must be the owner, the inscription not burned and not locked by a buyer (§3.8). A burned inscription keeps its number and can never move again. If the inscription is listed, the change waits out the notice period (§3.8). ### 3.5 `lock` ```json {"op":"lock","tick":"qpunks"} ``` Issuer only. Closes minting permanently. ### 3.6 Fungible tokens (BRC-20 style) ```json {"op":"token-deploy","tick":"qord","max":"21000000","lim":"1000","dec":0,"salt":"…"} {"op":"token-mint","tick":"qord","amt":"1000"} {"op":"token-send","tick":"qord","amt":"250","to":"qz…"} ``` Token ticks are a separate namespace from collections and are claimed with commit-reveal (`kind` = `token`). `dec` 0–18 (default 18); `max` > 0; `lim` 1 base unit to `max` (default `max`). There's no premine. Anyone can `token-mint` up to `lim`; the last mint gets the remainder; then mints are rejected. `token-send` moves the signer's balance and needs enough of it. ### 3.7 Marketplace: `list`, `delist` ```json {"op":"list","id":"48213-2","price":"12.5"} {"op":"delist","id":"48213-2"} ``` The signer must own the inscription. The price must be at least **0.001 QTC** and at most 21,000,000 QTC; from the **v2 activation block** (§3.11) the minimum is **0.000001 QTC**. A listing's ID is its location. **Notice period.** While an inscription is listed, the owner's `list` (new price), `delist`, `send` and `burn` don't apply at once: they take effect **15 blocks** later (**2 blocks** from the v3 activation block, §3.11). Until then the current listing stays buyable at its current price. A new request replaces an earlier pending one. A lock doesn't cancel it: if that sale settles, the change is moot; if the lock is released, the change applies at once (if its time has come). ### 3.8 Buying: reserve, then pay with escrow A purchase has up to three parts, all from the buyer's account. **1. Reserve it** with a buy: ```json {"op":"buy","id":"48213-2","listing":"50110-1"} ``` The buy is valid only if the inscription is listed, `listing` equals the current listing's ID, the signer isn't the seller, nobody else holds a reservation on the listing, and the signer hasn't held one on this listing before. A valid buy **reserves** the listing for the buyer until block **B + 15** (B = the buy's block; the *pay window*; B + 5 from v7, §3.15). While reserved, nobody else can buy it and the owner can't send, burn, list or delist it (their changes queue, §3.7). **2. Pay the fee** (only when a fee applies, §3.9): a reversible transfer of at least the fee to the fee address. **3. Pay the price**: a reversible transfer of at least the price to the seller, which must execute **strictly after** the fee escrow. An escrow pays for the reservation when it is a one-time escrow (its guardian is the sender, so only the buyer can cancel it) from the buyer, scheduled in a block no later than B + 15, executing after that block and at most **60 blocks** after it (5 blocks and B + 5 from v7, §3.15), and not already used. Escrows are matched in chain order: the first matching fee escrow becomes the fee payment, then the first matching price escrow that executes after it becomes the price payment. Escrows the buyer scheduled up to 15 blocks before the buy count too (a reorganisation can reorder transactions). If a buyer holds several reservations, an escrow pays for the oldest one it matches. The reservation resolves as follows: - **No price payment by the end of the pay window**: the reservation is released. - **Price escrow executed (`Ok`)**: the sale settles in that block. The inscription moves to the buyer, the listing closes, a sale is recorded. - **Fee or price escrow cancelled, or executed with `Err`**: the reservation is released. - **Safety valve**: a paid reservation still open **600 blocks** after the price escrow's execution block is released. If that escrow executes later anyway (`Ok`) while the same listing is still open and unreserved, the sale settles, since the buyer did pay. A buyer whose reservation is released can't reserve that listing again. Releasing a reservation applies any seller change that came due meanwhile, in the same block. Losing a race costs only the buy's network fee: whoever reserves first pays; everyone else hasn't paid anything. Because the money only moves when the price escrow executes, and it can only pay for a reservation the buyer holds, a buyer can't pay without getting the item (unless they leave an escrow running after their reservation was released), and a seller can't take payment and move the item. The fee always executes before the price, so a sale can't settle with the fee unpaid. ### 3.9 Market fee A deployment may name a **fee address** and a starting rate in basis points (50 = 0.5%), plus an optional `freeBelow` price; these are fixed for the deployment, like the activation block. The fee on a purchase is `ceil(price × bps / 10000)` planck, or zero if there's no fee address, `bps` is 0, the price is below `freeBelow`, or the seller is the fee address. The fee is fixed when the buy reserves the listing. The fee escrow executes before the price escrow by construction (§3.8), and cancelling it beforehand releases the reservation, so every settled sale has paid its fee. **Who pays it.** Before v7 the buyer pays the fee on top of the price. From v7 (§3.15) the seller pays it: the buyer still pays it into the fee escrow, but the price escrow only has to cover the price minus the fee, so the buyer pays exactly the listed price in all and the seller receives the price minus the fee. The fee address can change the rate for later buys (`bps` ≤ 1000): ```json {"op":"fee-set","bps":50,"nftBps":100,"freeBelow":"0.25"} ``` - `bps` is the rate on token lots. `nftBps` (optional, ≤ 1000) is a separate rate on inscriptions; until a `fee-set` gives one, inscriptions pay `bps` too, and a later `fee-set` without it keeps the last one given. - `dropBps` (optional, ≤ 1000, from v8): the launch fee on paid drop mints (§3.17). Before the v8 block it is ignored. Until a `fee-set` gives one the rate is 500 (5%), and a later `fee-set` without it keeps the last one given. - `freeBelow` (optional, QTC): a purchase whose price is below it pays no fee (and the buyer sends no fee escrow). A buy that reserves several token lots at once (§3.10, §3.16) compares the **total** of the lots it reserves, so splitting a sale into small lots doesn't avoid the fee: if the total is at least `freeBelow`, each lot pays `ceil(price × bps / 10000)`, whatever its own price. ### 3.10 Token market: `token-list`, `token-delist` A holder offers a lot of tokens for a fixed QTC price: ```json {"op":"token-list","tick":"road","amt":"5000","price":"2"} {"op":"token-delist","id":"203500-1"} ``` `token-list` needs `amt` > 0 and no more than the signer's balance, and a `price` from the minimum (0.001 QTC, or 0.000001 QTC from the v2 block) to 21,000,000 QTC for the whole lot. The tokens leave the seller's balance at once (they can't be sent or listed again) and the lot gets the `id` of the `token-list` operation. A lot is bought whole, with the same `buy` operation and escrow rules as an inscription (§3.8, §3.9), using `{"op":"buy","id":,"listing":}`. When the price escrow settles, the tokens are credited to the buyer. `token-delist` is the seller's only change to a lot. It's refused while a buy holds the lot; otherwise it takes effect `NOTICE` blocks later (§3.7) and returns the tokens. A buy that reserves the lot during the notice wins, and the pending take-down is dropped if that sale settles. The price per token shown by indexers is `floor(price × 10^dec / amt)` planck; it's for display and sorting only. **Listing several lots at once (v2).** From the v2 activation block (§3.11), one `token-list` can create up to **200** lots: ```json {"op":"token-list","tick":"road","lots":[["400","0.0012"],["400","0.0013"],["3200","4"]]} ``` Each entry is `[amt, price]` with the same rules as a single listing. Every entry must be valid and the signer must hold their total, or nothing is listed. Lot *k* (counting from 0) gets the ID `-k`, e.g. `214990-1-0`, and is bought, reserved and taken down exactly like any other lot. One `token-delist` can likewise name up to 200 lots, `{"op":"token-delist","ids":[...]}`; lots that aren't the signer's, are in a sale, or are already coming down are skipped, and it is rejected only if none can be taken down. **Buying several lots at once (v2).** From the v2 activation block (§3.11), a buy can name up to **50** lots: ```json {"op":"buy","ids":["203974-2","203975-2","203980-1"]} ``` Each named lot that is listed, not reserved, not the signer's own, and not one the signer held a reservation on before is reserved for the signer exactly as by a single buy (pay window B + 15), as one **group** identified by the buy's location. Lots that don't qualify are skipped; the buy is rejected only if no lot qualifies (or `ids` is empty, longer than 50, not all strings, or has duplicates). Ids that aren't token lots are skipped. A group is paid with **one fee escrow** of at least the sum of the group's fees (when that sum is above zero), then **one price escrow per seller** of at least the sum of that seller's unpaid lots in the group, each executing strictly after the fee escrow. The other escrow rules of §3.8 apply unchanged (one-time, scheduled by B + 15, executing within 60 blocks, matched in chain order; a buyer's waiting single reservations and groups are tried oldest first). When a seller's price escrow executes `Ok`, all of that seller's lots it paid for settle in that block, each recorded as its own trade at its own price. Cancelling, or an `Err` execution of, the fee escrow releases every lot of the group; the same for a price escrow releases the lots it paid for. Lots of the group left unpaid at the end of the pay window are released individually. ### 3.11 Rule changes (activation blocks) Rules that change after launch apply from a fixed block on, so replaying the chain never changes what already happened. **v2** (lower minimum price, multi-lot listings, take-downs and buys) applies from Quantus mainnet block **215100** for the public QINS Road deployment; **v3** (a 2-block notice period instead of 15, §3.7) applies from block **215800**. A deployment that starts later uses its own start block for both. **v4** (drops, §3.12) applies from block **233500** for the public QINS Road deployment. **v5** (collection thumbnails, §3.13) applies from block **238700**. **v6** (a 5-block pay window for drop mints and one unpaid reservation per wallet per drop, §3.14) applies from block **239000**. **v7** (the seller pays the market fee; short holds for every reservation; a cool-down after a hold ends unpaid or cancelled, §3.15) applies from block **241000**; so do market buys (§3.16). **v8** (a launch fee on paid drop mints, §3.17) applies from block **247000**. ### 3.12 Drops: random public mints (v4) A drop lets a collection's issuer offer a set of pieces that anyone can mint, each minter getting a piece picked at random. The issuer posts one operation; the minters post their own mints. **The set.** The issuer numbers the pieces 0…n−1 and gives each a **metadata string** `m`: a JSON object as UTF-8 text with `h` (sha256 of the content), `mime`, and optionally `name` and `attrs` (the same rules as §3.3). The set is committed to with a Merkle root: - leaf *i* = `sha256(0x00 ‖ "qins1:leaf::")` - node = `sha256(0x01 ‖ left ‖ right)`; at the end of an odd-length level the last node moves up unchanged. **Start a drop** (issuer only, collection not locked): ```json {"op":"drop","tick":"sig","n":1000,"root":"<64 hex>","price":"0.5","start":240100} ``` `n` is 1 to 100,000 and at most the room left in the collection (`max` − minted). `price` is the QTC price per piece: `"0"` for a free drop, otherwise the minimum price (§3.10) to 21,000,000. `start` (optional) is the first block at which pieces can be minted. The drop's ID is its location. A collection has one drop at a time: a new one is valid only once the previous one has no free pieces and no open reservations. While a drop runs, the issuer's own `mint` must leave room for its unminted pieces. `{"op":"drop-close","tick":"sig"}` (issuer) stops new mints; reservations already made can still be paid. **Mint** (anyone): ```json {"op":"drop-mint","tick":"sig","n":3} ``` `n` (default 1) is 1 to 20. It reserves `min(n, free)` slots, where *free* = n of the drop − minted − reserved; it fails if none are free or the drop hasn't started. On a free drop the pieces are minted at once. On a paid drop the minter pays like a purchase (§3.8): one one-time escrow from the minter to the **issuer** of at least `price × slots`, scheduled no later than B + 15 (B + 5 from v6, §3.14), executing after its scheduling block and at most 60 blocks later. There is no market fee on mints (from v8 a launch fee comes out of the price, §3.17). Escrows scheduled up to 15 blocks before the `drop-mint` count; a minter's reservations (and purchases) are paid oldest first. An unpaid reservation is released after B + 15 (B + 5 from v6); a cancelled or failed escrow releases it; a paid one still open 600 blocks after its escrow's execution block is released, and if that escrow executes `Ok` later it still mints whatever is free then. **The pick.** Pieces are minted in the block where the escrow executes (or the `drop-mint`'s block, for a free drop), using that block's hash *H*, which nobody knows when the reservation or the payment is signed. For slot *j* (0-based) of reservation *R*, with *r* pieces left: `x = int(first 16 hex of sha256("qins1:pick:" + H + ":" + R + ":" + j)) mod r`, where H is the block hash as 0x-prefixed lowercase hex. The piece taken is position *x* of the remaining list, and the last remaining piece moves into position *x* (a Fisher-Yates step; positions start as 0…n−1). Each piece minted this way is an inscription with ID `-`, the next global number and the next collection number, owned by the minter, with its content not yet revealed (no `h`, `mime` or `attrs`; its name is ` #` until revealed). **Reveal** (anyone, any time after the piece is minted): ```json {"op":"drop-reveal","drop":"","i":417,"m":"{\"h\":\"…\",\"mime\":\"image/png\",\"name\":\"…\",\"attrs\":{…}}","p":["",…],"d":""} ``` `p` is the Merkle proof for leaf `i` (sibling hashes from the leaf up, skipping levels where the node moves up unchanged, at most 40). It is valid if piece `i` is minted and not yet revealed, the proof matches the root, `m` is at most 8192 bytes and meets §3.3, and `d` (if present) matches `h`; without `d`, content comes from `data` chunks (§4). The inscription then takes `h`, `mime`, `attrs` and (if given) `name` from `m`. ### 3.13 Collection thumbnail (v5) A collection's issuer can give it a thumbnail, shown wherever the collection is listed: ```json {"op":"cover","tick":"sig","mime":"image/png","h":"","d":""} {"op":"cover","tick":"sig","id":""} ``` The first form carries the image itself: `mime` must be an `image/` type, `d` at most 65,536 bytes once decoded, and `sha256(d)` must equal `h`. The second points at an existing inscription that is an image (revealed, if it came from a drop, and not burned). Only the issuer can set it, at any time, also after the collection is locked; the latest valid `cover` replaces any earlier one. It changes nothing else about the collection. --- ### 3.14 Short holds for drop mints (v6) From the v6 activation block (§3.11), two rules make holding drop pieces without paying short and costly. Reservations made before it keep their old rules. - A `drop-mint` on a paid drop reserves its slots until **B + 5** instead of B + 15: its payment escrow must be scheduled no later than B + 5, and an unpaid reservation is released after B + 5. The other payment rules of §3.12 are unchanged (escrows scheduled up to 15 blocks before the `drop-mint` still count). - A wallet can hold only **one unpaid reservation per drop** at a time. A `drop-mint` from a wallet that already holds an open reservation in that drop with no payment bound to it is rejected. Once that reservation is paid, released or minted, the wallet can reserve again. Free drops are unaffected (they mint at once). ### 3.15 Seller-paid fee, short holds and a cool-down (v7) A reservation (§3.8, §3.10, §3.12) holds something for one buyer while they pay. Without limits, a wallet could reserve and never pay (or pay with a slow escrow and cancel it at the last moment), blocking everyone else each time. From the v7 activation block (§3.11), for reservations made at or after it: - **The seller pays the market fee.** The fee escrow is unchanged; the price escrow (or a seller's escrow in a multi-lot buy) must be at least the price minus that listing's fee (the lot's *due*). The buyer pays exactly the listed price in all; the seller receives the price minus the fee. Mints from drops have no market fee and are unaffected (from v8 a launch fee applies to paid mints, §3.17). - **Short holds.** The payment escrows must be scheduled no later than **B + 5** (B = the reservation's block). A multi-lot buy gets one more block for each extra seller it pays: B + 5 + (sellers − 1). Drop mints already have B + 5 (§3.14). - **Prompt payment.** Each payment escrow must execute at most **5 blocks** after it is scheduled (instead of 60), so a paid reservation can't be held open for long by an escrow that is cancelled at the last moment. - **Cool-down.** When a reservation ends without a sale or mint (its pay window runs out, or one of its escrows is cancelled or fails), the buyer can't make any new reservation (`buy` or a paid `drop-mint`) until **10 blocks** after the block it ended in. It still can't reserve that same listing again (§3.8). A completed purchase or mint never starts a cool-down. Each lot of a multi-lot buy that is released this way starts (or extends) the cool-down. Reservations made before the v7 block keep their old rules, including when the fee is paid. Losing a race for a reservation still costs only the reserving transaction's network fee: the reservation is rejected and nothing else is sent. ### 3.16 Market buys (v7) `{"op":"buy","tick":T,"spend":S,"max":M}` with an optional `"amt":A` buys token lots without naming them. It is valid from the v7 activation block (§3.11). Before that block a `buy` without `id` is invalid as before. - `spend`: a QTC amount greater than 0, the most the listed prices of the lots taken may add up to. - `max`: a decimal string with up to 18 decimal places, greater than 0, the most the buyer pays per whole token (a lot's price divided by its amount in whole tokens). - `amt`: optional, a token amount greater than 0 in the token's decimals, the most tokens the lots taken may add up to. When the transaction is applied, the indexer takes the open lots of `T` (no lock; not the signer's own; not a listing the signer is barred from, §3.8), at or under `max` per token, ordered by price per token ascending and then by listing id (block, then index) ascending. It walks that list once and takes each lot that keeps the total price within `spend` and the total tokens within `amt`, skipping a lot that doesn't fit, and skipping a lot whose seller would be a ninth seller; it stops after 50 lots. If no lot is taken the op is invalid and nothing is reserved. Otherwise the lots taken are reserved as one group exactly as by a multi-lot buy (§3.10), under the v7 rules (§3.15): one fee escrow and one price escrow per seller, each seller owed the sum of its lots' prices minus their fees, and the same cool-down rules apply (the cool-down also refuses a market buy). Market buys are applied in block order like every other op, so two buyers in the same block never collide on a lot: the first takes the cheapest lots, the second the cheapest lots left. A buyer only loses out when nothing is left within its limits. ### 3.17 Launch fee on drop mints (v8) From the v8 activation block (§3.11), a `drop-mint` on a paid drop (§3.12) made at or after it carries a **launch fee** to the fee address (§3.9), paid out of the price like a v7 market fee (§3.15): the minter pays the same total as before, the fee address receives the fee, and the issuer receives the rest. - The fee is `ceil(total × dropBps / 10000)` planck, where *total* = `price × slots` reserved, and `dropBps` is the rate last set by `fee-set` (§3.9), or **500** (5%) if none was. It is zero if there's no fee address, the rate is 0, the issuer is the fee address, or the total is below `freeBelow`. It is fixed when the `drop-mint` reserves its slots. - A reservation with a fee is paid with **two** one-time escrows from the minter, under the same timing rules as before (scheduled by the end of the pay window, §3.14; each executing within 5 blocks, §3.15): first one **to the fee address** of at least the fee, then one **to the issuer** of at least the total minus the fee, executing strictly after the fee escrow. A reservation without a fee is paid exactly as before, with one escrow of at least the total to the issuer. - The pieces are minted when the issuer's escrow executes `Ok` (§3.12). Cancelling, or an `Err` execution of, either escrow while the reservation is open releases it, with the v7 cool-down. - Reservations made before the v8 block, and free drops, carry no launch fee. ## 4. Resolving chunked content For an inscription without inline `d`, the indexer assembles the file from `data` operations with the same `h`, posted at any block before or after: 1. Gather candidate chunks for `h` and group them by `(n, i)`. Within each index, chunks signed by the **inscribing account** come first, then the rest in chain order. Duplicate bytes are dropped. 2. Try each `n` that has a candidate for every index, smallest first; concatenate one candidate per index, preferring earlier candidates; at most 1024 combinations. 3. The first concatenation whose sha256 equals `h` is the content (`ok`). Missing chunks: `pending`. Every combination fails: `corrupt`. A third party posting junk chunks can waste effort but never change anyone's art. Content status never affects ownership. --- ## 5. State checkpoints The protocol state (collections, tokens, inscriptions, chunks, commitments, escrows, sales, counters) has a canonical serialization (sorted keys; big integers as decimal strings). Its sha256 after applying block *n* is the **state digest** at *n*. The reference indexer publishes digests every 1000 finalized blocks at `/api/checkpoints`, so independent indexers can confirm they agree. --- ## 6. Display policy (not part of the protocol) A website built on QINS may decline to *display* content, but it can't change state: hidden inscriptions keep their numbers, owners and history. The reference site hides only illegal content (sexual material involving minors, extreme violence and similar), never copies, fakes or spam. --- ## 7. What QINS-1 deliberately leaves out - **Single-transaction swaps.** The escrow + lock design gives the same guarantees in three transactions. A future version may accept one `Utility.batch_all` with both, once wallet tooling can sign it. - **Sat-style tracking.** Quantus has accounts, not UTXOs, so inscriptions are standalone objects. - **Mutable metadata.** Names and attributes are fixed at inscription. --- ## 8. Reference implementation - `lib/protocol.js`: the rules, as a pure state machine (`beginBlock`, `apply`, `applyEscrow`, `stateDigest`). - `lib/extrinsic.js`: signer and remark from raw extrinsics; a metadata-driven SCALE decoder. - `lib/chain.js`: blocks and `ReversibleTransfers` events from a node. - `lib/indexer.js`: follows the chain; finalized journal, provisional tip, checkpoints. `npm test` checks the rules against crafted chain data in the real Quantus formats, and pastes the generated purchase, name-claim and inscription blocks into real bash and PowerShell sessions end to end.