Bitcoin mainnet · Name registry · Bitcoin Stamps carrier

A name registry written into Bitcoin transaction outputs

SRC-101 turns a Bitcoin transaction into a register entry. A deploy opens a namespace, a mint claims a name inside it for a paid term, and setrecord, transfer and renew keep that entry current. Names are leased, not owned outright: every entry carries an expiry, and when the expiry passes the name returns to the pool.

At a glance


What it actually is, in plain language

Think of a paper register in a records office. Somebody opens the book: this book is for names ending in a particular way, here is the price per name length, here is the address that collects the fees, here is how long one term lasts. That is a deploy. After that, anyone can write a line in the book claiming a free name for a number of terms, provided they pay the listed price to the listed address. That is a mint.

Once a line exists, the person who owns it can change the details recorded under the name (setrecord), hand the line to somebody else (transfer), or pay again to push the expiry date further out (renew). If nobody renews before the expiry date, the line goes quiet and the name becomes claimable by anyone again.

What makes this a Bitcoin protocol rather than a database is where the book lives. Each of those operations is a short JSON document written into a Bitcoin transaction output script through the Bitcoin Stamps data carrier. Bitcoin does not know or care what the document says. It confirms the transaction, and then indexers, programs that read the whole chain in order, apply the same rules and arrive at the same register.

The consequence people miss

A confirmed Bitcoin transaction is not a successful registration. Your transaction can confirm perfectly and your mint claim nothing, because somebody claimed the name two blocks earlier, or because the output paying the collector was one satoshi short. Always check the register afterwards, not just the transaction status. The validity rules spell out every case, and the status code table names each failure.

The register entry, and the two states it can be in

Everything in SRC-101 reduces to one row per name inside one namespace. This site draws that row the way the protocol stores it: the name in the lead, its record fields beneath, and a single mark for whether the term is still running.

Namespace 3a7f...c19bRegister, illustrative

satoshi

Active
tokenid
c2F0b3NoaQ==
owner
bc1qs2x...kgwls
expires
mint time plus dua years
preowner
none, first claim
address_btc
bc1qs2x...kgwls
primary
yes

lapsed

Expired
tokenid
bGFwc2Vk
owner
row still present
expires
already passed
renew
refused, status OE
transfer
refused, status OE
mint
open to anyone

An expired entry is not deleted. The row stays in the owners table with its old owner and its old expiry, and every owner-only operation against it fails. What changes is that a fresh mint of the same name now succeeds and overwrites the row, recording the previous holder as preowner.

Who this is for

If you want to hold a name

Start with the guide. It walks through choosing a namespace, what a term costs, why the payment output has to be exact, and what happens as your expiry approaches.

If you are building a wallet or app

Read the specification end to end, then check your builder against the test vectors. The validator catches the key-set mistakes that silently exclude a payload.

If you are writing an indexer

The key-set rules, the activation heights and the indexer semantics are where implementations diverge. Two of them are unusual enough that a reasonable implementer will get them wrong.

If you came from SRC-20

Same carrier, same prefix, same keyburn requirement, and almost nothing else in common. Go straight to what they share and where they diverge.

The lifecycle of one name

Five operations, one expiry clock. Everything below the deploy is scoped to a single name inside a single namespace, identified by the deploy transaction hash plus the decoded name.

The SRC-101 name lifecycle A deploy opens a namespace. A mint claims a free name and starts an expiry clock. While the term is running, the owner may setrecord, transfer or renew. When the expiry passes, owner operations are refused and the name becomes mintable by anyone again. deploy opens the namespace sets price, rec, idua, term window mint claims a free name, pays rec expiry = block time + dua years TERM RUNNING, OWNER ONLY setrecord writes btc, eth or txt data may claim the primary flag transfer new owner, same expiry records are cleared renew pays again, extends expiry only before it lapses expiry passes with no renew expired owner operations refused with status OE mintable again by anyone previous holder kept as preowner
The lifecycle as the reference indexer implements it in index_core/src101.py. Note the one edge that surprises people: there is no grace period. The renew path is closed at exactly the moment the expiry passes, and from that instant the name is open to anyone.

What SRC-101 shares with SRC-20, and where they diverge

Both protocols ride the same Bitcoin Stamps data carrier, and an indexer reads them out of a transaction with the same code. Above that line they share almost nothing: no ledger, no state, no consensus hash, and a completely different validation temperament.

Verified against btc_stamps 1.9.3
AspectSRC-20SRC-101
Data carrierIdentical. Bare multisig with ARC4, or P2WSH. Framed as a two-byte big-endian length, then stamp:, then the JSON.
Keyburn requirementIdentical. keyburn == 1 is required for the transaction to be classified as either protocol.
Genesis height788041870652
Counterparty carriageIgnored at and above block 796000Never ends. A Counterparty-carried SRC-101 is accepted at any height at or above genesis
Extra JSON fieldsTolerated, superset matchingRejected. Exact key-set matching for four of the five operations
Field-level failureRecorded as invalid with a status codeExcluded outright. A malformed field kills the whole operation before dispatch
State modelAccount ledger, balance per addressOne row per name, one owner, one expiry
Numeric typeDecimal, ceiling 2^64 minus 1int, no ceiling, must be at least 0
Payment requiredNone. Operations are free of protocol feesYes. Mint and renew must pay a computed amount to output 0
Ledger hashContributes to the block ledger hash, cross-checked against stampscanContributes nothing. No cross-check exists
Marketplace in Bitcoin UniverseStampDEX, external executionNone. No product implements a trade path

The SRC-20 documentation is a sibling of this site: bitcoinuniverseio.github.io/src-20. Its carrier section and this site's carrier section describe the same bytes, so if you have already implemented one carrier you have implemented both.

Five things implementers get wrong

  1. Extra fields are fatal, not ignored. A deploy, transfer, setrecord or renew payload is compared to its key set with a symmetric difference. One extra key, one missing key, and the payload is not an SRC-101 operation at all. It leaves no record and no status code. mint is the sole exception, and only at and above block 872200. See rule 20.
  2. prim must be the string, not the boolean. The validator compares the submitted value against "true" and "false" as text. A JSON boolean true fails that comparison, and because a field failure is fatal in SRC-101, the whole operation is discarded. See rule 32.
  3. A mint of several names partially succeeds. When a mint lists several names and some are already held with a live expiry, those names are quietly dropped from the list and the remaining ones are minted. You are not refunded and you are not told. Only if every name is taken does the operation fail, with status DM. See rule 55.
  4. A transfer wipes the records. The owners row written by a transfer sets the resolved Bitcoin address, the resolved Ethereum address and the text record back to empty. Transferring a name and expecting the records to travel with it is a mistake. See rule 61.
  5. lim is not a mint limit. The deploy field named lim is never enforced as a cap on anything. It is used solely as a sentinel: a namespace whose lim is zero is treated as not deployed, so every later operation against it fails with ND. Deploying with lim zero creates a namespace nobody can use. See rule 40.

A sixth, for readers rather than implementers: expiry is absolute. There is no grace period, no redemption window, and no automatic renewal. The block timestamp is compared against the stored expiry, and the moment it passes, the name is gone.

Bitcoin Universe support

Taken from the ecosystem capability registry, which is generated from the Core protocol registry, and nothing beyond it:

Core

view, discover, view-collection, view-activity, view-transaction

Wallet

view, send, receive

Inscribe

mint, transfer

No marketplace, stated plainly

The capability snapshot records no marketplace entry for SRC-101 at all. No Bitcoin Universe product implements list, buy, offer, settle or any other trade path for an SRC-101 name. The snapshot also records no source of truth, no indexer, no freshness policy, no confirmation policy and no reorg policy for this protocol. Anywhere you see an SRC-101 name being traded, that is a third party operating outside anything documented here.

Note also what Inscribe does not offer: there is no deploy action, and no action for renew or setrecord. Opening a namespace, renewing a term and writing records are things you would need to construct yourself. The guide lays out the practical consequence.

Grounding

Every normative statement on this site is traceable to code that enforces it. The primary source is the Bitcoin Stamps indexer, version 1.9.3:

  • indexer/src/index_core/src101.py, 1347 lines, holds the validator, the five operation handlers, the key sets and the owners projection.
  • indexer/src/config.py holds the activation heights and the table names quoted throughout.
  • indexer/src/index_core/models.py holds the classification gate that decides a transaction is SRC-101 at all.
  • indexer/src/index_core/transaction_utils.py holds the carrier decoding shared with SRC-20.
  • indexer/src/index_core/database.py holds the table writes, the reorg purge and the owners rebuild.

Where this site says something the code does not decide, it says so. Where the code does something surprising, the limitations section names it rather than smoothing it over.