Update
did:btcr2 DID documents can be updated by anchoring BTCR2 Updates to Bitcoin transactions. These transactions MAY be published to the Bitcoin network.
Any property in the DID document may be updated except the id. Doing so would invalidate the DID document.
The update operation has the following function signature:
fn update(
sourceDidDocument,
jsonPatch,
targetVersionId,
verificationMethodId,
signer,
) ->
signedUpdate
Input arguments:
sourceDidDocument: The DID document (data structure) that DID resolution returns before the new BTCR2 Signed Update is applied.jsonPatch: A single JSON Patch document RFC6902 with the changes to be made to the source DID document. Its wire shape is defined by thepatchproperty of the BTCR2 Unsigned Update (data structure).targetVersionId: TheversionIdthat will be returned in the DID document metadata (data structure) once the new BTCR2 Signed Update is applied.verificationMethodId: TheverificationMethodID used for signing the BTCR2 Update.signer: A signing interface. The signer receives bytes and returns a Schnorr signature BIP340 for those bytes. The signer makes the signature with the private key forverificationMethodId. The signer selects how it holds or reaches that key. An external signer is RECOMMENDED. An implementation that holds the key in its own process is also conformant.
Outputs:
signedUpdate: A copy of the BTCR2 Signed Update anchored to the Bitcoin blockchain by a BTCR2 Update Announcement.
Process
Updating a did:btcr2 DID document is a matter of constructing a BTCR2 Signed Update then announcing that update via one or more BTCR2 Beacons listed in the DID document. The update announcement process varies depending on the Beacon Type.
Constructing a BTCR2 Signed Update is a two-step process. First, a BTCR2 Unsigned Update is constructed. Then the signer signs the update to construct the BTCR2 Signed Update.
Construct BTCR2 Unsigned Update
This process constructs a BTCR2 Unsigned Update (data structure).
Apply jsonPatch to sourceDidDocument to create targetDidDocument. An INVALID_DID_UPDATE error MUST be raised if jsonPatch is malformed or fails to apply. JSON Patch RFC6902 operations are evaluated in order; the first operation that fails, including a failed test operation, fails the whole patch. targetDidDocument MUST be conformant to DID Core v1.1 DID-CORE. An INVALID_DID_UPDATE error MUST be raised if targetDidDocument.id is not equal to sourceDidDocument.id.
Fill the BTCR2 Unsigned Update (data structure) template below with the required template variables.
array-of-patches:jsonPatchembedded as JSON.source-hash:sourceDidDocumenthashed with the JSON Document Hashing algorithm.target-hash:targetDidDocumenthashed with the JSON Document Hashing algorithm.target-version-id: The value oftargetVersionId.
targetVersionId MUST be derived from the versionId returned in the DID document metadata (data structure) by a fresh resolution of the DID, rather than from a locally maintained count. Announcing a BTCR2 Signed Update whose targetVersionId is wrong in either direction can permanently prevent the DID from resolving.
sourceDidDocument MUST be the DID document (data structure) that the same fresh resolution returns.
A DID controller MUST NOT announce a BTCR2 Signed Update if it cannot resolve all previous BTCR2 Updates of the DID. It cannot resolve them if the fresh resolution returns a versionId less than the highest targetVersionId that the DID controller announced for the DID. If this occurs, resolve the DID again after the Beacon Signal of the last announced update has resolutionOptions.minConf confirmations. A lower minConf decreases the time to wait, but increases the risk from block reorganizations (see Find Beacon Signals).
{
"@context": [
"https://w3id.org/json-ld-patch/v1",
"https://w3id.org/zcap/v1",
"https://w3id.org/security/data-integrity/v2",
"https://btcr2.dev/context/v1"
],
"patch": {{array-of-patches}},
"sourceHash": "{{source-hash}}",
"targetHash": "{{target-hash}}",
"targetVersionId": {{target-version-id}}
}
Let update be the result of parsing the rendered template as JSON. The
resulting BTCR2 Unsigned Update (data structure) MUST be conformant to this specification.
Construct BTCR2 Signed Update
This process constructs a BTCR2 Signed Update (data structure) from update, a BTCR2 Unsigned Update (data structure).
An INVALID_DID_UPDATE error MUST be raised if no entry of the sourceDidDocument.capabilityInvocation Set identifies verificationMethodId. A reference entry identifies it when the two values are equal. An embedded verification method object identifies it when the id of the object is equal.
If that entry is a reference, find the verification method in the sourceDidDocument.verificationMethod Set with an id that is equal to the reference. An INVALID_DID_UPDATE error MUST be raised if there is no verification method with that id.
Create cryptosuite as a BIP340 Cryptosuite BIP340-Cryptosuite instance with signer as the signing interface and the "bip340-jcs-2025" cryptosuite.
Fill the Data Integrity VC-DATA-INTEGRITY template below with the required template variables.
verification-method: The value ofverificationMethodId.capability: A URN of the following format:urn:zcap:root:${encodeURIComponent(sourceDidDocument.id)}. TheencodeURIComponent()function is defined by ECMA-262 ECMA-262.invocation-target: The value ofsourceDidDocument.id.
{
"@context": [
"https://w3id.org/json-ld-patch/v1",
"https://w3id.org/zcap/v1",
"https://w3id.org/security/data-integrity/v2",
"https://btcr2.dev/context/v1"
],
"type": "DataIntegrityProof",
"cryptosuite": "bip340-jcs-2025",
"verificationMethod": "{{ verification-method }}",
"proofPurpose": "capabilityInvocation",
"capability": "{{ capability }}",
"capabilityAction": "Write",
"invocationTarget": "{{ invocation-target }}"
}
Let proofConfig be the result of parsing the rendered template as JSON. The
resulting Data Integrity Config (data structure) MUST be conformant to Verifiable Credentials Data Integrity 1.0 VC-DATA-INTEGRITY.
Pass update and proofConfig to the cryptosuite.createProof method and set update.proof to the resulting Data Integrity Proof (data structure).
Implementations SHOULD verify update.proof before they announce the update. Use the public key of the verification method that verificationMethodId identifies. An announced update with an invalid proof permanently invalidates the DID.
Announce DID Update
BTCR2 Signed Updates are announced to the Bitcoin blockchain depending on the Beacon Type.
Announcing to a Singleton Beacon
A BTCR2 Update Announcement for a Singleton Beacon is the BTCR2 Signed Update hashed with the JSON Document Hashing algorithm. This 32-byte SHA-256 hash is used as the Signal Bytes when constructing a Beacon Signal Bitcoin transaction. The Beacon Signal is signed by the private key that controls the Beacon Address and broadcast to the Bitcoin network. To broadcast signed Bitcoin transactions, see the Bitcoin-Core source code.
Funding a Beacon Signal
This section is non-normative. A full definition of the construction of a Beacon Signal is out of scope for this specification. This section shows a RECOMMENDED example.
The BTCR2 Signed Update supplies only the Signal Bytes. The transaction also has inputs, a fee, and a change output. The inputs are UTXOs that the caller selects. The three values are parameters of the RECOMMENDED example:
fn constructBeaconSignal(
signedUpdate,
prevouts,
feeRate,
changeAddress,
) ->
unsignedBeaconSignal
Input arguments:
signedUpdate: The BTCR2 Signed Update that the Beacon Signal announces.prevouts: The UTXOs that the transaction spends, each with its value. One of them is a UTXO that the Beacon Address controls.feeRate: The fee rate that the caller selects for the transaction.changeAddress: The address that receives the total value ofprevoutsminus the fee.
Outputs:
unsignedBeaconSignal: An Unsigned Beacon Signal
Announcing to an Aggregate Beacon
Aggregating and announcing updates for multiple did:btcr2 identifiers is the responsibility of the Aggregation Service. The main responsibilities include establishing a protocol for one or more rounds of secure group communications amongst Aggregation Participants, advertising available Aggregation Cohorts to Aggregation Participants including the creation, management, timing and scheduling of those Aggregation Cohorts, and broadcasting a Bitcoin transaction to the Bitcoin network that includes signatures from all Aggregation Participants in a given Aggregation Cohort.