{"generated":"2026-09-01","site":"https://bitcoinuniverseio.github.io/src-101/","entries":[{"page":"Overview","title":"A name registry written into Bitcoin transaction outputs","url":"./","text":"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.","aliases":["src101","src 101","what is src-101","bitname","names","namespace","home","start","intro"]},{"page":"Overview","title":"What it actually is, in plain language","url":"./#plain","text":"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","aliases":["explain","beginner","what is it","how does it work","lease","register"]},{"page":"Overview","title":"The lifecycle of one name","url":"./#lifecycle","text":"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.","aliases":["deploy","mint","transfer","setrecord","renew","expire","expiry","flow","diagram"]},{"page":"Overview","title":"What SRC-101 shares with SRC-20, and where they diverge","url":"./#family","text":"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.","aliases":["src-20","src20","comparison","difference","stamps","carrier","family"]},{"page":"Overview","title":"Five things implementers get wrong","url":"./#wrong","text":"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.","aliases":["mistakes","gotchas","pitfalls","traps","common errors"]},{"page":"Overview","title":"Bitcoin Universe support","url":"./#support","text":"Taken from the ecosystem capability registry, which is generated from the Core protocol registry, and nothing beyond it:","aliases":["core","wallet","inscribe","marketplace","trade","buy","sell","support matrix","capability"]},{"page":"Overview","title":"Grounding","url":"./#grounding","text":"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:","aliases":["source","btc_stamps","indexer","evidence","provenance"]},{"page":"Specification","title":"SRC-101 specification","url":"./specification.html","text":"Every rule below states what the reference indexer does, and names the file that does it. Where the code contains a branch that cannot be reached, or a field that is declared and never used, this document says so rather than describing the intention.","aliases":["src101","src 101","what is src-101","bitname","names","namespace","home","start","intro"]},{"page":"Specification","title":"1. Scope and terminology","url":"./specification.html#scope","text":"SRC-101 is defined on Bitcoin mainnet only . No other chain and no test network is in scope. Nothing in this document describes behaviour on signet, testnet or any fork.","aliases":["definitions","glossary","mainnet","creator","destination","terms","dua","idua","coef","preowner"]},{"page":"Specification","title":"2. The data carrier","url":"./specification.html#carrier","text":"This section is identical in substance to the SRC-20 carrier. If you have implemented one, you have implemented the other. It is repeated here so that this document stands alone.","aliases":["multisig","p2wsh","olga","arc4","stamp prefix","keyburn","framing","op_return"]},{"page":"Specification","title":"3. Classification and activation heights","url":"./specification.html#heights","text":"A payload is classified as SRC-101 when its lower-cased p value, upper-cased, equals SRC-101 . The three sub-protocols the carrier recognises are SRC-721 , SRC-20 and SRC-101 . Any other value makes the payload not a sub-protocol at all.","aliases":["870652","872200","940000","865000","genesis","block height","fork","end block"]},{"page":"Specification","title":"4. The payload and its key sets","url":"./specification.html#keysets","text":"Each operation has a fixed key set. For deploy , transfer , setrecord and renew , the payload's key set and the operation's key set are compared with a symmetric difference , and that difference must be empty. Every listed key must be present and no other key may be present. A payload that fails this test is not an","aliases":["exact match","symmetric difference","superset","extra fields","missing key","excluded"]},{"page":"Specification","title":"5. Field rules","url":"./specification.html#fields","text":"Field validation runs before any operation handler. It is fail-closed : see rule 35.","aliases":["prim","tokenid","base64","numeric","validation","fail closed","regex","address"]},{"page":"Specification","title":"6. deploy","url":"./specification.html#deploy","text":"Opens a namespace. It creates no name and claims nothing.","aliases":["deploy","namespace","lim","pri","idua","rec","wla","mintstart","mintend"]},{"page":"Specification","title":"7. mint","url":"./specification.html#mint","text":"Claims one or more free names in a namespace for a paid term. The checks below run in the order given; the first failure ends the operation.","aliases":["mint","claim","price","coef","discount","sig","whitelist","payment","dua"]},{"page":"Specification","title":"8. transfer","url":"./specification.html#transfer","text":"The name must already have an entry with an owner and an expiry, else NM . The creator must equal the current owner , else NO . The block timestamp must be strictly less than the expiry, else OE .","aliases":["transfer","send","sell","new owner","records cleared"]},{"page":"Specification","title":"9. renew","url":"./specification.html#renew","text":"The name must have an entry, the creator must be the current owner, and the block timestamp must be strictly less than the current expiry . Renewing an expired name is refused with OE . This is the rule with the largest practical consequence in the protocol.","aliases":["renew","renewal","extend","expiry","grace period","lapse"]},{"page":"Specification","title":"10. setrecord","url":"./specification.html#setrecord","text":"The name must have an entry, the creator must be the current owner where a creator is present, and the block timestamp must be strictly less than the expiry. The three failures are NM , NO and OE .","aliases":["setrecord","record","resolve","eth","ethereum","btc record","txt","primary","reverse"]},{"page":"Specification","title":"11. Validity and state","url":"./specification.html#validity","text":"There are three outcomes, and they are not the same thing:","aliases":["valid","invalid","excluded","status","ledger hash","tables","mempool"]},{"page":"Specification","title":"12. The Counterparty relationship","url":"./specification.html#counterparty","text":"An SRC-101 transaction that also carries a Counterparty asset identifier is accepted, at any height at or above genesis. The classification is a plain disjunction: SRC-101 with an asset identifier, or SRC-101 without one. Both branches are open forever.","aliases":["counterparty","cpid","asset","796000","xcp"]},{"page":"Specification","title":"Sources for this document","url":"./specification.html#sources","text":"indexer/src/index_core/src101.py for rules 20 to 73 and the status codes.","aliases":["source","btc_stamps","indexer","evidence","provenance"]},{"page":"Guide","title":"Working with SRC-101","url":"./guide.html","text":"This page walks through the five operations with complete payloads, shows exactly how many bytes each one occupies on chain, works out what a term costs, and explains how to tell whether your registration actually happened. Every example is constructed for illustration. The addresses and the public key are well formed and pass every checksum, because a broken example teaches the wrong lesson, but they are derived from fixed text rather than from any key anyone holds. No transaction hash here names a transaction that exists.","aliases":[]},{"page":"Guide","title":"1. Before you spend anything","url":"./guide.html#before","text":"Four things decide whether an SRC-101 transaction does what you meant, and all four are settled before you sign.","aliases":["checklist","prepare","namespace","payment","safety"]},{"page":"Guide","title":"2. Opening a namespace","url":"./guide.html#deploy","text":"A deploy is the largest payload in the protocol and the only one with no hash . All sixteen keys are mandatory.","aliases":["deploy","namespace","lim","pri","idua","rec","wla","mintstart","mintend"]},{"page":"Guide","title":"3. Claiming a name","url":"./guide.html#mint","text":"A mint at block 872200 or above. The tokenid value c2F0b3NoaQ== is Base64 for satoshi .","aliases":["mint","claim","price","coef","discount","sig","whitelist","payment","dua"]},{"page":"Guide","title":"4. What a term costs","url":"./guide.html#pricing","text":"The arithmetic is short and entirely deterministic. Using the deploy above, whose pri is {\"0\": 200000, \"3\": 2000000, \"4\": 800000} and whose idua is 1:","aliases":["price","cost","satoshis","rounds","idua","granularity","discount"]},{"page":"Guide","title":"5. Pointing a name somewhere","url":"./guide.html#records","text":"A name with no records is just a reservation. setrecord is what makes it resolve.","aliases":["setrecord","record","resolve","eth","ethereum","btc record","txt","primary","reverse"]},{"page":"Guide","title":"6. Handing a name on","url":"./guide.html#transfer","text":"{ \"p\": \"src-101\", \"op\": \"TRANSFER\", \"hash\": \"3a7f1c8e0b45d29a6f13e874c05b9d2e6a8f04713bc9e25d8a06f1c34b7e9c19\", \"toaddress\": \"bc1qs2x9wz22tasf8pfejlcc3e8yhnzhv9qs2kgwls\", \"tokenid\": \"c2F0b3NoaQ==\" } Five keys, no payment, no term change. The address funding input 0 must be the current owner, and the term must still be","aliases":["transfer","send","sell","new owner","records cleared"]},{"page":"Guide","title":"7. Keeping a name","url":"./guide.html#renew","text":"{ \"p\": \"src-101\", \"op\": \"RENEW\", \"hash\": \"3a7f1c8e0b45d29a6f13e874c05b9d2e6a8f04713bc9e25d8a06f1c34b7e9c19\", \"tokenid\": \"c2F0b3NoaQ==\", \"dua\": \"1\" } Five keys, and a payment at output 0 to a namespace recipient. The new expiry is the existing expiry plus the term, so renewing early costs you nothing in time. That is","aliases":["renew","renewal","extend","expiry","grace period","lapse"]},{"page":"Guide","title":"8. Byte framing and outputs","url":"./guide.html#framing","text":"The framed buffer is a two-byte big-endian length, then stamp: , then the JSON. The declared length covers the prefix and the JSON and excludes itself. The counts below are computed from the exact payloads on this page.","aliases":["bytes","framing","length prefix","outputs","multisig","p2wsh","size","length","stamp prefix"]},{"page":"Guide","title":"9. Reading a result","url":"./guide.html#reading","text":"After your transaction confirms, there are three things it might have become, and only one of them is what you wanted.","aliases":["status","did it work","failed","excluded","explorer"]},{"page":"Guide","title":"10. What Bitcoin Universe supports","url":"./guide.html#support","text":"Taken from the ecosystem capability registry, which is generated from the Core protocol registry and records what the product code implements.","aliases":["core","wallet","inscribe","marketplace","trade","buy","sell","support matrix","capability"]},{"page":"Guide","title":"11. Safety","url":"./guide.html#safety","text":"Names are decoded from Base64 and lower-cased, and the character rules reject spaces and format characters but not homoglyphs. Two names can render the same and be different registrations. Compare the decoded bytes, not the rendering.","aliases":["security","safety","homoglyph","phishing","scam","risk","warning"]},{"page":"Reference","title":"SRC-101 reference","url":"./reference.html","text":"What an implementer needs after the specification: the vocabulary, every status code, the five tables that hold state, how ordering, confirmation and reorgs actually behave, what the protocol cannot do, and a checklist to work through before you claim your indexer is correct.","aliases":["src101","src 101","what is src-101","bitname","names","namespace","home","start","intro"]},{"page":"Reference","title":"1. Terminology","url":"./reference.html#terms","text":"1. Terminology","aliases":["glossary","definitions","terms","dua","idua","coef","preowner"]},{"page":"Reference","title":"2. Status codes","url":"./reference.html#statuses","text":"Two families exist and they behave differently. Field-level codes are assigned by the validator before any handler runs, and they cause the operation to be abandoned. Operation-level codes are assigned by a handler, and they produce a recorded invalid operation.","aliases":["ND","UO","IRV","OE","DM","ITT","IRS","IDP","error","code","why did it fail"]},{"page":"Reference","title":"3. Storage tables","url":"./reference.html#tables","text":"The owners row is keyed by the protocol string, the deploy hash and the normalised token id joined together, and it is written as an upsert. An entry is never deleted by an operation: a name that expires keeps its row with its old owner and old expiry, and a later mint overwrites that row.","aliases":["SRC101","SRC101Valid","src101price","owners","recipients","database","schema"]},{"page":"Reference","title":"4. Indexer semantics","url":"./reference.html#semantics","text":"Operations within a block are processed in transaction order, and a name minted earlier in a block is visible to a later transaction in the same block through an in-block lookup that runs before the database is consulted. Across blocks, ordering is block index then transaction index.","aliases":["ordering","confirmation","mempool","ledger hash","consensus","unconfirmed"]},{"page":"Reference","title":"5. Reorg and the owners rebuild","url":"./reference.html#reorg","text":"Rollback is uniform across the indexer. A detected chain reorganisation triggers a rollback ten blocks deeper than the divergence, as a safety margin.","aliases":["reorg","reorganisation","rollback","rebuild","replay","recovery"]},{"page":"Reference","title":"6. The Counterparty relationship","url":"./reference.html#counterparty","text":"SRC-101 inherits the Bitcoin Stamps classification path, which resolves a Counterparty asset identifier for a transaction where one exists. The gate is a plain disjunction: an SRC-101 payload with an asset identifier, or an SRC-101 payload without one. Both are accepted.","aliases":["counterparty","cpid","asset","796000","xcp"]},{"page":"Reference","title":"7. The Stamps protocol family","url":"./reference.html#family","text":"All three share the same carrier, the same stamp: prefix and the same keyburn requirement, and all three are recognised from the same protocol field. None of them shares state with any other. A transaction is classified as exactly one.","aliases":[]},{"page":"Reference","title":"8. Size and fee considerations","url":"./reference.html#size","text":"The protocol imposes two costs. The first is the Bitcoin fee for carrying the payload, which scales with payload size and carrier choice. The second is the namespace payment, which mint and renew require and which is fixed by the deploy's price list.","aliases":["fee","cost","bytes","size","outputs","vbyte"]},{"page":"Reference","title":"9. Limitations","url":"./reference.html#limitations","text":"Stated plainly, because most of these have no workaround.","aliases":["cannot","no marketplace","no escrow","no grace","restrictions","caveats"]},{"page":"Reference","title":"10. Security considerations","url":"./reference.html#security","text":"Do not add a multisig fallback when P2WSH data fails. The exclusion is consensus-load-bearing and the source marks it as such. Adding a fallback forks the register.","aliases":["security","safety","homoglyph","phishing","scam","risk","warning"]},{"page":"Reference","title":"11. Implementation checklist","url":"./reference.html#checklist","text":"Work through this before claiming an SRC-101 indexer is correct. Each item has a corresponding vector on the test vectors page.","aliases":["checklist","implement","indexer","conformance","todo"]},{"page":"Test vectors","title":"SRC-101 test vectors","url":"./vectors.html","text":"Every vector states the outcome the reference indexer produces and the rule that decides it. All are constructed for testing. None is drawn from a transaction on chain, and this site makes no claim about what any particular real transaction did.","aliases":["src101","src 101","what is src-101","bitname","names","namespace","home","start","intro"]},{"page":"Test vectors","title":"1. Shared fixtures","url":"./vectors.html#fixtures","text":"Every vector below uses these. Addresses and the public key are checksum-valid and lie on the curve, because a broken fixture teaches the wrong lesson, but each is derived from fixed text rather than from a key anyone holds.","aliases":["fixtures","example","test data","addresses"]},{"page":"Test vectors","title":"2. Carrier framing","url":"./vectors.html#framing","text":"The framed buffer is a two-byte big-endian length, then stamp: , then the JSON. The declared length covers the prefix and the JSON and excludes itself. Counts are computed from the exact payloads used on the guide .","aliases":["bytes","length","stamp prefix","outputs"]},{"page":"Test vectors","title":"3. Key-set vectors","url":"./vectors.html#keysets","text":"Every vector here is either accepted for dispatch or excluded. None produces a status code.","aliases":[]},{"page":"Test vectors","title":"4. Field-rule vectors","url":"./vectors.html#fields","text":"Every failure here is an Excluded , because field validation is fail-closed. There is no status code and no record.","aliases":[]},{"page":"Test vectors","title":"5. Name encoding vectors","url":"./vectors.html#names","text":"tokenid acceptance","aliases":["base64","tokenid","decode","special characters","homoglyph","duplicate"]},{"page":"Test vectors","title":"6. deploy vectors","url":"./vectors.html#deploy","text":"Against the fixture namespace: prices 200000 for the fallback, 2000000 for length 3, 800000 for length 4, granularity 1.","aliases":["deploy","namespace","lim","pri","idua","rec","wla","mintstart","mintend"]},{"page":"Test vectors","title":"7. mint vectors","url":"./vectors.html#mint","text":"Against the fixture namespace: prices 200000 for the fallback, 2000000 for length 3, 800000 for length 4, granularity 1.","aliases":["mint","claim","price","coef","discount","sig","whitelist","payment","dua"]},{"page":"Test vectors","title":"8. transfer , renew and setrecord vectors","url":"./vectors.html#owner","text":"Owner-only operations","aliases":["transfer","send","sell","new owner","records cleared"]},{"page":"Test vectors","title":"9. A stateful name lifecycle","url":"./vectors.html#lifecycle","text":"One name, satoshi , in the fixture namespace, from first claim to lapse and re-claim. Each step assumes the previous ones applied. Timestamps are the block timestamps of the containing blocks.","aliases":["deploy","mint","transfer","setrecord","renew","expire","expiry","flow","diagram","example","walkthrough","scenario","lifecycle","reclaim"]},{"page":"Test vectors","title":"10. Height-dependent behaviour","url":"./vectors.html#heights","text":"The same input at different heights","aliases":["872200","940000","870652","height","fork","activation"]},{"page":"Validator","title":"SRC-101 payload validator","url":"./validator.html","text":"Paste an SRC-101 JSON operation and choose a block height. The tool works out which operation it is, applies the exact key set for that operation at that height, checks every field rule, and explains each result. It distinguishes a payload that is excluded , leaving no trace at all, from one that is recorded as invalid with a status code.","aliases":["src101","src 101","what is src-101","bitname","names","namespace","home","start","intro"]},{"page":"Validator","title":"What this tool cannot know","url":"./validator.html#tool-panel","text":"A payload can be perfectly well formed and still fail on chain. These checks need the register or the transaction:","aliases":[]},{"page":"Validator","title":"Reading the verdict","url":"./validator.html#reading","text":"Three heights change what this tool does. Move the height field and watch the same payload change verdict.","aliases":["valid","invalid","excluded","verdict","result"]},{"page":"Validator","title":"Why the block height matters","url":"./validator.html#height","text":"Three heights change what this tool does. Move the height field and watch the same payload change verdict.","aliases":["height","872200","940000","activation"]},{"page":"Validator","title":"If you are coming from SRC-20","url":"./validator.html#src20","text":"The field names are different and so is the temperament. The differences that cost people the most:","aliases":["src-20","src20","difference","migration","comparison"]},{"page":"Validator","title":"What this tool does not do","url":"./validator.html#scope","text":"It does not decode a transaction. Paste the JSON payload, not the raw hex.","aliases":[]},{"page":"Changelog","title":"Changelog","url":"./changelog.html","text":"Two histories, kept apart. The protocol changed at specific block heights, and this document changed on specific dates. Conflating them is how stale documentation gets believed.","aliases":[]},{"page":"Changelog","title":"Protocol history, by block height","url":"./changelog.html#protocol","text":"Every height below is a constant in the reference indexer's configuration. Nothing here is a plan or a proposal.","aliases":["heights","changes","fork","870652","872200","940000"]},{"page":"Changelog","title":"Document history","url":"./changelog.html#document","text":"2026.09.01","aliases":["version","changelog","edition","corrections"]},{"page":"Changelog","title":"How this document changes","url":"./changelog.html#policy","text":"Rule numbers are assigned once and never reused. A withdrawn rule keeps its number and is marked withdrawn here.","aliases":[]}]}