BRC-161 Tokens

BSV-21 Fungible Tokens (JSON / Legacy)

This document specifies the legacy JSON wire encoding of BSV-21 fungible tokens: an ord inscription with content type application/bsv-20 . Token balances live in UTXOs. Each token is identified by the outpoint of its deploy output. Two supply models are supported: Fixed supply — the entire supply is created in one deploy output. Auth (authority) — deploy cre

Open Protocol Labs (info@opl.dev) Authors: David Case (dcase@opl.dev), Luke Rohenaz (luke@opl.dev) Contributors: Kurt Wuckert Jr. (kurt@opl.dev), Michael Boyd (root@opl.dev), Dan Wagner (dan@opl.dev)

How it connects

Relationships

Found in the source

Implementation links

These links are extracted from the upstream implementation section. Inclusion is not an OpenStandards endorsement.

Authoritative content mirror

Full upstream text

View source
Rendered from tokens/0161.md at the indexed upstream commit

Abstract

This document specifies the legacy JSON wire encoding of BSV-21 fungible tokens: an ord inscription with content type application/bsv-20. Token balances live in UTXOs. Each token is identified by the outpoint of its deploy output. Two supply models are supported:

  1. Fixed supply — the entire supply is created in one deploy output.
  2. Auth (authority) — deploy creates minting authority; later spends of authority mint new supply.

A binary script-prefix encoding of the same token model is described in BRC-162.

Motivation

Issuers need fungible tokens that:

  • have a stable id that is not a global ticker race,
  • move as UTXOs (split, merge, parallel spends), and
  • support both fixed supply and issuer-controlled minting.

BSV-21 identifies each token by its deploy outpoint and carries balances on outputs. The token fields are a prefix on the locking script: they do not replace the spend condition. Any script can follow — P2PKH, multisig, covenants, marketplace templates, and other contract locks — so token value and Bitcoin script stay composable. Indexers enforce per-token supply and authority rules; consensus does not run a separate token VM.

The JSON encoding in this document puts those fields in an ord inscription (application/bsv-20). The envelope and 1-sat output are only the carrier (BRC-160, BRC-159). Token identity, transfers, mints, and burns follow the UTXO and authority rules here — not 1Sat sat-ordering or origin tracking.

BSV-21 builds on an earlier BSV-20 inscription format, which is deprecated. It keeps the same content type and JSON "p": "bsv-20" so existing inventory stays readable.

Relationship to other documents

Concern Document
UTXOs as tokens (philosophy) BRC-45
1Sat origin and sat ordering BRC-159
Inscription envelopes BRC-160
Offline BEEF validity proofs BRC-176

This BRC does not define marketplace locks, overlay topic naming, or BRC-100 basket profiles for tokens.

Specification

Token identification

  • A token id is the outpoint of the deploy output that created the token.
  • The id field MUST use the form <txid>_<vout>: 64 lowercase hex txid characters, underscore, non-negative decimal vout.
  • That same underscore form is the token id everywhere else — APIs, storage, topic names, comparison. A token id is a BSV-21 identifier, not a general outpoint reference, so it does not take the BRC-36 dot form.
  • The token id is fixed for the life of the token. Transfers never change it.

UTXO model

BSV-21 balances are carried on transaction outputs. Spending a valid token (or authority) input and creating valid token (or authority) outputs is how supply moves, splits, merges, mints, or burns. Any Bitcoin locking script MAY lock a token output (P2PKH, multisig, covenant, marketplace template, …).

Content type and inscription

JSON BSV-21 fields live in a 1Sat / ord inscription on the output locking script:

  • Content type MUST be application/bsv-20.
  • Body MUST be a JSON object.
  • Protocol field "p" MUST be the string bsv-20.

Inscription envelope rules are defined in BRC-160. Unrecognized JSON keys MUST be ignored; only fields defined here affect validity.

Relationship to 1Sat Ordinals

The ord envelope is only the carrier for the BSV-21 JSON payload. Token identity, transfers, mints, and burns follow the UTXO balance and authority rules in this document — not BRC-159 sat ordering or origin tracking.

A spend moves tokens because valid value (or authority) inputs fund valid outputs of the same token id. Whether the 1-satoshi lands in a particular output under ordinal theory is irrelevant to BSV-21 admission.

Supply models

Fixed supply — deploy+mint

One output creates the token and holds the entire initial supply.

Field Required Description
p Yes bsv-20
op Yes deploy+mint
amt Yes Total supply as decimal string, max 2^64 - 1
dec No Decimal precision 0–18; default 0; string integer only
sym No See Symbol (sym)
icon No See Icon (icon)
{
  "p": "bsv-20",
  "op": "deploy+mint",
  "amt": "21000000",
  "sym": "GOLD",
  "dec": "8",
  "icon": "abc123…def456_0"
}

Token id = this output's outpoint.

Authority supply — deploy+auth

Deploy creates no token value. The deploy output is the first authority UTXO. Later authority spends mint value.

Field Required Description
p Yes bsv-20
op Yes deploy+auth
dec No Decimals 0–18, default 0 (string)
sym No See Symbol (sym)
icon No See Icon (icon)
amt No MUST NOT be present
{
  "p": "bsv-20",
  "op": "deploy+auth",
  "sym": "STABLE",
  "dec": "2",
  "icon": "abc123…def456_0"
}

Deploy under a contract

The deploy output may be locked with a covenant (or other contract) in the same transaction that creates the token.

In the fixed-supply model, the whole initial supply is born under the contract’s spend rules. In the authority model, minting capability is born the same way. Later holders still receive ordinary value outputs; what the contract enforces is whatever it locks (deploy, authority, or both).

Deploy display fields

sym, icon, and dec are optional deploy-only display metadata. They are set on deploy+mint / deploy+auth and inherited for wallets and indexers on all later operations. They MUST NOT appear as required fields on mint, auth, transfer, or burn. Missing or malformed display fields do not invalidate the deploy or the token id.

Symbol (sym)

Presence Optional on deploy
Type JSON string
Meaning Short human-readable ticker / name for UI
Uniqueness Not enforced. Many tokens MAY share the same sym. Applications MUST key tokens by deploy outpoint id, never by symbol alone.

Empty string and omission are both treated as "no symbol."

Icon (icon)

Presence Optional on deploy
Type JSON string
Meaning Pointer to on-chain image bytes used as the token icon

When present, icon MUST be an outpoint naming the output that holds the image:

  • Format: <txid>_<vout> (64 hex txid, underscore, non-negative decimal vout).
  • Relative form: _N (underscore + decimal vout) MAY be used when the image output is in the same transaction as the deploy. Indexers expand this to <deploy_txid>_N.

The referenced outpoint SHOULD be one of:

  1. Inscription — a 1Sat / ord inscription whose body is image (or other display) content (BRC-160); or
  2. B protocol — a Bitcom B protocol file output (19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut) whose payload is the image bytes.

icon is a pointer only. It is not embedded image data, not an HTTP(S) URL, and not required for token validity. Wallets resolve the outpoint (e.g. via OrdFS /content/{outpoint}) to fetch bytes and content type. If the outpoint is missing, unresolvable, or not image-like, UIs SHOULD fall back to a placeholder; the token remains valid.

Same-tx example (image inscribed on output 0, token deploy on output 1):

{
  "p": "bsv-20",
  "op": "deploy+mint",
  "amt": "1000",
  "sym": "TEST",
  "icon": "_0"
}

Operations after deploy

mint

Creates new supply by spending at least one valid authority input of the same token.

Field Required Description
p Yes bsv-20
op Yes mint
id Yes Token id (txid_vout of deploy)
amt Yes Amount minted in this output (string uint64)

Any number of mint outputs MAY be created from a single authority spend. Minted amounts are created, not drawn from input balances.

auth

Continues, splits, merges, or transfers minting authority. Does not carry token value.

Field Required Description
p Yes bsv-20
op Yes auth
id Yes Token id
amt No MUST NOT be present

Authority capabilities:

  • Split — one auth in → many auth out
  • Combine — many auth in → one auth out
  • Transfer — auth to a new locking script
  • End — spend auth with no replacement auth out (that auth is destroyed; minting for the token ends only when no auth outputs remain)

transfer

Moves existing supply.

Field Required Description
p Yes bsv-20
op Yes transfer
id Yes Token id
amt Yes Amount in this output (string uint64)

burn

Explicitly removes supply from circulation. Burn outputs are recorded for supply accounting (mints − burns) but carry no spendable token value. Spending a burn output later has no effect on token validation.

Field Required Description
p Yes bsv-20
op Yes burn
id Yes Token id
amt Yes Amount burned in this output (string uint64)

Field validation summary

Field Rules
amt Required: deploy+mint, mint, transfer, burn. Prohibited: deploy+auth, auth. Decimal string of uint64 (max 18446744073709551615).
id Required: mint, auth, transfer, burn. Format txid_vout (valid outpoint). Auto = deploy outpoint for deploy ops.
dec Optional on deploy only. String integer 0–18. Default 0. Numeric JSON numbers are not valid.
sym Optional on deploy only. Display string; not unique. See Symbol.
icon Optional on deploy only. Outpoint pointer to an inscription or B-protocol file. See Icon.

Validation rules

Validation is per token id within a transaction. Indexers admit or reject outputs; consensus miners do not enforce BSV-21 rules.

Deploy (deploy+mint, deploy+auth):

  • Always valid as genesis (no token-input check).
  • Token id := this output's outpoint.

Mint:

  • Requires at least one valid authority input of the same token.
  • Mint outputs create supply; they are not paid from transfer-input balances.

Auth:

  • Requires spending a valid authority input of the same token.
  • Auth inputs contribute 0 to token balance.

Transfer and burn (balance):

  • Let I = sum of amounts on valid value inputs of this token (prior admitted deploy+mint, mint, or transfer outputs — not auth, not burn).
  • Let O_t = sum of transfer output amounts for this token.
  • Let O_b = sum of burn output amounts for this token.
  • Admit transfer and burn outputs only when I >= O_t + O_b.
  • If O_t + O_b > I: those outputs are invalid and input tokens are burned (no admitted transfer/burn outs from that imbalance).
  • If I > O_t + O_b: the excess is burned (implicit burn).
  • Authority inputs do not relax transfer balance checks. Presence of auth does not allow unfunded transfers.
  • Burn inputs contribute nothing to I.

Display metadata:

  • sym, icon, and dec are set at deploy only (see Deploy display fields).
  • Later operations need not repeat them; indexers attach deploy metadata when serving balances.
  • Invalid or unresolvable icon does not affect balance or authority admission.

Locking scripts

Any valid locking script is allowed. BSV-21 does not constrain spend conditions beyond the inscription fields and the validation rules above.

Satoshi value (convention)

By convention in the 1Sat ecosystem, token outputs often hold 1 satoshi. That is ecosystem practice for indexing and wallet UX, not a consensus rule of this protocol. Validators MAY apply a 1-sat policy when admitting outputs.

Protocol identifier note

All JSON operations use "p": "bsv-20" for backward compatibility. Implementations MUST NOT require "p": "bsv-21". The name BSV-21 refers to this specification family (deploy-id tokens + auth), not the JSON p string.

Examples

Fixed supply lifecycle

  1. Deploy deploy+mint with amt: "10000", dec: "2" → token abc…_0 with 10 000 base units (100.00 display).
  2. Split — spend deploy; two transfer outs of 5 000 each.
  3. Pay — spend one 5 000; transfer 4 900 to recipient + 100 change.

Auth lifecycle

  1. Deploy deploy+auth → token def…_0, authority at that outpoint.
  2. Mint — spend auth; outputs: mint 1 000 000 + auth (continue).
  3. Distributetransfer splits of the mint output.
  4. Delegate — spend auth → two auth outs (admin A, admin B).
  5. End auth — spend an auth with no auth out; that authority ends. Minting stops only when the last auth is ended.

Balance check

Valid:

In:  1000 + 500 transfer
Out: 800 + 600 + 100 transfer

Invalid (all transfer outs rejected; inputs burned):

In:  500
Out: 300 + 400

Security considerations

  • Indexer trust — validity is not miner-enforced; wallets rely on overlays / indexers that implement these rules.
  • Symbol collisionsym is not unique; always key tokens by deploy outpoint id.
  • Auth compromise — holder of an authority UTXO can mint unbounded supply until that auth is ended.
  • Over-transfer burn — creating outputs that exceed inputs burns the inputs; careless tx building destroys balances.
  • Display spoofingsym is not unique; icon is an unauthenticated outpoint claim. Resolve the pointed inscription/B file independently if display integrity matters.

Implementations

References

  1. BRC-36 — Format for Bitcoin Outpoints
  2. BRC-45 — Definition of UTXOs as Bitcoin Tokens
  3. BRC-159 — 1Sat Ordinals — Single-Satoshi Tokens and Origin Tracking
  4. BRC-160 — 1Sat Ordinals — Inscription Envelopes
  5. B protocol (Bitcom 19HxigV4QyBv3tHpQVcUEQyq1pzZVdoAut)
  6. BRC-176 — BSV-21 Validity Proofs