DIDRegistry

Overview

The DIDRegistry contract implements a decentralized identity (DID) registry following the W3C DID specification. It enables users to register, update, and manage DID Documents on-chain with support for verification methods, services, and delegated control.

Contract Details

Property
Value

Solidity Version

^0.8.28

License

MIT

Inheritance

Context, EIP712 (OpenZeppelin)

DID Method

did:pkh (Public Key Hash)


Purpose

The DIDRegistry contract provides a complete on-chain DID management system:

  • Self-Sovereign Identity: Users control their own DID documents

  • Delegated Control: Authorized controllers can manage DIDs on behalf of subjects

  • Verification Methods: Support for multiple cryptographic keys with relationship types

  • Services: Link external services to DID documents

  • Meta-Transactions: EIP-712 signatures enable gasless updates


Data Structures

VerificationMethod

Represents a cryptographic key or verification method.

Field
Type
Description

id

string

Full DID URL identifier for the method

methodType

string

Cryptographic suite type

metadata

string

JSON-encoded additional properties

controller

address

Ethereum address of the controller

relationships

uint8

Bitflags indicating verification relationships

Service

Represents an external service endpoint.

Field
Type
Description

id

string

Unique service identifier

serviceType

string

Type classification

serviceEndpoint

string

URL, URI, or JSON endpoint data

DIDDocument

The complete DID Document structure.

Field
Type
Description

context

string[]

JSON-LD context URIs

controllers

address[]

Delegated controller addresses

alsoKnownAs

string[]

Alias identifiers

verificationMethods

VerificationMethod[]

Array of verification methods

services

Service[]

Array of service endpoints

nonce

uint256

Auto-incrementing counter for updates


Verification Relationships

Verification relationships are stored as packed bitflags in a uint8:

Constant
Value
Hex
Description

AUTHENTICATION

1

0x01

Key can authenticate as the DID subject

ASSERTION

2

0x02

Key can make assertions/claims

KEY_AGREEMENT

4

0x04

Key can be used for key agreement (encryption)

CAPABILITY_INVOCATION

8

0x08

Key can invoke capabilities

CAPABILITY_DELEGATION

16

0x10

Key can delegate capabilities

Examples

Relationships
Value
Binary

Authentication only

1

00001

Authentication + Assertion

3

00011

Key Agreement only

4

00100

All relationships

31

11111


State Variables

Variable
Type
Visibility
Description

DID_TYPE

string

public constant

DID method type ("did:pkh")

AUTHENTICATION

uint8

public constant

Authentication bitflag (1)

ASSERTION

uint8

public constant

Assertion bitflag (2)

KEY_AGREEMENT

uint8

public constant

Key Agreement bitflag (4)

CAPABILITY_INVOCATION

uint8

public constant

Capability Invocation bitflag (8)

CAPABILITY_DELEGATION

uint8

public constant

Capability Delegation bitflag (16)

didDocuments

mapping(address => DIDDocument)

internal

DID document storage


Functions

Constructor

Initializes the contract with EIP-712 domain parameters.

Parameters:

Name
Type
Description

name

string

Domain name (e.g., "DIDRegistry")

version

string

Domain version (e.g., "1")


Registration Functions

registerDID

Registers a new DID document for msg.sender.

Parameters:

Name
Type
Description

_didDocument

DIDDocument

The DID document to register

Requirements:

  • Subject must not already have a registered DID (nonce == 0)

  • Context array must not be empty

Emits: DIDRegistered


registerDIDOf

Registers a DID on behalf of another address using their signature.

Parameters:

Name
Type
Description

_didDocument

DIDDocument

The DID document to register

_didSubject

address

The address to register the DID for

_subjectSignature

bytes

EIP-712 signature from the subject

Requirements:

  • Signature must be from the _didSubject

  • Subject must not already have a registered DID

Emits: DIDRegistered


Update Functions

updateDID

Updates an existing DID document.

Parameters:

Name
Type
Description

_didDocument

DIDDocument

The updated DID document

_didSubject

address

The address whose DID to update

Requirements:

  • Caller must be the subject OR a listed controller

  • Provided nonce must match current stored nonce

  • Context array must not be empty

Emits: DIDUpdated


updateDIDOf

Updates a DID document using a signature from an authorized party.

Parameters:

Name
Type
Description

_didDocument

DIDDocument

The updated DID document

_didSubject

address

The address whose DID to update

_signature

bytes

EIP-712 signature from subject or controller

Requirements:

  • Signer must be the subject OR a listed controller

  • Provided nonce must match current stored nonce

Emits: DIDUpdated


Query Functions

getDIDDocument

Retrieves the DID document for a given address.

Parameters:

Name
Type
Description

subject

address

The DID subject address

Returns: DIDDocument struct (empty if not registered)


isController

Checks if an address is a controller for a DID.

Parameters:

Name
Type
Description

subject

address

The DID subject address

account

address

The address to check

Returns: true if account is listed as a controller


Relationship Helper Functions

hasRelationship

Checks if a relationship flag is set.

Parameters:

Name
Type
Description

relationships

uint8

The packed relationship bitflags

flag

uint8

The flag to check (e.g., AUTHENTICATION)

Returns: true if the flag is set

Example:


addRelationship

Adds a relationship flag.

Parameters:

Name
Type
Description

relationships

uint8

Current relationship bitflags

flag

uint8

The flag to add

Returns: Updated relationship bitflags


removeRelationship

Removes a relationship flag.

Parameters:

Name
Type
Description

relationships

uint8

Current relationship bitflags

flag

uint8

The flag to remove

Returns: Updated relationship bitflags


Hashing Functions

hashDIDDocument

Computes the EIP-712 struct hash for a DID document.

getTypedDataHash

Returns the complete EIP-712 typed data hash for signing.


Events

DIDRegistered

Emitted when a new DID document is registered.

DIDUpdated

Emitted when a DID document is updated.

Parameter
Description

subject

The DID subject address

updatedBy

The address that performed the update

nonce

The new nonce value after update


Errors

Error
Description

InvalidContext()

Context array is empty

InvalidControllers()

Controllers array validation failed

InvalidSignature()

Signature verification failed

InvalidNonce()

Provided nonce doesn't match stored nonce

Unauthorized()

Caller is not authorized to update

AlreadyRegistered()

DID already registered for this address


EIP-712 Type Definitions

VerificationMethod

Service

DIDDocument


Usage Examples

Registering a DID Document (TypeScript/Viem)

Registering on Behalf of Another User

Updating with Delegated Controller

Reading and Decoding a DID Document


W3C DID Document Mapping

The contract's structures map to W3C DID Document format:

W3C Property
Contract Field
Notes

@context

context

Array of context URIs

id

N/A (mapping key)

Derived from did:pkh:{address}

controller

controllers

Array of controller addresses

alsoKnownAs

alsoKnownAs

Alternative identifiers

verificationMethod

verificationMethods

Array of methods

authentication

relationships bitflag

Derived from bitflag

assertionMethod

relationships bitflag

Derived from bitflag

keyAgreement

relationships bitflag

Derived from bitflag

capabilityInvocation

relationships bitflag

Derived from bitflag

capabilityDelegation

relationships bitflag

Derived from bitflag

service

services

Array of services

Example: JSON-LD to Solidity Encoding

W3C JSON-LD Format:

Solidity Struct Encoding:


Security Considerations

  1. Nonce Protection: Each update increments the nonce, preventing replay attacks

  2. Controller Authorization: Only subject or listed controllers can update

  3. Signature Verification: Meta-transactions verified via EIP-712 ECDSA recovery

  4. Context Validation: Empty context arrays are rejected

  5. Immutable Registration: DID cannot be re-registered once created


  • Agreement: Uses DIDs for party identification

  • Consent: Links consent records to DID-identified suppliers


Deployment

The contract is deployed using Hardhat Ignition:

Last updated