did:tdw DID Log Example
The following covers the evolution of a did:tdw
from inception through several
versions, showing the DID, DIDDoc, DID Log, and some of the
intermediate data structures.
The examples are aligned with version 0.4 of the did:tdw
specification.
In some of the following examples the data for the DID log entries is
displayed as prettified JSON for readability. In the log itself, the JSON has
all whitespace removed, and each line ends with a CR
, per the JSON
Lines convention.
DID Creation Data¶
These examples show the important structures used in the Create (Register) operation for a did:tdw
DID.
Input to the SCID Generation Process with Placeholders¶
The following JSON is an example of the input that the DID Controller constructs and passes into the SCID Generation Process. In this example, the DIDDoc is particularly boring, containing the absolute minimum for a valid DIDDoc.
This example includes both the initial "authorized keys" to sign the Data Integrity proof
(updateKeys
) and the pre-rotation commitment to the next authorization keys (nextKeyHashes
). Both
are in the parameters
property in the log entry.
{
"versionId": "{SCID}",
"versionTime": "2024-09-26T23:22:26Z",
"parameters": {
"prerotation": true,
"updateKeys": [
"z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R"
],
"nextKeyHashes": [
"QmXC3vvStVVzCBHRHGUsksGxn6BNmkdETXJGDBXwNSTL33"
],
"method": "did:tdw:0.4",
"scid": "{SCID}"
},
"state": {
"@context": [
"https://www.w3.org/ns/did/v1"
],
"id": "did:tdw:{SCID}:domain.example"
}
}
Output of the SCID Generation Process¶
After the SCID is generated, the literal {SCID}
placeholders are
replaced by the generated SCID value (see below). This JSON is the
input to the entryHash
generation
process -- with the SCID
versionId``. Once the process has run, the version number of this first version
of the DID (
1), a dash
-and the resulting output hash replace the [[ref:
SCID as the
versionId` value.
{
"versionId": "QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ",
"versionTime": "2024-09-26T23:22:26Z",
"parameters": {
"prerotation": true,
"updateKeys": [
"z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R"
],
"nextKeyHashes": [
"QmXC3vvStVVzCBHRHGUsksGxn6BNmkdETXJGDBXwNSTL33"
],
"method": "did:tdw:0.4",
"scid": "QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ"
},
"state": {
"@context": [
"https://www.w3.org/ns/did/v1"
],
"id": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example"
}
}
Data Integrity Proof Generation and First Log Entry¶
The last step in the creation of the first log entry is the generation
of the data integrity proof. One of the keys in the updateKeys
[[ref:
parameter MUST be the verificationMethod
in the proof (in did:key
form) to generate the signature across the post-entryHash processed
DID log entry. The generated proof is added to the JSON Line
and the log entry JSON object becomes the first entry in the [[ref:
DID Log.
The following is the JSON prettified version of the entry log file that is
published as the initial did.jsonl
file. When published, all extraneous
whitespace is removed, as shown in the block below the pretty-printed version.
{
"versionId": "1-QmQq6Kg4ZZ1p49znzxnWmes4LkkWgMWLrnrfPre8UD56bz",
"versionTime": "2024-09-26T23:22:26Z",
"parameters": {
"prerotation": true,
"updateKeys": [
"z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R"
],
"nextKeyHashes": [
"QmXC3vvStVVzCBHRHGUsksGxn6BNmkdETXJGDBXwNSTL33"
],
"method": "did:tdw:0.4",
"scid": "QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ"
},
"state": {
"@context": [
"https://www.w3.org/ns/did/v1"
],
"id": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example"
},
"proof": [
{
"type": "DataIntegrityProof",
"cryptosuite": "eddsa-jcs-2022",
"verificationMethod": "did:key:z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R#z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R",
"created": "2024-09-26T23:22:26Z",
"proofPurpose": "authentication",
"proofValue": "z2fPF6fMewtV15kji2N432R7RjmmFs8p7MiSHSTM9FoVmJPtc3JUuZ472pZKoWgZDuT75EDwkGmZbK8ZKVF55pXvx"
}
]
}
The same content "un-prettified", as it is found in the did.jsonl
file:
{"versionId": "1-QmQq6Kg4ZZ1p49znzxnWmes4LkkWgMWLrnrfPre8UD56bz", "versionTime": "2024-09-26T23:22:26Z", "parameters": {"prerotation": true, "updateKeys": ["z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R"], "nextKeyHashes": ["QmXC3vvStVVzCBHRHGUsksGxn6BNmkdETXJGDBXwNSTL33"], "method": "did:tdw:0.4", "scid": "QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ"}, "state": {"@context": ["https://www.w3.org/ns/did/v1"], "id": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example"}, "proof": [{"type": "DataIntegrityProof", "cryptosuite": "eddsa-jcs-2022", "verificationMethod": "did:key:z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R#z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R", "created": "2024-09-26T23:22:26Z", "proofPurpose": "authentication", "proofValue": "z2fPF6fMewtV15kji2N432R7RjmmFs8p7MiSHSTM9FoVmJPtc3JUuZ472pZKoWgZDuT75EDwkGmZbK8ZKVF55pXvx"}]}
did:web
Version of DIDDoc¶
As noted in the publishing a parallel did:web
DID section of this specification a did:tdw
can be published
by replacing did:tdw
with did:web
in the DIDDoc, adding an alsoKnownAs
entry for the did:tdw
and publishing the resulting DIDDoc at did.json
, logically beside the did.jsonl
file.
Here is what the did:web
DIDDoc looks like for the did:tdw
above.
{
"@context": [
"https://www.w3.org/ns/did/v1"
],
"id": "did:web:domain.example",
"alsoKnownAs": ["did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example"]
}
Version 2 of the DIDDoc¶
Time passes, and the DID Controller of the did:tdw
DID decides to
update its DID to a new version, version 2. In this case, the only change
the DID Controller makes is transition the authorization key to
the pre-rotation key.
Version 2 Entry Hashing Input¶
To generate a new version of the DID, the DID Controller needs to
provide the updated parameters
, and the new DIDDoc. The following
processing is done to create the new DID log entry:
- The
versionId
from the previous (first) log entry is made the value of theversionId
in the new log entry. - The
versionTime
in the new log entry is set to the current time. - The
parameters
entry passed in is processed. In this case, since theupdateKeys
array is updated, and pre-rotation is active, the a verification is done to ensure that the hash of theupdateKeys
entries are found in thenextKeyHashes
property from version 1 of the DID. As required by thedid:tdw
specification, a newnextKeyHashes
is included in the newparameters
. - The new (but unchanged) DIDDoc is included in its entirety, as the value of the
state
property. - The resultant JSON object is passed into the
entryHash
generation process which outputs theentryHash
for this log entry. Once again, theversionId
value is replaced by the version number (the previous version number plus1
, so2
in this case), a dash (-
), and the newentryHash
. - The data integrity proof is generated added to the log
entry, spaces are removed, a
CR
character added (per JSON Lines) and the entire entry is appended to the existing DID log file.
The DID log file can now be published, optionally with an updated version of the corresponding did:web
DID.
The following is the JSON pretty-print log entry for the second version of an example did:tdw
. Things to note in this example:
- The data integrity proof
verificationMethod
is thedid:key
from the first log entry, since theupdateKeys
change in the second log entry does not take affect until after the version update is complete. - A new
updateKeys
property in theparameters
has been added, along with commitment to a future key (nextKeyHashes
) that will control future updates to the DID.
{
"versionId": "2-QmXL6CLK1BMHAd3zQMqkY49VSc9T3zhUcPxu6zEW176PfN",
"versionTime": "2024-09-26T23:22:26Z",
"parameters": {
"updateKeys": [
"z6MkvQnUuQn3s52dw4FF3T87sfaTvXRW7owE1QMvFwpag2Bf"
],
"nextKeyHashes": [
"QmdA9fxQSLLwCQo6TkovcoaLgGYWq6Ttqx6A5D1RY13iFG"
]
},
"state": {
"@context": [
"https://www.w3.org/ns/did/v1"
],
"id": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example"
},
"proof": [
{
"type": "DataIntegrityProof",
"cryptosuite": "eddsa-jcs-2022",
"verificationMethod": "did:key:z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R#z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R",
"created": "2024-09-26T23:22:26Z",
"proofPurpose": "authentication",
"proofValue": "z2nkLj9rYAMG7TStpvihuo4HTovpC7uvWcDoYiGhoN8cqQuiwW2EnPZdWtid2FZAQDQPoaNkTooKVftGKDTh9p3Fy"
}
]
}
Log File For Version 2¶
The new version 2 did.jsonl
file contains two entries, one for each version
of the DIDDoc -- as per the use of JSON Lines.
{"versionId": "1-QmQq6Kg4ZZ1p49znzxnWmes4LkkWgMWLrnrfPre8UD56bz", "versionTime": "2024-09-26T23:22:26Z", "parameters": {"prerotation": true, "updateKeys": ["z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R"], "nextKeyHashes": ["QmXC3vvStVVzCBHRHGUsksGxn6BNmkdETXJGDBXwNSTL33"], "method": "did:tdw:0.4", "scid": "QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ"}, "state": {"@context": ["https://www.w3.org/ns/did/v1"], "id": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example"}, "proof": [{"type": "DataIntegrityProof", "cryptosuite": "eddsa-jcs-2022", "verificationMethod": "did:key:z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R#z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R", "created": "2024-09-26T23:22:26Z", "proofPurpose": "authentication", "proofValue": "z2fPF6fMewtV15kji2N432R7RjmmFs8p7MiSHSTM9FoVmJPtc3JUuZ472pZKoWgZDuT75EDwkGmZbK8ZKVF55pXvx"}]}
{"versionId": "2-QmXL6CLK1BMHAd3zQMqkY49VSc9T3zhUcPxu6zEW176PfN", "versionTime": "2024-09-26T23:22:26Z", "parameters": {"updateKeys": ["z6MkvQnUuQn3s52dw4FF3T87sfaTvXRW7owE1QMvFwpag2Bf"], "nextKeyHashes": ["QmdA9fxQSLLwCQo6TkovcoaLgGYWq6Ttqx6A5D1RY13iFG"]}, "state": {"@context": ["https://www.w3.org/ns/did/v1"], "id": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example"}, "proof": [{"type": "DataIntegrityProof", "cryptosuite": "eddsa-jcs-2022", "verificationMethod": "did:key:z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R#z6MkhbNRN2Q9BaY9TvTc2K3izkhfVwgHiXL7VWZnTqxEvc3R", "created": "2024-09-26T23:22:26Z", "proofPurpose": "authentication", "proofValue": "z2nkLj9rYAMG7TStpvihuo4HTovpC7uvWcDoYiGhoN8cqQuiwW2EnPZdWtid2FZAQDQPoaNkTooKVftGKDTh9p3Fy"}]}
Log File For Version 3¶
The same process is repeated for version 3 of the DID. In this case:
- The DIDDoc is changed.
- an
authentication
method is added. - two services are added.
- No changes are made to the authorized keys to update the DID. As a result, the
parameters
entry is empty ({}
), and the parameters in effect from previous versions of the DID remain in effect.
Here is the pretty-printed log entry:
{
"versionId": "3-QmaSKJRACGefmi19LkS6TFj5FeMEfr98GpBWk7vEmbhT92",
"versionTime": "2024-09-26T23:22:26Z",
"parameters": {},
"state": {
"@context": [
"https://www.w3.org/ns/did/v1",
"https://w3id.org/security/multikey/v1",
"https://identity.foundation/.well-known/did-configuration/v1",
"https://identity.foundation/linked-vp/contexts/v1"
],
"id": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example",
"authentication": [
"did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example#z6MkrgET7ZLV32qNrr6vUd2kVXGw63vbPvqxDqqhRQpvngBX"
],
"assertionMethod": [
"did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example#z6MkrgET7ZLV32qNrr6vUd2kVXGw63vbPvqxDqqhRQpvngBX"
],
"verificationMethod": [
{
"id": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example#z6MkrgET7ZLV32qNrr6vUd2kVXGw63vbPvqxDqqhRQpvngBX",
"controller": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example",
"type": "Multikey",
"publicKeyMultibase": "z6MkrgET7ZLV32qNrr6vUd2kVXGw63vbPvqxDqqhRQpvngBX"
}
],
"service": [
{
"id": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example#domain",
"type": "LinkedDomains",
"serviceEndpoint": "https://domain.example"
},
{
"id": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example#whois",
"type": "LinkedVerifiablePresentation",
"serviceEndpoint": "https://domain.example/.well-known/whois.vc"
}
]
},
"proof": [
{
"type": "DataIntegrityProof",
"cryptosuite": "eddsa-jcs-2022",
"verificationMethod": "did:key:z6MkvQnUuQn3s52dw4FF3T87sfaTvXRW7owE1QMvFwpag2Bf#z6MkvQnUuQn3s52dw4FF3T87sfaTvXRW7owE1QMvFwpag2Bf",
"created": "2024-09-26T23:22:26Z",
"proofPurpose": "authentication",
"proofValue": "z2V72e7bRFpjvphDcWfYeSDTLsbkoVU5SfWAKMwpxYAL74D8GugTuoB2vH93cJqb8XXz8tN4es9AM787CogcbmXKa"
}
]
}
Here is the log entry for just version 3 of the DID.
{"versionId": "3-QmaSKJRACGefmi19LkS6TFj5FeMEfr98GpBWk7vEmbhT92", "versionTime": "2024-09-26T23:22:26Z", "parameters": {}, "state": {"@context": ["https://www.w3.org/ns/did/v1", "https://w3id.org/security/multikey/v1", "https://identity.foundation/.well-known/did-configuration/v1", "https://identity.foundation/linked-vp/contexts/v1"], "id": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example", "authentication": ["did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example#z6MkrgET7ZLV32qNrr6vUd2kVXGw63vbPvqxDqqhRQpvngBX"], "assertionMethod": ["did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example#z6MkrgET7ZLV32qNrr6vUd2kVXGw63vbPvqxDqqhRQpvngBX"], "verificationMethod": [{"id": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example#z6MkrgET7ZLV32qNrr6vUd2kVXGw63vbPvqxDqqhRQpvngBX", "controller": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example", "type": "Multikey", "publicKeyMultibase": "z6MkrgET7ZLV32qNrr6vUd2kVXGw63vbPvqxDqqhRQpvngBX"}], "service": [{"id": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example#domain", "type": "LinkedDomains", "serviceEndpoint": "https://domain.example"}, {"id": "did:tdw:QmfGEUAcMpzo25kF2Rhn8L5FAXysfGnkzjwdKoNPi615XQ:domain.example#whois", "type": "LinkedVerifiablePresentation", "serviceEndpoint": "https://domain.example/.well-known/whois.vc"}]}, "proof": [{"type": "DataIntegrityProof", "cryptosuite": "eddsa-jcs-2022", "verificationMethod": "did:key:z6MkvQnUuQn3s52dw4FF3T87sfaTvXRW7owE1QMvFwpag2Bf#z6MkvQnUuQn3s52dw4FF3T87sfaTvXRW7owE1QMvFwpag2Bf", "created": "2024-09-26T23:22:26Z", "proofPurpose": "authentication", "proofValue": "z2V72e7bRFpjvphDcWfYeSDTLsbkoVU5SfWAKMwpxYAL74D8GugTuoB2vH93cJqb8XXz8tN4es9AM787CogcbmXKa"}]}
And so on...