Working guide
How BRC-20 works in practice
The specification states the rules. This page walks through what actually happens on chain and in your wallet, in order, with the numbers written out. If you read one section, read the two-phase transfer: it is where almost every surprise and almost every loss comes from.
The mental model
Picture a paper ledger. Every page is one ticker. Every line is one posting, in block order. Anyone with the same blocks and the same rulebook writes the same ledger.
Bitcoin does not keep this ledger. Bitcoin only stores the inscriptions, in order, forever. The ledger is what an indexer gets when it reads those inscriptions and applies the rules. Your balance is not a record anyone can edit; it is the result of a replay.
Three consequences follow, and they explain most BRC-20 behavior:
- Nothing validates at signing time. Bitcoin will happily confirm an
inscription that says
{"p":"brc-20","op":"mint","tick":"zzzz","amt":"999"}for a ticker that does not exist. You pay the fee, the transaction confirms, and the ledger records nothing. Invalid operations cost real money and produce nothing. - Order decides ownership. When two people inscribe the same new ticker, the earlier confirmed inscription owns it and the later one is simply ignored (R10). There is no tie-break beyond block height and position in the block.
- Moving a satoshi can move a balance. A transfer inscription is a bearer instrument. Spending it, even accidentally, settles it.
Deploying a ticker
A deploy opens the ledger page and fixes the economics permanently. There is no upgrade,
no admin key, no way to change max, lim, or dec later.
Worked example
Inscribe this content as text/plain;charset=utf-8:
{"p":"brc-20","op":"deploy","tick":"ordi","max":"21000000","lim":"1000"}
Reading it field by field:
| Field | Value | Effect |
|---|---|---|
tick | ordi | Claims the ticker, case-insensitively. ORDI is the same asset. |
max | 21 000 000 | Total units that can ever be minted. Immutable. |
lim | 1 000 | Most that any single mint may take. 21 000 mints minimum to exhaust supply. |
dec | omitted | Defaults to 18 decimal places. |
The deploy does not credit anyone anything. Deployers get no premine and no special rights: a deployer who wants tokens has to mint like everyone else. The one exception is a self-mint deploy (5-byte tickers), where only the deployer may mint.
Omitting lim sets the per-mint limit to max, so the very first
mint can take the entire supply. Setting dec to "0" makes the
token indivisible forever. Neither can be corrected afterwards.
Minting
A mint credits units to whoever first owns the mint inscription, which in practice is the address that receives the inscribed satoshi in the reveal transaction.
Worked example
{"p":"brc-20","op":"mint","tick":"ordi","amt":"1000"}
At confirmation the indexer checks, in order:
- Is
ordideployed in an earlier block, or earlier in this block? If not, nothing happens (R12). - Is
amtat mostlim(1 000)?"1001"would be invalid outright, not clipped (R13). - Do the decimals fit
dec? (R11) - Is there supply left? If only 400 remain, this mint credits 400, not 1 000 (R14).
Passing all four, the receiving address's available balance for
ordi increases by the credited amount and minted supply rises by the same
amount.
The last mint of a ticker is the protocol's only partial application. If 400 units remain
and you mint "1000", you receive 400 and the ticker is fully minted. Every
later mint, including one in the same block after yours, is worth nothing. This is why
mint-out races end with a block full of paid-for, empty inscriptions.
The two-phase transfer
Sending BRC-20 takes two Bitcoin transactions, and the balance moves on the second one.
Worked example: sending 100 ordi
Alice holds 1 000 ordi, all available. She sends 100 to Bob.
Phase one. Alice inscribes:
{"p":"brc-20","op":"transfer","tick":"ordi","amt":"100"}
She inscribes it to her own address. On confirmation the indexer checks that 100 is at most her available balance (R16) and posts:
| Column | Before | Change | After |
|---|---|---|---|
| available | 1000 | -100 | 900 |
| transferable | 0 | +100 | 100 |
| overall | 1000 | 0 | 1000 |
Phase two. Alice spends the transfer inscription's satoshi to Bob's address in an ordinary Bitcoin transaction. On confirmation:
| Account | Available | Transferable | Overall |
|---|---|---|---|
| Alice | 900 | 0 | 900 |
| Bob | 100 | 0 | 100 |
Bob receives it as available balance immediately. He does not need to do anything, and the spent transfer inscription is now inert: moving it again has no BRC-20 effect (R18).
Three ways a transfer inscription ends
| Where the inscription goes | Result | Rule |
|---|---|---|
| To another address | Sender debited, recipient credited. The intended case. | R19 |
| Back to the sender | Reservation released: the amount returns to available. A safe way to cancel. | R20 |
| Spent as transaction fee | The inscription is consumed and the amount returns to the sender's available balance. Nobody is credited. | R21 |
A wallet that does not understand inscriptions treats the transfer inscription's satoshi as ordinary change. If it spends that satoshi to pay a fee, or sweeps it into a consolidation transaction, the first-spend rule fires against whoever ends up holding it. Use a wallet that tracks inscriptions and never sweep an inscription-bearing UTXO with a general-purpose Bitcoin wallet.
Before you sign
- Ticker: exactly the 4 bytes you intend. Lookalike tickers using different Unicode characters are a known scam pattern, and the site's validator reports the byte length of what you paste.
- Amount: quoted as a string, within
limfor a mint, within your available balance for a transfer. - Destination: where the inscription lands, which is not always where your wallet's "recipient" field points.
- Available versus overall: only available balance can back a new transfer inscription.
- Fee: an invalid operation still costs the full inscription fee.
Bitcoin Universe support
The matrix below reflects what is wired in the Bitcoin Universe codebase as of 2026-09-01. Capabilities not listed are not currently supported.
| Surface | Supported | Authority and limits |
|---|---|---|
| Inscribe | deploy, mint, transfer |
Builds and inscribes the payloads described on this site. |
| Wallet | view, send, receive | Inscription-aware handling of BRC-20 balances and transfer inscriptions. |
| Marketplace | view, discover, view collection, view activity, list, update listing, unlist, buy, settle | Executed through the UniSat Marketplace Open API. Order authority, ownership checks, and confirmation policy are the provider's; settlement uses that workflow plus a wallet-signed PSBT. Universe keeps no local rollback state for those orders. |
| Marketplace offers | Not supported | Protocol-native BRC-20 offers are deliberately refused pending a reviewed non-custodial offer protocol. |
| Token explorer | Token, holder, and supply reads | Universe-operated BRC-20 read model over confirmed operations. Published coverage
is partial: no exhaustive mempool feed with a stable pending lifecycle. |
Two things are worth stating plainly. First, Universe marketplace execution for BRC-20 is provider-driven rather than settled against a Universe-operated order authority. Second, a Universe-internal BRC-20 marketplace authority exists in the indexer but ships default-off with published release blockers, so it backs no user-facing claim here.
Next
- Check a payload in the validator.
- Read the exact rules in the specification.
- Test a parser against the test vectors.
- Run an indexer? Start with indexer semantics.