Skip to main content
BRC-20 is a token standard built on top of the Bitcoin Ordinals protocol, enabling the creation and trading of fungible tokens on the Bitcoin blockchain by inscribing structured JSON data into satoshis. The ordinal/inscription layer stores raw text on-chain, and off-chain indexers and wallets interpret that text to derive token state such as deployments, minting, and transfers.

Common fields

Every BRC-20 inscription must be valid JSON. Two fields appear in all operations:
p
string
required
Protocol identifier. Must equal "brc-20".
tick
string
required
Token ticker symbol. Typically 3–6 characters. See namespace isolation for length rules.

Operations

Deploy

Creates a new token definition. The first valid deploy inscription for a ticker becomes the canonical definition of that token.
{
  "p": "brc-20",
  "op": "deploy",
  "tick": "ordi",
  "max": "21000000",
  "lim": "1000"
}
op
string
required
Operation type. Must equal "deploy".
tick
string
required
Ticker symbol for the new token.
max
string
required
Maximum token supply as a stringified integer. Under self-mint semantics, "0" means unlimited supply.
lim
string
Maximum amount mintable per individual mint inscription. Optional.
self_mint
string
Set to "true" to enable restricted issuance mode (deployer-only minting). Any other value or omission defaults to public minting.

Mint

Issues token units from a previously deployed token, up to the defined supply cap.
{
  "p": "brc-20",
  "op": "mint",
  "tick": "ordi",
  "amt": "1000"
}
op
string
required
Operation type. Must equal "mint".
tick
string
required
Ticker of the token to mint.
amt
string
required
Amount to mint as a stringified integer. Must not exceed the lim value defined in the deploy inscription.

Transfer

Moves token balance to another address. BRC-20 transfers are a two-step process:
  1. Inscribe a transfer inscription on a satoshi (this locks the specified balance).
  2. Send that satoshi (ordinal) to the recipient’s Taproot address.
The recipient address is not included in the JSON — the transfer is completed by physically sending the ordinal to the destination.
{
  "p": "brc-20",
  "op": "transfer",
  "tick": "ordi",
  "amt": "500"
}
op
string
required
Operation type. Must equal "transfer".
tick
string
required
Ticker of the token to transfer.
amt
string
required
Amount to transfer as a stringified integer.
Transfers require the recipient to have a Taproot address (bc1p...). Sending to non-Taproot addresses is not supported.

Self-mint

Overview

The default BRC-20 issuance model is permissionless: once a token is deployed, anyone may mint until the supply cap is reached. Self-minting is a restricted issuance mode where only the deployer is allowed to mint tokens after deployment. This is achieved via an explicit opt-in flag on the deploy inscription. Indexers enforce the parent inscription requirement.

Enabling self-mint

Add "self_mint": "true" to the deploy inscription:
{
  "p": "brc-20",
  "op": "deploy",
  "tick": "token",
  "max": "21000000",
  "lim": "1000"
}
When self_mint is enabled:
  • All subsequent mint inscriptions must use the deploy inscription as their parent. Mint inscriptions without this parent relationship are invalid.
  • max=0 is redefined to mean unlimited supply, bounded only by indexer max-uint64 constraints.

Unlimited supply via max=0

{
  "p": "brc-20",
  "op": "deploy",
  "self_mint": "true",
  "tick": "ordi",
  "max": "0",
  "lim": "1000"
}
max still represents the global mint ceiling. BRC-20 tokens cannot be destroyed, and transfers to unspendable addresses do not reduce mint capacity.

Namespace isolation

To avoid collisions with existing assets and legacy indexers, tickers are segmented by byte length:
Ticker lengthRulesSelf-mint support
4 bytesLegacy namespace, unchangedNo
5 bytesExtended namespaceYes
6 bytesExtended namespace with snipe protectionYes
Indexers that do not support extended namespaces will ignore 5-byte and 6-byte tickers.

6-byte tickers and snipe protection

The BRC-20 ticker namespace was extended to support 6-byte tickers with Phase 1 of BRC2.0, while preserving compatibility with existing 4- and 5-byte semantics.

Ticker constraints

6-byte tickers must:
  • Be exactly 6 characters
  • Match the regex ^[A-Za-z0-9-]{6}$
  • Be treated case-insensitively
Invalid examples include unicode, symbols other than -, or incorrect length. 4- and 5-byte tickers remain unchanged and unaffected.

Snipe protection via pre-deploy commitment

To prevent ticker sniping and front-running, 6-byte tickers require a pre-deploy commitment before the actual deploy. Pre-deploy inscriptions commit to a ticker without revealing it by inscribing a hash:
hash = sha256(sha256(ticker_bytes + salt_bytes + deployer_pkscript))
This binds the ticker to both a salt and the deployer’s pkscript, preventing replay or theft.

Step 1: Pre-deploy inscription

{
  "p": "brc-20",
  "op": "predeploy",
  "hash": "<computed_hash>"
}
op
string
required
Must equal "predeploy".
hash
string
required
sha256(sha256(ticker_bytes + salt_bytes + deployer_pkscript)) encoded as hex.

Step 2: Deploy inscription

{
  "p": "brc-20",
  "op": "deploy",
  "tick": "ticker",
  "salt": "<salt_used_in_hash>",
  "self_mint": "true",
  "max": "21000000",
  "lim": "1000"
}
salt
string
required
The same salt used to compute the pre-deploy hash. Indexers recompute and validate the commitment.

Deployment rules

  • The deploy inscription must be a child of the pre-deploy inscription.
  • The deploy must occur at least 3 blocks after the pre-deploy.
  • Indexers must reject deploys that violate ordering or hash validation.
  • Pre-deploy inscriptions do not expire and remain valid if transferred.
Pre-deploy inscriptions are accepted starting 10 blocks before the 6-byte namespace activation height (912690).

Required tooling

To create or interact with BRC-20 inscriptions:
  • Inscription platforms: UniSat, Ordinals Wallet, LooksOrdinal
  • Indexers / explorers: Ordiscan, BRC-20.io

Limitations

The Bitcoin blockchain does not enforce BRC-20 rules. All validation — determining the canonical deploy, mint, and transfer history — is performed by off-chain indexers. Token state is only as reliable as the indexers interpreting the inscriptions.
Transfers require Taproot-compatible addresses (bc1p...). Sending to non-Taproot addresses is not supported by the protocol.