DidDoc
Last updated
Last updated
This module implements decentralized identity (DID) management by enabling on‑chain creation, update, deactivation, and querying of DID documents. It follows self‑sovereign identity (SSI) principles and is inspired by the W3C DID specification.
The diddoc
module is responsible for handling decentralized identifiers (DIDs) and their associated documents. A DID
document (or simply “DID document”) encapsulates all information about a decentralized identity: its identifier, the
public keys (verification methods) used for authentication and cryptography, the relationships that designate which keys
are allowed to perform certain actions, and service endpoints that describe how to interact with the identity. In
addition to managing identity creation and updates, the module supports deactivation of DID documents and parameter
management, ensuring that all DID documents conform to defined limits and patterns. To optimize storage, DID documents
are compressed before being stored on‑chain.
The module defines several messages to modify the on‑chain state. Each message implements the Cosmos SDK Msg
interface
and has its own structure, validation rules, and state modifications.
Purpose: Creates a new DID document and stores it on‑chain. The document must be signed by two keys—a primary key and a backup key—to ensure its authenticity and future updatability. Additionally, a DID document tier is specified so that the document adheres to the limits defined for that tier.
Structure:
Field Details:
Sender: The account address (in Bech32 format) that submits the creation request.
Signatures: An array containing exactly two signatures:
Each signature includes:
MethodId: A string referencing the verification method used to sign. For example, the primary key might be
referenced as "did:empe:...#0"
, while the backup key might be referenced as "did:empe:...#backup"
.
SigBytes: The signature bytes (encoded in base64) produced by signing the serialized DID document.
TierName: Specifies the name of the DID document tier to use. Each tier (configured in module parameters) defines its own limits for the maximum number of verification methods and elements allowed in a DID document.
Processing and State Modifications:
Validation:
The DID document is checked for completeness. This includes verifying that all required fields are present and
that the document’s id
begins with the expected DID prefix.
Field limits are enforced based on the selected tier’s configuration.
Signature Verification:
The module serializes the DID document using the provided codec.
Both signatures are verified against the corresponding public keys embedded (or referenced) in the document.
Storage:
Once all validations pass, the document is compressed (to save space) and stored in the module’s key–value store.
The document is stored with an initial version number of 1 and marked with a status of ACTIVE.
Events:
An event (e.g. EventCreateDidDocument
) is emitted to indicate successful creation.
Purpose: Updates an existing DID document. This message allows changes to the document while enforcing versioning and disallowing certain forbidden modifications.
Structure:
Field Details:
Sender: The Bech32 address of the account requesting the update.
UpdatedDidDocument: A wrapper object containing:
DidDocument: The full, updated DID document.
Version: The new version number. This must be exactly one greater than the currently stored version.
Signature: Contains:
MethodId: The identifier of the verification method used for the update. Typically, this is chosen from the
document’s capabilityInvocation
relationships.
SigBytes: The base64‑encoded signature over the serialized update payload.
Processing and State Modifications:
Version Check:
The module ensures that the new version equals the stored version plus one.
Validation:
The updated document is validated for structure, field limits, and integrity.
Forbidden modifications (for example, altering the backup key) are detected and rejected.
Signature Verification:
The update signature is verified against the verification method indicated by MethodId
.
Storage:
Upon successful verification, the updated DID document is compressed and stored, and its version is updated.
Events:
An event (e.g. EventUpdateDidDocument
) is emitted to indicate a successful update.
Purpose: Deactivates an existing DID document so that it cannot be used or updated further.
Structure:
Field Details:
Sender: The account address submitting the deactivation request.
Did: The unique decentralized identifier of the document to be deactivated.
Version: A number that must be exactly one greater than the current version of the stored DID document.
Signature: A signature over a deactivation payload. The verification approach depends on whether the document is stored on‑chain:
On‑Chain: The signature is verified using the backup verification method.
Off‑Chain: An Ethereum‑style signature verification process is used.
Processing and State Modifications:
Version Validation:
Confirms that the provided version number is correct.
Signature Verification:
Depending on the state of the DID document (on‑chain or off‑chain), an appropriate signature verification method is invoked.
Storage:
The document’s status is updated to DEACTIVATED
and stored with the new version.
Events:
Emits an event (e.g. EventDeactivateDidDocument
) to signal the deactivation.
Purpose: Allows updates to module parameters (such as the DID prefix or field limits). This message is typically submitted by the governance process.
Structure:
Field Details:
Authority: The address that is permitted to update parameters (for example, the governance module’s account). It must be a valid Bech32 address and match the stored authority.
Params: A structure containing:
did_prefix: The prefix used for DIDs within this module.
did_doc_tiers: A list of DID document tiers. Each tier is defined by:
name: The tier’s name.
max_did_verification_methods_count: The maximum number of verification methods permitted in a DID document for this tier.
max_did_elements_count: The maximum number of elements (such as those in context, controller, service, etc.) allowed in this tier.
Processing and State Modifications:
Validation:
Ensures that the authority is correct and that the new parameters meet all validation rules (for instance, the DID prefix must follow a specific regex pattern).
Storage:
Updates the module’s parameter store.
Events:
Typically, an event is emitted so that parameter changes can be tracked.
A DID document is the fundamental data structure managed by this module. It is defined as follows:
Id:
The unique identifier for the DID. Must be prefixed according to module parameters (e.g. "did:empe:"
).
Context: Provides semantic context to the DID document. This field is an array of URIs that define the meaning of the other fields.
Controller: Lists one or more DIDs that are allowed to control (update, deactivate, etc.) the DID document.
AlsoKnownAs: Contains alternative names or URLs for the DID.
VerificationMethod: An array of objects that specify public keys or other verification mechanisms. Each verification method typically includes:
Id: A unique fragment appended to the DID (for example, "#0"
, "#backup"
).
Type: The type of verification method (usually "JsonWebKey"
).
Controller: The DID that controls this verification method.
Verification Material: Usually provided as a JSON Web Key (JWK) containing:
kty: Key type (e.g. "EC"
).
crv: The elliptic curve used (e.g. "secp256k1"
).
x: Base64‑encoded representation of the X-coordinate.
y: Base64‑encoded representation of the Y-coordinate (may be empty for compressed keys).
Authentication, AssertionMethod, KeyAgreement, CapabilityInvocation, CapabilityDelegation:
Each of these is an array of DidVerificationRelationship
objects that can either:
Reference an existing verification method (by its id
), or
Embed a verification method inline.
These relationships define which keys are used for authentication, making assertions, performing key agreements, invoking capabilities, or delegating them.
Service: Specifies external services associated with the DID. Each service includes:
Id: A unique identifier for the service (often formed by appending a fragment to the DID).
Type: The type of service (e.g. "DIDCommMessaging"
).
ServiceEndpoint: A list of URLs or endpoints where the service is accessible.
The module exposes several gRPC query endpoints:
QueryDidDocument: Returns the current DID document for a given DID.
QueryDidStatus: Provides the current status of a DID (e.g. whether it is active or deactivated, and whether it is stored on‑chain or off‑chain).
QueryDidDocumentVersion: Returns the current version number of a DID document.
QueryParams: Returns the current module parameters.
Default Genesis:
Created by DefaultGenesis()
, which initializes an empty document list and sets default parameters.
InitGenesis: Reads and decompresses the DID documents from genesis and stores each in the module’s state.
ExportGenesis: Retrieves all stored DID documents, compresses them into a single byte slice, and produces a genesis state.
create-did-document:
Reads a JSON file containing a DID document, along with the tier name and two signatures (primary and backup),
constructs a MsgCreateDidDocument
, and broadcasts it.
Example:
update-did-document:
Reads an update payload (a DID document with a bumped version) from a JSON file and submits a MsgUpdateDidDocument
along with the required signature.
Example:
deactivate-did-document:
Deactivates a DID document by broadcasting a MsgDeactivateDidDocument
.
Example:
insert-diddocs-to-genesis: Bulk inserts randomly generated DID documents into a genesis file.
did-document: Queries a DID document by its identifier.
did-status: Queries the status (active/deactivated, on‑chain/off‑chain) of a given DID.
params: Queries the current module parameters.
These commands are available under the module’s CLI command tree (see the client/cli
directory).
The keeper of the diddoc module encapsulates all storage logic:
StoreDidDocument: Compresses the DID document and writes it along with metadata (version and status) under a prefixed key.
ReadDidDocument / ReadStoredDidDocument: Retrieves, decompresses, and unmarshals DID documents from the key–value store.
Pagination: Supports standard Cosmos SDK pagination for listing DID documents.
Signature and Key Verification: Implements functions to verify both ECDSA and Ethereum‑style signatures. It also contains helper functions for reconstructing public keys from JSON Web Keys (JWK).
Unit Tests: Cover message validation, keeper operations, signature verification (both standard and Ethereum‑style), and state modifications.
Simulation: A simulation package generates random DID documents and simulates operations (create, update, deactivate) to test module behavior under load.
Integration Tests: Validate end‑to‑end flows (for example, ensuring that updates to a DID document properly increment version numbers and maintain integrity).
The diddoc module is a comprehensive solution for decentralized identity management on a blockchain. Its messages
enable users to create, update, and deactivate DID documents while enforcing strict versioning, signature verification,
and parameter limits. A DID document includes key fields such as the identifier (id
), context, controllers,
verification methods (with embedded cryptographic material), various relationships for authentication and delegation,
and service endpoints. All documents are compressed before storage, and robust queries as well as CLI commands enable
easy access and management of identity data.
With the latest changes, the module now supports multiple DID document tiers through the updated parameters (did_prefix
and a list of did_doc_tiers
), and the DID document creation process requires specifying the tier name to
ensure that the document adheres to the predefined limits.
For further details, refer to the source code in the x/diddoc/
directory and the associated tests and simulations.
DidDocument: The core object containing the decentralized identity information. ( See for field details.)