DUST-20 REV 1.1.0

DUST-20 documentation

Guide

The lifecycle in plain language, with the arithmetic shown.

Protocol
DUST-20Registry id dust20, alias dust-20
Chain
BitcoinNetwork: mainnet
Ownership model
UTXOUnits are carried by satoshis in unspent outputs
Carrier
Inscription + spendDeploy and mint are inscribed; movement is a spend
Decimals
0Balances are whole units only
Document version
1.1.0Revised 2026-09-01
Lifecycle
ExperimentalNot a ratified multi-party standard
Owning repository
bitcoinuniverseio/dust-20Documentation source of truth

G.1 The lifecycle

Four things happen to a DUST-20 token, in order. Two of them are messages someone writes. Two of them are just Bitcoin.

1. Deploy

Someone inscribes a deploy. It names a ticker, a maximum supply, and the exact satoshis that back one unit. From that moment the ratio is fixed forever, and the first valid deploy of that ticker identity is the one that counts.

2. Mint

Someone inscribes a mint into an output whose value equals the units they are creating multiplied by the fixed ratio. The units now exist, sitting in that output.

3. Hold

Holding units means controlling the unspent output whose satoshis carry them. There is no balance record anywhere on Bitcoin, only an output you can spend.

4. Spend

Sending units means spending those satoshis. The output layout of the transaction you build decides which whole units survive and which are destroyed.

Why the satoshis matter

In most token systems the amount is a number inside a message, and you have to trust software to add it up correctly. In DUST-20 the amount is physically present in the transaction as bitcoin. If a ticker is backed at 546 satoshis per unit then 91 units occupy exactly 49,686 satoshis, and anyone can check that against the raw transaction. The same property is what makes DUST-20 dangerous: anything that happens to the satoshis happens to the units.

G.2 Reading a deploy

{
  "p": "dust-20",
  "op": "deploy",
  "tick": "dust",
  "supply": "1000000",
  "unit_sats": "546",
  "max_sats": "546000000",
  "lim_sats": "54600"
}
tick
The ticker as written. Its identity is this text in Unicode NFC form, folded to lower case, so DUST and dust are the same ticker and cannot both be deployed.
supply
One million whole units may ever exist. There are no decimals, so a unit is never divided.
unit_sats
Each unit is backed by 546 satoshis, forever. 546 is a common example because it matches the usual Bitcoin dust threshold for a P2WPKH output. It is not a default, and a deploy that omits the field is rejected.
max_sats
1,000,000 x 546 = 546,000,000 satoshis, about 5.46 BTC. This is a redundancy check: if it does not match the exact product the deploy is rejected rather than corrected.
lim_sats
54,600 satoshis per mint, which is 100 units. Optional. Omitting it, or writing "0", means one mint could take the whole supply.

Note what that max_sats figure means in practice. If this ticker is ever fully minted, 5.46 BTC is immobilised inside DUST-20 outputs for as long as people hold the units. Sizing a deployment is a decision about how much bitcoin every future holder has to lock up.

G.3 Reading a mint

{
  "p": "dust-20",
  "op": "mint",
  "tick": "dust",
  "amt": "100",
  "sats": "54600"
}

The mint says: create 100 units of dust, backed by 54,600 satoshis. Three numbers have to agree before a reader will accept it.

Deployment ratio546 sats per unitFrom the resolved deploy, never from the mint payload.
Declared backing100 x 546 = 54,600 satsThe sats field must equal this exactly.
Real output value54,600 satsThe Bitcoin output carrying the inscription must hold exactly this.

One satoshi off is invalid, and permanent

If the output holds 54,599 satoshis the mint is invalid. Bitcoin confirms the transaction, the inscription exists, and the units do not. There is no correction transaction. Check the output value in the wallet prompt before you sign.

Deploy a ticker

DEPLOY

One million units, each backed by 546 satoshis, capped at 100 units per mint.

{
  "p": "dust-20",
  "op": "deploy",
  "tick": "dust",
  "supply": "1000000",
  "unit_sats": "546",
  "max_sats": "546000000",
  "lim_sats": "54600"
}

max_sats is 1,000,000 × 546. lim_sats of 54,600 allows 100 units per mint.

Deploy without a per-mint cap

DEPLOY

Omitting lim_sats means a single mint may take the entire supply.

{
  "p": "dust-20",
  "op": "deploy",
  "tick": "grain",
  "supply": "21000",
  "unit_sats": "1000",
  "max_sats": "21000000"
}

Omitted and "0" both mean no per-mint limit. Use a cap if you want distribution over time.

Mint at the cap

MINT

100 units backed by exactly 54,600 satoshis.

{
  "p": "dust-20",
  "op": "mint",
  "tick": "dust",
  "amt": "100",
  "sats": "54600"
}

The inscription must sit at offset 0 of an output holding exactly 54,600 satoshis.

Mint a single unit

MINT

One unit backed by 546 satoshis.

{
  "p": "dust-20",
  "op": "mint",
  "tick": "dust",
  "amt": "1",
  "sats": "546"
}

The smallest valid mint for this deployment is one whole unit.

G.4 Worked transactions

You hold an allocation of 91 units backed at 546 satoshis each, sitting in one output worth 49,686 satoshis. You want to send 10 units to someone.

The safe construction

Partial send with colored change, no units lost
PartRoleValueUnitsWhy
in[0]Colored49,68691

Your allocation.

in[1]Cardinal20,0000

Ordinary bitcoin, added so the fee never touches colored satoshis.

out[0]Colored5,46010

The receiver. 10 x 546.

out[1]Colored44,22681

Your colored change. This output is what keeps the remaining units alive.

out[2]Cardinal18,0000

Ordinary change.

feeMiner2,0000

Taken entirely from cardinal value.

All 91 units survive: 10 whole blocks of 546 satoshis land inside out[0], and 81 whole blocks land inside out[1].

The construction that destroys 49 units

Same transaction, same intent, one output missing. There is no colored change output, so the 81 units you meant to keep have nowhere to be placed on purpose. Ordinal flow places them anyway, wherever the satoshis happen to land.

The same send with no colored change output
PartRoleValueUnits landingResult
in[0]Colored49,68691

Your allocation.

in[1]Cardinal20,0000

Fee funding.

out[0]Colored5,46010SURVIVES
out[1]Cardinal18,00032

32 whole units land in the output you built as ordinary change. They survive, in the wrong place, and your wallet has no idea they are there.

feeMiner46,22649BURNED

49 of 91 units are destroyed, and 32 more end up somewhere you did not plan. Bitcoin confirms this transaction normally. Your wallet shows a successful send. No node, explorer or fee estimator flags anything. Only a DUST-20 reader knows the balance moved. Run both constructions in the allocation simulator to see exactly where the satoshis land.

The one thing to remember

If you are sending part of an allocation and the transaction has no explicit colored change output, the remainder does not stay yours in any predictable way. Whole units land in whatever supported output the satoshis reach next, and everything past the end of the output range is destroyed. Do not approve it.

G.5 Support matrix

What Bitcoin Universe products actually do with DUST-20 today, taken from the capability registry rather than from intent.

Bitcoin Universe product surfaces that handle DUST-20
SurfaceActionsWhat that means
Core view discover view-collection view-activity view-transaction

Discovery and browsing of DUST-20 tokens, collections, activity and transactions.

Wallet view send receive

Balance display and ordinary Bitcoin send and receive of the outputs that carry units.

Inscribe deploy mint transfer

Building deploy and mint inscriptions, and the spend that moves an allocation.

Marketplace is read-only

DUST-20 marketplace availability is read-only. You can view, browse collections and read activity. You cannot list, buy, sell, make or accept offers, or settle. The recorded reason is that DUST-20 mutations are unavailable until a typed authoritative ownership resolver replaces the retired address-only legacy flow. See the full recorded state.

Every marketplace action, and whether DUST-20 supports it
ActionAvailableMode or recorded reason
view YES read-only
view-collection YES read-only
view-activity YES read-only
list NO DUST-20 mutations are unavailable until a typed authoritative ownership resolver replaces the retired address-only legacy flow.
update-listing NO DUST-20 mutations are unavailable until a typed authoritative ownership resolver replaces the retired address-only legacy flow.
unlist NO DUST-20 mutations are unavailable until a typed authoritative ownership resolver replaces the retired address-only legacy flow.
buy NO DUST-20 mutations are unavailable until a typed authoritative ownership resolver replaces the retired address-only legacy flow.
sell NO DUST-20 mutations are unavailable until a typed authoritative ownership resolver replaces the retired address-only legacy flow.
make-offer NO DUST-20 mutations are unavailable until a typed authoritative ownership resolver replaces the retired address-only legacy flow.
accept-offer NO DUST-20 mutations are unavailable until a typed authoritative ownership resolver replaces the retired address-only legacy flow.
cancel-offer NO DUST-20 mutations are unavailable until a typed authoritative ownership resolver replaces the retired address-only legacy flow.
settle NO DUST-20 mutations are unavailable until a typed authoritative ownership resolver replaces the retired address-only legacy flow.
reconcile NO DUST-20 mutations are unavailable until a typed authoritative ownership resolver replaces the retired address-only legacy flow.

Support outside Bitcoin Universe is not claimed here. If a wallet or marketplace says it supports DUST-20, test it against the published vectors before trusting it with a balance, because most of the transfer and burn behaviour on this site is settled by one implementation rather than by an agreed standard.