An Introduction to did:btcr2, a Second-Generation Bitcoin DID Method

Apr 10, 2026

An Introduction to did:btcr2, a Second-Generation Bitcoin DID Method

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_RETURN output. 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:

  1. 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_RETURN output.
  2. 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.
  3. 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):

  1. It makes sure that sourceHash matches the current DID document.
  2. It verifies the proof with a key from the capabilityInvocation list of the current DID document.
  3. 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.

Jintek LLC