diff --git a/README.md b/README.md index 100a9bbf..5029e6cb 100644 --- a/README.md +++ b/README.md @@ -238,6 +238,7 @@ BRC | Standard 174 | [Consensus-Unique Name Tokens — Identity Binding and Verified Resolution](./tokens/0174.md) 176 | [BSV-21 — Validity Proofs](./tokens/0176.md) 177 | [Wallet-Enforced Expiry for `noSend` Actions](./wallet/0177.md) +185 | [1Sat Ordinal Collections](./tokens/0185.md) 190 | [Access Gates for Metanet Rooms](./apps/0190.md) 210 | [Derived Collectibles](./apps/0210.md) 218 | [Chat-Native Command Grammar for the Metanet](./apps/0218.md) diff --git a/SUMMARY.md b/SUMMARY.md index 11501cf9..9b487dcd 100644 --- a/SUMMARY.md +++ b/SUMMARY.md @@ -130,6 +130,7 @@ * [P1Sat Permission Scheme for Basket `1sat`](./tokens/0165.md) * [Consensus-Unique Name Tokens — Identity Binding and Verified Resolution](./tokens/0174.md) * [BSV-21 — Validity Proofs](./tokens/0176.md) +* [1Sat Ordinal Collections](./tokens/0185.md) * [Miner-Enforced Resale-Royalty Covenant Tokens (OP_PUSH_TX)](./tokens/0226.md) ## Overlays diff --git a/tokens/0185.md b/tokens/0185.md new file mode 100644 index 00000000..dedd2583 --- /dev/null +++ b/tokens/0185.md @@ -0,0 +1,325 @@ +# BRC-185: 1Sat Ordinal Collections + +Open Protocol Labs (info@opl.dev) + +**Authors:** Luke Rohenaz (luke@opl.dev), David Case (dcase@opl.dev) + +**Contributors:** Kurt Wuckert Jr. (kurt@opl.dev), Michael Boyd (root@opl.dev), Dan Wagner (dan@opl.dev) + +## Abstract + +This BRC defines **collections** of 1Sat inscribed ordinals: a **collection** origin inscription and **collection item** inscriptions that reference it. + +The **user-minted** model (wallet / app mints) uses a [BRC-160](./0160.md) envelope on a 1-sat output, **MAP** metadata on the same output after `OP_RETURN`, and **Sigma** for issuer binding. + +The proposed **parent** path links an item through field 3 and an exact collection-origin spend. This can be useful when a separate publisher signature is unavailable. + +## Motivation + +Markets and wallets group ordinals into collections. Historical docs used MAP `subType` values `collection` / `collectionItem`. This BRC standardizes that MAP model with **Sigma** for issuer-bound membership for user-minted items, and documents how contract mints link items via parent when that path is unavailable. + +## Relationship to other documents + +| Concern | Document | +|---------|----------| +| 1-sat chains | [BRC-159](./0159.md) | +| Envelopes + basic MAP | [BRC-160](./0160.md) | +| Sigma wire format and verification | [BRC-183](https://github.com/opldotdev/BRCs/blob/codex/brc-183-sigma/scripts/0183.md) | +| Wallet storage / P1Sat | [BRC-147](./0147.md) / [BRC-165](./0165.md) | +| Historical docs | [1sat-ordinals collections](https://docs.1satordinals.com) | + +## Status and prior art + +This is a proposed verification profile for existing collection metadata. Parsing a collection claim is already implemented; full verification of both paths below is not established as universal deployed behavior. [BRC-159](./0159.md) defines token identity, [BRC-160](./0160.md) defines envelopes and parent spend proof, and this proposal adds collection vocabulary and issuer checks. [BRC-161](./0161.md), [BRC-162](./0162.md), [BRC-163](./0163.md) and [BRC-176](./0176.md) concern fungible BSV-21 tokens and do not establish collection membership. + +## Specification + +The key words MUST, SHOULD and MAY define conformance to this proposed profile. Existing unsigned metadata remains readable as a collection claim; it is not retroactively a verified issuer endorsement. + +This document defines one relationship: whether a given inscription is a **member** of a given collection. There are two ways to establish it, and a reader admits an output as a member if **either** succeeds. + +* **MAP path** — the item declares the collection in MAP and carries a Sigma signature from the collection's issuer. This is the user-minted case, where a publisher signs each item. +* **Parent path** — the item names the collection origin as its inscription parent and **spends** that origin in the mint transaction. The spend of the collection origin is the authorization in this path. + +Both paths are specified below, followed by the membership rule that reads them. + +### User-minted (MAP + Sigma) + +#### Same-output layout + +Collection and item mints put the inscription and MAP on **one** 1-satoshi output. For user-minted items, MAP follows the envelope after `OP_RETURN` ([BRC-160](./0160.md)). + +**User-minted shape:** + +``` +OP_FALSE OP_IF + "ord" + OP_1 "image/png" + OP_0 +OP_ENDIF + +OP_RETURN + 1PuQa7K62MiKCtssSLKy1kh56WWU7MtUR5 + SET + type "ord" + name "The Awesome Collection" + subType "collection" + subTypeData "{\"description\":\"…\"}" +| +``` + +**Item (absolute `collectionId`):** + +``` +… +OP_RETURN + 1PuQa7K62MiKCtssSLKy1kh56WWU7MtUR5 + SET + type "ord" + name "Item #3" + subType "collectionItem" + subTypeData "{\"collectionId\":\"\",\"mintNumber\":3}" +| +``` + +Lock/envelope order may vary as allowed by BRC-160. Collection and item mints on this path MUST carry a Sigma from the issuer, appended after MAP on the same output (`|` bitcom separator). + +#### Collection inscription + +MAP fields: + +| Key | Requirement | Value | +|-----|-------------|--------| +| `app` | MUST | Minting app id (string); descriptive, not authenticated app identity | +| `type` | MUST | `ord` | +| `name` | MUST | Collection display name (string) | +| `subType` | MUST | `collection` | +| `subTypeData` | MUST | Stringified JSON (below) | + +**`subTypeData` (collection):** + +| Field | Requirement | Meaning | +|-------|-------------|---------| +| `description` | MUST | Short description (string) | +| `quantity` | MAY | Declared size as a string, as in the published collection schema; omit if open-ended | +| `rarityLabels` | MAY | Rarity label-to-percentage object; see metadata rules below | +| `traits` | MAY | JSON object describing the trait schema; contents are application-defined | + +Unknown keys are ignored. Inscription body SHOULD be an image type for previews. + +Mint the collection **before** items that reference it (unless using same-tx relative ids below). A verifier MUST establish that the referenced output is a collection origin with the collection metadata above. An unavailable transaction is unresolved, not proof that the collection does not exist. + +#### Collection item inscription + +MAP fields: + +| Key | Requirement | Value | +|-----|-------------|--------| +| `app` | MUST | Minting app id (string); descriptive, not authenticated app identity | +| `type` | MUST | `ord` | +| `name` | MUST | Item display name (string) | +| `subType` | MUST | `collectionItem` | +| `subTypeData` | MUST | Stringified JSON (below) | + +**`subTypeData` (collection item):** + +| Field | Requirement | Meaning | +|-------|-------------|---------| +| `collectionId` | MUST | Collection origin outpoint (see forms below) | +| `mintNumber` | MAY | JSON integer giving the position in the set | +| `rank` | MAY | JSON integer starting at 1; 1 is most rare | +| `rarityLabel` | MAY | Label from the collection's scheme | +| `traits` | MAY | JSON array of trait objects; contents are application-defined | +| `attachments` | MAY | JSON array of attachment objects; contents are application-defined | + +#### Metadata types and conformance + +This profile retains the published schema's required top-level strings `app` and `name`, +required collection string `description`, optional string `quantity`, and +optional integer `mintNumber` and `rank` (`rank` starts at 1). A numeric string +is not an integer. Readers are not required to coerce values, recover names +from other fields, or accept malformed metadata. Optional fields may be +omitted; when present, they MUST have their specified types. + +For this profile, `rarityLabels` is a JSON object mapping labels to percentage +strings, using the published object example. If provided, its percentages MUST +sum to 100, as required by the original indexer rule. For this proposed profile, each percentage string MUST match `(?:0|[1-9][0-9]*)(?:\.[0-9]+)?` and represent a value from 0 through 100 inclusive. Sum exact decimal values, not binary floating-point approximations; signs, whitespace and exponent notation are invalid. The object MUST be nonempty. For example, `{"common":"3.00","rare":"97.00"}` is valid, whereas `{}` and `{"rare":"1e2"}` are not. This does not enforce +supply or guarantee that actual mints follow the declared distribution. The +historical documentation calls this field “stringified JSON”; this profile +places the object inside the already stringified `subTypeData` object, rather +than adding a second serialization layer. It does not require accepting arrays +as an alternative. For `traits` and `attachments`, this profile fixes only the container types in the tables. Interpretation and validation of their contents belong to application schemas; no rarity, attachment availability or trait-schema conformance is implied. The historical trait documentation has conflicting array/object descriptions; the container choices here are explicit proposal decisions. + +The [collection schema](https://docs.1satordinals.com/adding-metadata/collections), +[item schema](https://docs.1satordinals.com/adding-metadata/collectionitem-subtype) +and [base ord schema](https://docs.1satordinals.com/adding-metadata/ord-schema-type) +are the sources for these requirements. Those pages contain inconsistent +field-placement examples, and specify AIP signatures. This proposal explicitly +uses `subTypeData.collectionId` and Sigma for its MAP path; it does not claim to +be an unchanged transcription of the historical AIP profile. + +A valid signature establishes who signed particular bytes; it does not make +wrong-type or missing required metadata conforming. Implementations MAY expose +nonconforming historical records for inspection, but that is an application +choice and MUST NOT be reported as conformance to this profile. Verify the +original signed script bytes without rewriting metadata or reserializing JSON. + +#### `collectionId` forms + +`collectionId` identifies the collection **origin** outpoint. + +1. **Absolute** — exactly 64 hexadecimal txid characters, followed by `_` or `.`, followed by an index matching `0|[1-9][0-9]*` and bounded by uint32 (`4294967295`). No signs, whitespace, leading zeros or trailing characters are accepted. Normalize to lowercase `txid_vout` for comparison and indexing, without changing the signed source. Dot form denotes the same decoded outpoint; preserve dot form at BRC-36 boundaries. See [BRC-184](https://github.com/opldotdev/BRCs/blob/codex/brc-184-content-addressing/outpoints/0184.md). +2. **Same-transaction relative** — `_N` with the same canonical decimal uint32 index, identifying a different output in **this** transaction (e.g. `_0` when a later item output references collection output 0). The actual output must exist and be a collection origin; a reference to the item itself fails. + +Indexers MUST expand `_N` to `{this_txid}_N` using the item's transaction id before comparing or storing membership. Verification requires `N < output_count`, a distinct referenced output and the collection-origin checks; syntax alone does not establish those facts. `1sat-stack` implements relative expansion (`NormalizeRelativeOutpoint`), but that helper alone does not perform all these validation checks. + +Top-level MAP key `collectionId` (outside `subTypeData`) is **not** used for membership; only `subTypeData.collectionId` under `subType=collectionItem`. + +#### Issuer authenticity (Sigma) + +User-minted collection and item mints use **Sigma** so the signature is bound to this output's script / transaction. + +Each valid Sigma signer covering the collection metadata is an eligible **collection issuer** in this profile. Signatures that do not cover the membership-bearing fields MUST NOT authorize membership. Item membership on the MAP path requires a valid Sigma on the item from **that same signer** (see [Collection membership](#collection-membership)). + +Sigma wire format and verification are defined in [BRC-183](https://github.com/opldotdev/BRCs/blob/codex/brc-183-sigma/scripts/0183.md). + +#### Wallet filing (informative) + +Collectables use storage basket `1sat` under [BRC-147](./0147.md). [BRC-165](./0165.md) defines P1Sat permission requests; `p 1sat ` is a permission route, not the storage basket. A membership claim or overlay admission alone does not establish verified membership for wallet authorization. + +### Contract-minted (parent) + +A mint may use the [BRC-160](./0160.md) parent / child pattern when authorization is established by a collection-origin spend: + +1. The parent is the **collection origin** (the 1-sat collection inscription outpoint). +2. The item mint **spends that parent** as an input. +3. The item inscription includes **field 3 (parent)** set to that outpoint (encoding and spend proof per BRC-160). + +The parent item does not need collection-item MAP, `subTypeData.collectionId`, or Sigma under this path. The referenced collection origin MUST satisfy the collection metadata schema above, but it does not need Sigma for the parent path. The exact-origin spend supplies authorization. If the item also claims MAP-path conformance, evaluate that path and its metadata separately; malformed optional MAP does not manufacture or remove a valid parent-spend proof. + +For the 36-byte parent form, serialize the display txid's 32 decoded bytes in +reverse order, followed by the output index as four little-endian bytes. +[BRC-160](./0160.md) is authoritative for parent encoding and spend proof. +This parent serialization must not be substituted for Sigma's input-hash +preimage, whose separate rules are in BRC-183. + +Field 3 without spending the parent is not a valid link. For collection membership via this path, the parent MUST be the collection origin. Authorization is whatever the contract enforces on that spend — not owner Sigma. + +This exact-origin path can authorize children in only the transaction that spends the origin. Once spent, that outpoint cannot be spent again. Continued minting from a successor would need an additional profile that proves successor-to-origin ancestry; this proposal does not silently treat a successor as the origin. A contract can authorize output creation and signatures through its design; there is no general Bitcoin prohibition on contract-created MAP. The distinction here is the evidence used for membership. + +In-envelope MAP fields are an extension permitted structurally by BRC-160, but their decoding and precedence are not established by the inspected collection parser. They are outside this profile's MAP verification path. A reader may expose such fields as extension metadata, without using them to override the post-`OP_RETURN` membership fields. + +### Collection membership + +An output is a **member** of a collection if **either** path fully succeeds: + +1. **MAP path** — all of: + * The same-output post-`OP_RETURN` MAP has `subType=collectionItem` and `subTypeData.collectionId` naming the collection origin (including `_N` expansion), and + * the item carries a **valid Sigma** whose signer is the **same** as a valid Sigma signer covering the collection metadata on the collection origin. + +2. **Parent path** — inscription field 3 names that collection origin and the mint spends that outpoint ([BRC-160](./0160.md)). + +Either path alone is enough. Writers typically use one (MAP + matching Sigma for user-minted items; parent for contract mints). Readers do not require both. + +MAP `collectionId` without a matching collection-issuer Sigma is **not** membership on the MAP path — only a claim. + +### Validation and failure states + +Both collection and item outputs MUST be valid 1-satoshi inscriptions under BRC-160. A claimed collection MUST have `type=ord`, `subType=collection` and object-valued `subTypeData`; an arbitrary spent parent is not automatically a collection. Collection-origin metadata MUST satisfy the collection schema above. MAP-path items MUST satisfy the item schema; parent-path items follow the separate requirements in the parent section. Parse `subTypeData` as a UTF-8 JSON object. Malformed JSON, duplicate JSON member names or conflicting membership-bearing MAP fields invalidate the affected MAP schema. A non-string item `collectionId` fails the MAP path; it does not invalidate an independently valid parent path. Unknown metadata is ignored. Writers SHOULD emit one MAP `SET` segment and unique keys for this profile. + +Relative `_N` references cannot be resolved without the item's transaction. The referenced output must be distinct from the item and within the actual output count. Wrong-type optional metadata is nonconforming; invalid membership-bearing metadata fails verification. + +A reader MUST distinguish a parsed claim, unresolved evidence, verified membership and failed verification. Missing evidence required by the evaluated path produces unresolved evidence; unavailable Sigma inputs affect only MAP-path verification. A signature mismatch produces failed MAP-path verification; an independently valid parent path can still succeed. Verify the actual Sigma bytes and covered output prefix under BRC-183. Comparing signer strings without verifying signatures is insufficient. Exact signer-address equality is used; BAP rotation or issuer delegation requires an additional profile. + +Membership is assessed at inscription creation. It does not establish current ownership or transfer validity, which require BRC-159 tracking. Chain validation and reorganization handling remain necessary for accepted mint transactions. + +### Verification examples + +| Evidence | Result | +|----------|--------| +| Item names collection, matching valid covered Sigma on both | Verified MAP-path member | +| Item names collection, valid Sigma from unrelated signer | Claim; failed MAP path | +| Item names collection, collection transaction unavailable | Unresolved | +| Parent field names valid collection origin, exact origin spent in mint | Verified parent-path member | +| Parent field names origin, mint spends only its successor | Fails this profile's exact-origin path | +| `_2` names output 2 of same mint; output is a valid collection | Expand then verify Sigma; relative syntax alone is not authorization | + +### Historical example and reproducible evidence + +The historical **Musashi** collection provides a pinned example: + +| Role | Origin outpoint | +|------|-----------------| +| Collection | `ee8c1a403ad4d9396df261b96f53a30209c2ba419d0e9b41f4930a4602e72cde_0` | +| Item | `34adf92c766e11a656d3ff3508df7b1a31405821bf734bc9bef9fb43fcf701f9_0` | + +The item names that exact collection in `subTypeData.collectionId`. Both raw +transactions contain one-satoshi outputs with MAP before Sigma. Verification +of the raw script prefixes and compact signatures recovers the same public +key, `037da89fcbeab8c3fe819bb48eb46beada585f1a5b3532f3a729b24780138806dd`, +and signer address `12KP5KzkBwtsc1UrTrsBCJzgqKn8UqaYQq`. This establishes +cryptographically verified issuer binding for the supplied bytes, rather than +merely matching unverified signer strings. + +The root has top-level name `Musashi`, string quantity `"240"` and object +`rarityLabels`. The item's name `Musashi 42` exists only in `subTypeData.name`, +and its mint number is string `"42"`. The string quantity matches the published type. The string mint number and +nested-only item name do not satisfy the published schema; the empty rarity +object does not satisfy its percentage-total rule. These signatures remain +useful cryptographic evidence, but these records are not positive metadata +conformance fixtures. No historical string rank is asserted by this example. + +[Evidence JSON](./media/0185-musashi-evidence.json) records the pinned +transaction IDs, metadata, signature bytes, prefix lengths and hashes. +The recorded intermediate values allow independent reproduction of the signing calculation from the raw transactions. They are cryptographic examples, not a general BRC-160/185 validator. + +The item bytes are pinned in [1sat-stack's fixture](https://github.com/b-open-io/1sat-stack/blob/589884a6a445a57b62e79057d27040660bdaec37/pkg/template/bitcom/testdata/34adf92c766e11a656d3ff3508df7b1a31405821bf734bc9bef9fb43fcf701f9.hex). +Raw transaction retrieval sources for the [root](https://api.whatsonchain.com/v1/bsv/main/tx/ee8c1a403ad4d9396df261b96f53a30209c2ba419d0e9b41f4930a4602e72cde/hex) +and [item](https://api.whatsonchain.com/v1/bsv/main/tx/34adf92c766e11a656d3ff3508df7b1a31405821bf734bc9bef9fb43fcf701f9/hex) +are also listed in the JSON. + +A parsed collection reference is a **claim**. The checks above establish +**cryptographic issuer binding**. Accepted on-chain membership additionally +requires chain inclusion, transaction validity and origin evidence under +BRC-159/160. The evidence and verifier make no assertion of current canonical +chain inclusion, current ownership or complete membership validation. + +### Fungible-token wrapper boundary + +A BSV-21 deployment inscription can also carry collection-item MAP and Sigma. In that composition, this profile assesses the deployment inscription's relationship to the collection. It does not grant membership automatically to every fungible unit or subsequent BSV-21 transfer output. Token supply and transfer validity continue to follow their own BRCs; collection-specific metadata belongs outside the generic token JSON. + +## What this document does not cover + +* Enforcement of actual mint frequencies against declared rarity percentages +* On-chain royalty enforcement +* OrdFS / streams +* Non-collection MAP subTypes +* (Sigma wire format — [BRC-183](https://github.com/opldotdev/BRCs/blob/codex/brc-183-sigma/scripts/0183.md)) + +## Security considerations + +* **False `collectionId`** — anyone can write the string; MAP-path membership also requires valid Sigma from the collection issuer. +* **Parent path** — trust is the spend of the collection origin under contract rules. +* **Order** — items referencing a non-existent collection are not members under strict indexing. +* **Relative ids** — `_N` is only valid in the mint transaction that contains output `N`. + +## Implementations + +* [docs.1satordinals.com](https://docs.1satordinals.com) +* [b-open-io/1sat-stack](https://github.com/b-open-io/1sat-stack) — `ParseCollection` extracts claims and expands relative ids. Its [item topic manager](https://github.com/b-open-io/1sat-stack/blob/589884a6a445a57b62e79057d27040660bdaec37/pkg/collection/topic_item.go) requires valid Sigma but explicitly does not match the collection issuer at ingest. Overlay admission is therefore not full verification under this proposal. +* [b-open-io/1sat-sdk](https://github.com/b-open-io/1sat-sdk) — collection tooling; a cross-implementation conformance claim for this proposed verification profile requires shared fixtures. + +The SDK's standalone `mintCollectionItem({ ref })` creates only the item output, +so it cannot use `_N` to create sibling default content; `_0` would refer to +itself. Use an existing absolute content reference with that helper. Lower-level +multi-output ORDFS builders can support relative content references when the +corresponding content outputs are actually composed. This content-reference +limitation is separate from same-transaction collection IDs in this profile. + +## References + +1. [BRC-159](./0159.md) — 1Sat core +2. [BRC-160](./0160.md) — Inscriptions and basic MAP +3. [BRC-183](https://github.com/opldotdev/BRCs/blob/codex/brc-183-sigma/scripts/0183.md) — Sigma +4. [BRC-184](https://github.com/opldotdev/BRCs/blob/codex/brc-184-content-addressing/outpoints/0184.md) — Outpoint Content Addressing +5. 1Sat Ordinals metadata — diff --git a/tokens/README.md b/tokens/README.md index cf93efaf..7ad46b1c 100644 --- a/tokens/README.md +++ b/tokens/README.md @@ -23,4 +23,5 @@ BRC | Standard 165 | [P1Sat Permission Scheme for Basket `1sat`](./0165.md) 174 | [Consensus-Unique Name Tokens — Identity Binding and Verified Resolution](./0174.md) 176 | [BSV-21 — Validity Proofs](./0176.md) +185 | [1Sat Ordinal Collections](./0185.md) 226 | [Miner-Enforced Resale-Royalty Covenant Tokens (OP_PUSH_TX)](./0226.md) diff --git a/tokens/media/0185-musashi-evidence.json b/tokens/media/0185-musashi-evidence.json new file mode 100644 index 00000000..6cb2e0d2 --- /dev/null +++ b/tokens/media/0185-musashi-evidence.json @@ -0,0 +1,105 @@ +{ + "schema": "brc-185-musashi-evidence-v1", + "purpose": "Pinned raw-transaction and Sigma issuer-binding evidence; not full chain or membership validation.", + "sources": { + "item": "https://raw.githubusercontent.com/b-open-io/1sat-stack/589884a6a445a57b62e79057d27040660bdaec37/pkg/template/bitcom/testdata/34adf92c766e11a656d3ff3508df7b1a31405821bf734bc9bef9fb43fcf701f9.hex", + "root": "https://api.whatsonchain.com/v1/bsv/main/tx/ee8c1a403ad4d9396df261b96f53a30209c2ba419d0e9b41f4930a4602e72cde/hex", + "item_api": "https://api.whatsonchain.com/v1/bsv/main/tx/34adf92c766e11a656d3ff3508df7b1a31405821bf734bc9bef9fb43fcf701f9/hex" + }, + "records": [ + { + "role": "item", + "txid": "34adf92c766e11a656d3ff3508df7b1a31405821bf734bc9bef9fb43fcf701f9", + "outputIndex": 0, + "satoshis": 1, + "scriptLength": 14256, + "contentType": "image/webp", + "map": { + "app": "ZoideNFT", + "type": "ord", + "subType": "collectionItem", + "subTypeData": "{\"name\":\"Musashi 42\",\"collectionId\":\"ee8c1a403ad4d9396df261b96f53a30209c2ba419d0e9b41f4930a4602e72cde_0\",\"mintNumber\":\"42\",\"rarityLabel\":\"RARE\"}", + "royalties": "[{\"type\":\"paymail\",\"destination\":\"1HjN545U6hJewz5JiQX7QbTNPNUyqxhaSf\",\"percentage\":0.1}]" + }, + "subTypeData": { + "name": "Musashi 42", + "collectionId": "ee8c1a403ad4d9396df261b96f53a30209c2ba419d0e9b41f4930a4602e72cde_0", + "mintNumber": "42", + "rarityLabel": "RARE" + }, + "sigma": [ + { + "algorithm": "BSM", + "declaredSigner": "12KP5KzkBwtsc1UrTrsBCJzgqKn8UqaYQq", + "vin": 0, + "resolvedVin": 0, + "sourceTXID": "ce616907bb8d19f1c3a4f7767863e41b258afb5204278e7fb9ef07bc711a6342", + "sourceVout": 3, + "inputBytesHex": "ce616907bb8d19f1c3a4f7767863e41b258afb5204278e7fb9ef07bc711a634203000000", + "inputHash": "03a45f2a9557c8623e292468ff3837d755997d2ef018abfd6e3e5254aeac1f80", + "signedPrefixLength": 14141, + "signedPrefixSHA256": "2b2e513080bfdfbd07a0b32b1b147253f8aeea8aa182847dc57f1a36912688dc", + "sigmaSeparatorOffset": 14141, + "separatorOpcode": 1, + "messageHash": "1ac4e472b4a8d5614e61197d515e691f5f02bd38b4139763d4c805ed724f09c4", + "bitcoinSignedMessageDigest": "8aac6522f6609d3feae6704b54580b5b6be4a094d9c575c5788892d2f28c1e64", + "compactSignatureHex": "1fa86118c68c274c244148dc9b6d79e4bc812dcfdfebea511cb714a54a2ab2c8fe74472aaf9c87dac70129263467d4601ddd3aeb145b2c204c3c3bb6f41bbcbcf7", + "compactSignatureBase64": "H6hhGMaMJ0wkQUjcm2155LyBLc/f6+pRHLcUpUoqssj+dEcqr5yH2scBKSY0Z9RgHd066xRbLCBMPDu29Bu8vPc=", + "recovery": 0, + "recoveredPublicKey": "037da89fcbeab8c3fe819bb48eb46beada585f1a5b3532f3a729b24780138806dd", + "recoveredAddress": "12KP5KzkBwtsc1UrTrsBCJzgqKn8UqaYQq" + } + ] + }, + { + "role": "root", + "txid": "ee8c1a403ad4d9396df261b96f53a30209c2ba419d0e9b41f4930a4602e72cde", + "outputIndex": 0, + "satoshis": 1, + "scriptLength": 1279928, + "contentType": "image/png", + "map": { + "app": "ZoideNFT", + "type": "ord", + "subType": "collection", + "name": "Musashi", + "subTypeData": "{\"description\":\"A collection inspired by the solitude of a Samurai.\",\"quantity\":\"240\",\"rarityLabels\":{},\"traits\":{}}" + }, + "subTypeData": { + "description": "A collection inspired by the solitude of a Samurai.", + "quantity": "240", + "rarityLabels": {}, + "traits": {} + }, + "sigma": [ + { + "algorithm": "BSM", + "declaredSigner": "12KP5KzkBwtsc1UrTrsBCJzgqKn8UqaYQq", + "vin": 0, + "resolvedVin": 0, + "sourceTXID": "d57877f8b326e280b06d314bb419b443762def4cd855f59c897c4d5231f67aa7", + "sourceVout": 1, + "inputBytesHex": "d57877f8b326e280b06d314bb419b443762def4cd855f59c897c4d5231f67aa701000000", + "inputHash": "759fcc7978324c256c3c46d5cfa07a11ce0d439e61e3f681a6384d5d92fa6ed6", + "signedPrefixLength": 1279813, + "signedPrefixSHA256": "9e7b74dfbefe93fb4bfba4da052d4293cb57eecaddad76dc32bc6d9a4f1283db", + "sigmaSeparatorOffset": 1279813, + "separatorOpcode": 1, + "messageHash": "7217c217737f7713a4c4cccef9d8953b43932bd5b7518ddca70b8ef67e3042b5", + "bitcoinSignedMessageDigest": "783aa27839cec0cf083cd7e6fc0a65808201bbe22f8270a36bc3a06c445950f8", + "compactSignatureHex": "2017c1831b041446e82eaa68249802bad86e6a184b8861e4ad7a78d04ebfa6d4ef4907463f945917196d9eb4b5e2a7b1e738f856f3abd4e47b401221ecd499264a", + "compactSignatureBase64": "IBfBgxsEFEboLqpoJJgCuthuahhLiGHkrXp40E6/ptTvSQdGP5RZFxltnrS14qex5zj4VvOr1OR7QBIh7NSZJko=", + "recovery": 1, + "recoveredPublicKey": "037da89fcbeab8c3fe819bb48eb46beada585f1a5b3532f3a729b24780138806dd", + "recoveredAddress": "12KP5KzkBwtsc1UrTrsBCJzgqKn8UqaYQq" + } + ] + } + ], + "interpretation": { + "claim": "Item subTypeData.collectionId names the pinned root output.", + "issuerBinding": "Both compact signatures over the actual covered MAP prefixes recover the same signer; verifier requires raw transactions.", + "descriptiveCompatibility": "Item name is nested; root quantity and item mintNumber are canonical decimal strings. Root rarityLabels is an object. These descriptive forms do not invalidate issuer binding.", + "chainValidation": "Not performed by this fixture verifier; chain inclusion, transaction validity, origin status and ownership require separate evidence." + } +}