Introduction
The original did:btcr method came from the Rebooting the Web of Trust community. Work on its spec started at a virtual hackathon in July 2017. BTCR showed that Bitcoin can be a Verifiable Data Registry for decentralized identifiers. But BTCR had limitations, and these limitations became clear as the DID ecosystem became mature and Bitcoin itself changed. did:btcr2 is a new design that removes those limitations. It also uses Bitcoin protocol upgrades such as Taproot and Schnorr signatures.
Why BTCR Needed a Second Generation
The original BTCR method bound a DID to a Bitcoin transaction. This design had these consequences:
- Each DID creation needed an on-chain transaction: A BTCR identifier is the TxRef of a confirmed transaction, so each new DID cost a Bitcoin transaction fee. The BTCR spec itself says that some aspects of the method "will not be practical if inappropriately scaled".
- The current state moved with each update: The DID string stayed the same, but each update spent the current output and made a new transaction. To find the current DID document, a resolver had to follow the chain of spent outputs to the tip. Also, a TxRef points to a position in the chain, so a chain reorganization can change the transaction that it refers to. BIP 136 recommends that you do not use a TxRef for a position with less than 100 blocks of maturity.
- DID documents were public: A resolver built the BTCR DID document from public transaction data, or from a "continuation" DID document at an HTTP URL in the
OP_RETURNoutput. Thus, anyone with the DID could get the DID document and correlate the identity. The did:btcr2 spec says that BTCR focused on censorship resistance, and that the early DID ecosystem had a "heavy reliance on public DID documents". - No aggregation: Each DID operation needed its own Bitcoin transaction. BTCR had no mechanism to put updates from many controllers into one transaction.
These limitations are not small. They are structural barriers for practical identity systems.
What did:btcr2 Changes
Zero-Cost Offline Creation
A btcr2 identifier comes from a secp256k1 public key or from the hash of a genesis document (Create). Creation is fully offline, and it needs no Bitcoin transaction. To make a key-based DID, you generate a key pair and encode the public key with Bech32m. Bitcoin uses the same encoding for Taproot addresses. The result is a globally unique DID that is cryptographically bound to your key.
The identifier has a human-readable prefix: k for key-based DIDs and x for external (document-based) DIDs. The encoded data contains the Bitcoin network, the spec version, and the genesis bytes (Identifier Encoding). The genesis bytes are a 33-byte compressed public key or a 32-byte SHA-256 hash.
Long-Term Stable Identifiers
A btcr2 identifier comes from genesis bytes that do not change. The identifier does not point to a transaction or to an output, so a chain reorganization cannot change what it refers to. Updates go through Beacons, and they do not change the identifier. The Beacons are services in the DID document, so the controller can change them with an update. Thus, a DID that you create today keeps the same identifier after any number of updates to the DID document.
Private DID Documents
btcr2 introduces "Sidecar" delivery. With sidecar delivery, the controller gives the DID document data and its update history directly to the relying party. The controller does not have to publish this data to external storage. This is different from federated identity models, where a central provider is between the parties in each interaction.
For key-based DIDs, the resolver generates the initial DID document from the DID itself, so the controller only shares the DID string. For document-based DIDs, the controller gives the genesis document. In both cases, if updates exist, the controller gives them as a list of plain JSON objects (Update Data Distribution).
Each Beacon Signal puts only a 32-byte hash on-chain (the Signal Bytes). Resolution can occur in a "closed loop", where only the parties with the sidecar data can resolve the DID. The reference implementation README names this closed loop and "non-correlation through pairwise DIDs" as goals. A controller can also publish updates to Content Addressable Storage (CAS). But the spec tells controllers to consider data on CAS as public.
Beacon-Based Aggregation
btcr2 does not need one transaction for each DID operation. It uses three Beacon types:
- Singleton Beacon: One update in each transaction, directly from the controller. This is the simplest path. The transaction puts a hash of the update in an
OP_RETURNoutput. - CAS Beacon (Content Addressable Storage): One on-chain commitment for many updates. The Beacon Announcement Map goes into CAS, and the transaction contains the hash of the map.
- SMT Beacon (Sparse Merkle Tree): Aggregation with the most privacy of the three types. The Aggregation Service must know all DIDs in the cohort, because each DID gives the position of a leaf (Privacy Considerations). A per-leaf nonce makes update leaves and non-update leaves look the same. Thus, the Aggregation Service cannot tell if a participant updated, or what the update contains, unless the controller tells it. On-chain observers see only one root hash.
With aggregation, one Bitcoin transaction fee pays for the updates of all DIDs in a cohort. The Aggregation Service sets the minimum and maximum number of participants for each cohort (Create Aggregation Cohort).
Bitcoin-Native Cryptography
btcr2 uses BIP 340 Schnorr signatures. Bitcoin activated the same signature scheme with the Taproot upgrade. The project developed a Data Integrity cryptosuite, bip340-jcs-2025, that follows the W3C Data Integrity model. The cryptosuite signs and verifies DID updates with Bitcoin-native cryptography. Each update is a JSON Patch (RFC 6902) with a hash of the source document and a hash of the target document. For multi-party Beacons, the spec gives a RECOMMENDED example that uses MuSig2 (BIP 327) for n-of-n Schnorr multi-signatures (Aggregate Beacons).
Immutable History and Security
Each btcr2 DID has a single canonical history that Bitcoin anchors. The resolver sorts the updates by targetVersionId, with the block height as a tiebreaker (Process Next Update). For each update, the resolver does these steps (Apply update):
- It makes sure that
sourceHashmatches the current DID document. - It verifies the proof with a key from the
capabilityInvocationlist of the current DID document. - It applies the JSON Patch and makes sure that the result matches
targetHash.
Late publishing occurs when someone reveals a DID update at a later time and changes the history of the DID document. If the version numbers have a gap, or if a duplicate version has different content, the resolver raises a LATE_PUBLISHING error (Check update.targetVersionId). Bitcoin anchors the order and the commitments, so nobody can rewrite the announcement history without detection. The document updates travel off-chain by sidecar. Thus, resolution still depends on the controller (or CAS) to make that data available.
Current Status
As of September 2026, the btcr2 specification says that it is "still under active development and may be subject to breaking changes". The spec authors come from Digital Contract Design, Legendary Requirements, Jintek LLC, and BlipJoy LLC. A TypeScript reference implementation is available as an open-source monorepo with ten packages. The packages cover the core method, the cryptosuite, key management, Bitcoin connectivity, Sparse Merkle Trees, aggregation, and a CLI.
The implementation page says that the SDK can create, resolve, update, and deactivate DIDs. The @did-btcr2/aggregation package adds multi-party CAS and SMT Beacons with MuSig2 over Nostr or HTTP. The packages are still at version 0.x, so a minor release can contain changes that are not backward compatible.
Conclusion
did:btcr2 removes the practical limitations of the original BTCR: expensive creation, a current state that moved with each update, public documents, and no aggregation. The result is a Bitcoin-anchored DID method with a lower creation cost and more privacy options. The correct anchor for an identity system depends on the use case, and Bitcoin is not the correct anchor for all systems. If you want the properties of Bitcoin, btcr2 makes them available without the costs of the original method. The design follows the protocol changes of Bitcoin, and the implementation is open source.
Related Resources
- did:btcr2 Specification: The full method specification
- did:btcr2 TypeScript Implementation: The open-source reference monorepo
- Original did:btcr Method Spec: The W3C CCG report for the first-generation Bitcoin DID method
- Decentralized Identity on Bitcoin: Why the base layer is important for trust
- The W3C DID Standard and Bitcoin: An overview of the DID specifications and of the Bitcoin DID methods
- Self-Sovereign vs. Federated Identity: SSI compared with OAuth and SAML, and why the change is important
- Zero-Cost DID Creation: A detailed look at the offline creation model of btcr2
- Data Integrity BIP340 Cryptosuites: The
bip340-jcs-2025cryptosuite spec - BIP 340: Schnorr Signatures for secp256k1
- BIP 327: MuSig2: n-of-n Schnorr multi-signatures
- BIP 350: Bech32m: The address encoding for Taproot, which btcr2 identifiers also use
- RFC 6902: JSON Patch
- W3C DID Core 1.0: The W3C Recommendation. The did:btcr2 spec targets DID Core 1.1, which is a Candidate Recommendation as of September 2026.
