BRC-247 Peer to peer

Identity-Key Issuer Attestation

This BRC defines how a BRC-100 wallet attests 1Sat inscriptions and BRC-162 token deploys with its identity key, whichever wallet profile holds the token (1Color, BRC-207; P2P-FT, BRC-251). The issuance carries a SIGMA signature, made under BRC-77 by the issuing account's identity key and bound to one of the transaction's inputs. A holder reads the issuer fr

Brandon Cryderman / HandCash (brandongcryderman@gmail.com) Status: Draft (proposed number, not a BSVA assignment)

How it connects

Relationships

Authoritative content mirror

Full upstream text

View source ↗
Rendered from peer-to-peer/0247.md at the indexed upstream commit

Abstract

This BRC defines how a BRC-100 wallet attests 1Sat inscriptions and BRC-162 token deploys with its identity key, whichever wallet profile holds the token (1Color, BRC-207; P2P-FT, BRC-251). The issuance carries a SIGMA signature, made under BRC-77 by the issuing account's identity key and bound to one of the transaction's inputs. A holder reads the issuer from the signature itself. JSON token deploys (BRC-161) can carry the same stamp. Names and images for an identity key, and optional BAP profiles linked to it, are BRC-248.

Motivation

BRC-163 lets a token deploy carry a Sigma signature by "the issuer's identity key", and BRC-160 leaves issuer authenticity for 1Sat inscriptions to a separate specification. BRC-162 tokens, and the wallet profiles that hold them (BRC-207 and BRC-251), identify an asset by its deploy outpoint and define no identity system. None of them says what is signed, binds the signature to the transaction, or says how a later holder learns who issued the asset.

Every BRC-100 application already identifies users by identity key: mutual authentication, BRC-52 certificates, BRC-169 handles and messagebox addressing all name it. Signing assets with a second identity, such as a BAP identity with its own rotating keys, would leave users and holders with two identities to reconcile. This BRC makes the identity key the issuer and leaves profiles to BRC-248.

Specification

Roles

Thing What it is
Issuer The BRC-100 identity key of the account that issues. In a vault of several accounts (BRC-208), each account's own identity key.
Stamp An input-bound SIGMA signature under BRC-77 by the issuer, with a MAP issuer tape where this BRC requires one.
Profile A name and image for an identity key, from BRC-248: a BRC-169 handle, publicly revealed BRC-52 certificates, or a linked BAP profile.

Signing

The stamp is a SIGMA tape with algorithm BRC77. Its signature is a BRC-77 signed message by the issuer, addressed to anyone (no specific verifier):

  • The BRC-77 signature carries the issuer's identity public key. Verifiers MUST take the issuer from it. The SIGMA address field MUST be the address of that key; an address alone does not identify the issuer.
  • BRC-77 signs with a BRC-42 child of the identity key (protocol [2, "message signing"], a fresh key ID). The identity private key never signs on chain directly. A BRC-100 wallet produces it with createSignature under that protocol and counterparty anyone.
  • Writers MUST use BRC77. A verifier MAY accept a BSM SIGMA whose signing address is the address of the issuer named in the MAP tape, as written by earlier 1Sat tooling; it MUST NOT accept a BSM stamp with no MAP issuer.

vin is the ASCII decimal index of a real input. SIGMA signers resolve -1 to a concrete index before writing, as 1sat-sdk does, so verifiers MUST reject a SIGMA vin of -1. As SIGMA defines, the signed message is sha256(inputHash ‖ dataHash):

  • inputHash is sha256 of the outpoint spent by input vin: the 32 bytes of its txid in display order (as the hex is written, not reversed), followed by its output index as a 4-byte little-endian integer.
  • dataHash is sha256 of every chunk of the locking script before the | that introduces the SIGMA tape.

The issuer signature is the first SIGMA tape. Later signatures, such as the platform co-signature the 1Sat docs describe, sign over it and do not change the issuer.

Asset attestation layout

Asset Where the stamp goes
1Sat inscription At the end of the inscription output
BRC-162 deploy (1Color or P2P-FT) In a separate stamp output of the deploy transaction
JSON token deploy (deploy+mint or deploy+auth, BRC-161) At the end of the deploy output

A 1Sat inscription or JSON token deploy output MAY end with:

OP_RETURN
  1PuQa7K62MiKCtssSLKy1kh56WWU7MtUR5
  SET
  issuer
  <issuer identity key, compressed hex>
  |
  SIGMA
  BRC77
  <issuer address>
  <signature>
  <vin>

Here dataHash covers the envelope, the owner lock and the MAP tape. The MAP tape is optional on these outputs because the BRC-77 signature already names the issuer, and 1sat-sdk writes the SIGMA tape alone. If the tape is present, issuer MUST equal the key in the signature.

A BRC-162 deploy MAY be accompanied by one stamp output in the same transaction:

OP_FALSE OP_RETURN
  1PuQa7K62MiKCtssSLKy1kh56WWU7MtUR5
  SET
  issuer
  <issuer identity key, compressed hex>
  deploy
  <SHA-256 of output 0's locking script, lowercase hex>
  |
  SIGMA
  BRC77
  <issuer address>
  <signature>
  <vin>

BRC-162 requires a deploy to be output 0, so the stamp output names it by position. The deploy output stays an ordinary BRC-162 prefix followed by its owner lock, which BRC-207 and BRC-251 wallets hold as ordinary custody. They would not hold it if a tape followed the lock. The stamp output holds 0 satoshis, carries no token prefix, and MUST carry the MAP issuer tape. Its dataHash covers that tape, whose deploy hash commits to the deploy's id, amount, payload and owner lock. A verifier MUST check that deploy equals the SHA-256 of output 0's locking script and that output 0 is a BRC-162 deploy. If either check fails, the stamp asserts nothing. A transaction MUST NOT carry two stamp outputs.

The issuer metadata is a MAP SET tape. MAP is the Bitcom protocol that 1Sat inscriptions already use for metadata. If the script already has an OP_RETURN section, the tape goes after a |. MAP keys MUST NOT repeat, and a script MUST NOT carry two issuer tapes. Readers ignore other MAP keys in the issuer tape. A bapId written by earlier stamps matters only as Earlier BAP-signed stamps describes.

A tag or customInstructions claim is not a proof. A mined issuer tape with no valid SIGMA tape asserts nothing, and readers MUST ignore its issuer.

Signing order

A wallet that does not yet know the funding outpoint MUST NOT sign. It MAY write the unsigned tape and sign in a later step.

Input signatures commit to the outputs, so the stamp must be complete before any input is signed. A BRC-100 wallet selects funding after the requested outputs are fixed. An issuer stamping a BRC-162 deploy through such a wallet supplies the vin input itself and keeps output order (randomizeOutputs: false).

BRC-163

A token deploy stamped under this BRC satisfies the BRC-163 issuer attestation: BRC-163's issuer key is the identity key. A writer that sets the BRC-163 issuer:<pubkeyHex> filter tag MUST use the issuer identity key.

Not a processing profile

The stamp is evidence for display, not a BRC-162 wallet processing requirement. A deploy MUST NOT name this BRC in its req map. A required profile makes every wallet that does not implement it refuse the asset (a BRC-251 wallet refuses any non-empty req), and the stamp is optional (see Unsigned issuance). An issuer in a payload ext entry or a display field is a claim, not a stamp, and readers MUST NOT show it as the issuer.

Earlier AIP signatures

The 1Sat docs (Signing, Collection SubType) describe an earlier form, | AIP <address> BITCOIN_ECDSA <signature> -1, where -1 means the whole output script is signed. It signs no input, so anyone can copy the script into another transaction and the signature still verifies. A verifier MAY show such a signer as an unbound claim, but MUST NOT treat it as a stamp under this BRC.

Earlier BAP-signed stamps

Earlier drafts of this BRC signed with a BAP signing key and named a bapId. Such a stamp names a BAP key, not an identity key. A reader MAY attribute it to an identity key only through a BRC-248 link from the BAP identity its bapId names, with the signing key active for that BAP identity at the asset's mined height. Otherwise its issuer is unknown. Writers MUST NOT sign new stamps with BAP keys.

Collections

The 1Sat Collection SubType requires the collection record and its members to be signed by the same key. Under this BRC that key is the issuer identity key, so a member is signed by its collection's issuer when both stamps verify for the same identity key.

Unsigned issuance

The stamp is optional. An asset can be worth holding for its content or its spendable value alone, whoever made it. A 1Sat inscription or token deploy without an issuer stamp is a valid asset, as BRC-163 already says of unsigned deploys:

  • A wallet MUST let the user issue without a stamp, and MUST show the user that the asset will name no issuer.
  • An unsigned issuance MUST NOT carry the issuer tape, a stamp output, an issuer: tag or an issuer field in customInstructions.
  • A wallet MUST NOT stamp with any key other than the issuing account's identity key.
  • Receivers MUST accept unsigned assets and show the issuer as unknown, not as a defect.

A user who wants an issuance unlinked from their usual identity issues it unsigned, or from another account.

Attributing a held asset

The stamp sits on the genesis output (1Sat) or in the deploy transaction (BRC-162 or BRC-161). A later holder holds a different output, so a stamp alone says nothing about that output. A wallet MUST NOT show an issuer for a held output until the output is bound to the stamped issuance:

Asset Binding
1Sat inscription A complete BRC-150 proof from the held output back to the stamped origin
BRC-162 or BRC-161 token A BRC-176 validity proof from the held output back to the stamped deploy, whose outpoint is the token id

The proof carries the stamped transaction, including a BRC-162 stamp output, so a holder verifies the stamp offline. If the binding is missing or does not verify, the issuer is unknown. An indexer's answer MAY be displayed only as unproven.

Display key

A wallet that has verified a stamp SHOULD key display by (issuer, tokenId), with the issuer identity key as the evidence and a BRC-248 profile as its label. BRC-207 and BRC-251 identify an asset by its token id alone. An asset with no verified stamp keeps the token id alone and has no issuer.

Relationship to other documents

Concern Where it lives
Issuer identity The BRC-100 identity key
Asset issuer stamp This BRC
Name and image for an identity key BRC-248
Handle bound to an identity key BRC-169
Certified attributes of an identity key BRC-52
Optional BAP profile BAP records, linked to an identity key under BRC-248

Non-goals

  • A second identity key tree for issuance, including BAP signing keys or a [0, "sigma identity"] protocol ID.
  • Rotating or revoking a stamp's key.
  • Changing BAP, BRC-52 or BRC-169 formats.
  • Delegating issuance by handing a child private key to another wallet.

Rationale

The identity key rather than a BAP identity. Holders, applications and handles already address users by identity key. A BAP identity is a second identifier with its own key chain. Attributing an asset to it needs that chain, and block heights for every rotation. With the identity key, the stamp names the issuer and nothing else needs checking. BAP profiles remain usable as an optional profile source (BRC-248).

BRC-77 rather than the identity key directly. BRC-77 signs with a derived child and carries the identity public key. The stamp names the identity key without putting signatures by the identity private key on chain, and a BRC-100 wallet makes it through its ordinary signing interface.

No rotation. A rotatable stamp key protects little. The identity key also controls the wallet, so whoever compromises it already has the wallet. Stamps cannot be revoked. Holders judge an issuer by its profile and history.

Linkability. Every stamp links its asset to the issuer's identity key, which issuers usually want. An issuer can still issue unlinked, either unsigned or from another account.

A separate output for BRC-162 deploys. BRC-207 and BRC-251 wallets hold a token output as ordinary custody only when its prefix is followed by an ordinary P2PKH lock. A tape after the lock would leave the issuer's own supply or minting authority outside that custody. The BRC-162 payload cannot hold the stamp either: SIGMA signs the bytes before its tape, and a signature inside the payload would sign itself. A separate output keeps the deploy a plain managed output. The input binding limits the stamp to one transaction, and its deploy hash fixes which output 0 it names, so nobody who controls that input can pair the stamp with a different deploy.

MAP for the issuer metadata. MAP is the registered Bitcom protocol that 1Sat inscriptions already use for metadata, and readers already parse it. A bare JSON push has no protocol prefix and would need its own parser rules.

Reference implementations

  • 1sat-sdk: packages/templates/src/bitcom/sigma.ts implements the SIGMA tape with BSM and BRC77; packages/actions/src/apply/inscribeSigma.ts binds it to a 2-sat anchor input.
  • HandCash Desktop (@handcash/wallet-ui): src/wallet/sigmaIssuer.ts (SIGMA BRC77 sign and verify) and src/wallet/issuerMetadata.ts (the issuer tape), with readers in src/wallet/issuerAttribution.ts. HandCash stamps and reads 1Sat items only. It no longer holds BRC-162 tokens, so it implements neither the BRC-162 stamp output nor attribution through a BRC-176 proof.