Bitcoin has no token standard and no NFT contract, yet since 2023 people have been trading "NFTs" and fungible tokens on it. None of this required a soft fork. Ordinals is a numbering scheme for satoshis that lives entirely in software outside the protocol. Inscriptions are arbitrary files stored in Taproot witness data and attached to a numbered sat. Runes are fungible token balances carried in OP_RETURN outputs. Bitcoin nodes validate the transactions as ordinary Bitcoin transactions and know nothing about the meaning an indexer gives them.
Ordinal theory: numbering every sat
Casey Rodarmor's ordinal theory gives each of the 2.1 quadrillion satoshis a serial number, in the order they are mined. The first sat of the genesis block's subsidy is sat 0; each block's subsidy continues the count from where the previous block's stopped.
To track a sat after it is mined, ordinal theory uses a first-in-first-out rule. Line up the sats of all inputs in input order, then hand them out to the outputs in output order, each output taking as many sats as its value. Whatever is left over is the fee, and those sats are assigned to the coinbase outputs of the block that includes the transaction, after the new subsidy sats.
def fifo(input_ranges, output_values):
"""input_ranges: (first_sat, count) per input, in input order.
output_values: value in sats per output, in output order."""
sats = [s for first, n in input_ranges for s in range(first, first + n)]
outputs, i = [], 0
for value in output_values:
outputs.append(sats[i:i + value])
i += value
return outputs, sats[i:] # leftover sats are the fee
print(fifo([(100, 3), (500, 2)], [2, 2]))
# ([[100, 101], [102, 500]], [501])
Real indexers work with ranges rather than lists, but the rule is the same. Because the numbering follows only from the block history, anyone running an indexer such as ord against a full node gets the same answer.
Some sats are labelled "rare" by their position in the schedule:
| Rarity | Which sat |
|---|---|
| Common | Any sat that isn't the first of its block |
| Uncommon | First sat of each block |
| Rare | First sat of each difficulty adjustment period |
| Epic | First sat of each halving epoch |
| Legendary | First sat of each cycle (halving and difficulty adjustment coincide) |
| Mythic | First sat of the genesis block |
These labels are a social convention. The protocol treats every sat as identical.
Inscriptions: files in the witness
An inscription puts content into a Taproot script-path spend, inside an envelope that can never execute:
OP_FALSE
OP_IF
OP_PUSH "ord"
OP_PUSH 1
OP_PUSH "text/plain;charset=utf-8"
OP_PUSH 0
OP_PUSH "Hello, world!"
OP_ENDIF
OP_FALSE OP_IF ... OP_ENDIF skips everything between, so the script is valid regardless of the data. Tag 1 is the content type, and the empty push 0 separates the fields from the body. Script pushes are limited to 520 bytes, so larger files are split across many pushes.
Creating one takes two transactions:
- Commit: pay to a Taproot output whose script tree contains the envelope. Only a hash of the script is visible on-chain.
- Reveal: spend that output through the script path. The script, and so the file, appears in the witness.
The inscription is attached to the first sat of the reveal transaction's first output by default, and its ID is the reveal txid plus an index, such as ...i0. From then on, whoever holds that sat "owns" the inscription.
Why the witness discount made it cheap
Since SegWit, block space is measured in weight units: non-witness bytes cost 4 WU each, witness bytes cost 1 WU, and a block may hold 4 million WU. Witness data is therefore about four times cheaper per byte than data in outputs. Taproot's tapscript also removed the old 10,000-byte script size limit, so a single inscription can be close to the size of a whole block. SegWit's discount was intended to favour signatures over UTXO-set growth; inscriptions use the same discount for images and text, and they don't add to the UTXO set beyond a small output.
BRC-20: a convention on top of inscriptions
BRC-20, introduced in March 2023, is not a Bitcoin feature. It is a set of text inscriptions containing JSON that indexers agree to interpret:
{ "p": "brc-20", "op": "deploy", "tick": "ordi", "max": "21000000", "lim": "1000" }
{ "p": "brc-20", "op": "mint", "tick": "ordi", "amt": "1000" }
{ "p": "brc-20", "op": "transfer", "tick": "ordi", "amt": "250" }
Balances exist only in indexer databases. To transfer, you inscribe a transfer inscription to yourself, then send that inscription to the recipient. Every step needs its own transaction, which leaves lots of small outputs, and correctness depends on indexers implementing the same rules.
Runes: fungible tokens in OP_RETURN
Rodarmor designed Runes as a leaner alternative, and the protocol went live at block 840,000, the April 2024 halving block. Runes doesn't use inscriptions or ordinal numbering at all. Rune balances belong to UTXOs, and instructions go in a runestone: an output whose script starts with OP_RETURN OP_13, followed by integer-encoded fields.
A runestone can:
- Etch a new rune: name, divisibility, symbol, optional premine, and optional open-mint terms (amount per mint, cap, block window).
- Mint from an open etching.
- Carry edicts that move amounts of a rune ID (written
BLOCK:TX, the position of its etching) to specific outputs.
Runes in the inputs that no edict assigns go to the first non-OP_RETURN output, or to an output named by a pointer field. If a runestone is malformed, it is a cenotaph and every rune in the transaction's inputs is burned. Because balances follow UTXOs, Runes fits Bitcoin's model better than BRC-20: one transaction can move many balances, and it doesn't need a separate transfer inscription.
Wallet pitfalls: spending the wrong sats
To an ordinary Bitcoin wallet, an output holding an inscription or runes is just a UTXO with some sats in it. It may pick that UTXO to pay a fee or merge it into change, and the inscription or tokens go with the sats to wherever FIFO sends them, sometimes to the miner.
Practical rules:
- Use an Ordinals-aware wallet (or
ord wallet) for addresses that hold inscriptions or runes. - Keep those assets in separate addresses or accounts from the BTC you spend day to day.
- If you must use a general wallet, use coin control and mark those UTXOs as frozen or do-not-spend.
- Inscriptions usually sit in outputs of a few hundred to 10,000 sats (
ord's default "postage"). A small-value UTXO in your wallet may be worth far more than its sats. - Never import a seed used for inscriptions into a wallet that auto-consolidates UTXOs.
ord wallet inscriptions # list inscriptions and their outpoints
ord wallet send --fee-rate 5 bc1p... 6fb9...i0 # send one inscription safely
The block space debate
Inscriptions and runes have competed with payments for block space, pushing fees up during mint rushes and filling the mempool with low-value transactions. Critics call it spam and argue that nodes should filter it. Supporters answer that the transactions pay market fees and are valid under consensus rules, and that filtering only in relay policy doesn't work because miners can accept them directly. Some node operators run Bitcoin Knots, which ships stricter default filters.
The dispute widened to OP_RETURN. Bitcoin Core used to relay only transactions whose OP_RETURN data fit within a small limit (around 80 bytes). Bitcoin Core 30.0, released in October 2025, relaxed this default so that larger data-carrier outputs are relayed. The reasoning was that the limit was being bypassed through the witness and private miner submission anyway. The change was contentious. Two points are often missed: it is mempool policy, not consensus, so blocks with large OP_RETURN outputs were always valid; and inscriptions don't use OP_RETURN at all.
Summary
| Ordinals | Inscriptions | BRC-20 | Runes | |
|---|---|---|---|---|
| What it is | Numbering for sats | Files attached to a sat | JSON token convention | UTXO-based fungible tokens |
| Where the data lives | Nowhere (derived) | Taproot witness | Taproot witness | OP_RETURN output |
| Validated by | Indexers | Indexers | Indexers | Indexers |
| Since | Jan 2023 | Jan 2023 | Mar 2023 | Apr 2024 (block 840,000) |
All four depend on an indexer reading ordinary Bitcoin transactions. If you build on them, run your own ord or indexer against your own node, pin the version you depend on, and treat wallet coin control as part of your security model.
Get the weekly commit
New blockchain deep dives every week.