DID Registry Smart Contract

View as Markdown

The DID Registry is the core on-chain contract that stores DID registrations, document hashes, and lifecycle state on the ADI blockchain.

Contract Address

NetworkAddress
ADI Mainnet0x... (TBD)
ADI Testnet0x5FbDB2315678afecb367f032d93F642f64180aa3
Local DevnetDeployed via forge script

Interface

1// SPDX-License-Identifier: MIT
2pragma solidity ^0.8.24;
3
4interface IDIDRegistry {
5 struct DIDRecord {
6 address owner;
7 bytes32 documentHash;
8 string storageUri;
9 uint256 versionId;
10 uint256 created;
11 uint256 updated;
12 bool deactivated;
13 uint256 nonce;
14 }
15
16 event DIDRegistered(string indexed did, address indexed owner, bytes32 documentHash);
17 event DIDUpdated(string indexed did, bytes32 newDocumentHash, uint256 versionId);
18 event DIDDeactivated(string indexed did);
19 event DIDOwnerChanged(string indexed did, address indexed newOwner);
20
21 function registerDID(
22 string calldata did,
23 bytes32 documentHash,
24 string calldata storageUri
25 ) external;
26
27 function resolveDID(string calldata did) external view returns (DIDRecord memory);
28
29 function updateDID(
30 string calldata did,
31 bytes32 newDocumentHash,
32 string calldata newStorageUri
33 ) external;
34
35 function deactivateDID(string calldata did) external;
36
37 function changeOwner(string calldata did, address newOwner) external;
38
39 function getNonce(string calldata did) external view returns (uint256);
40
41 function isActive(string calldata did) external view returns (bool);
42}

Key Functions

registerDID

Registers a new DID on the blockchain.

1function registerDID(
2 string calldata did,
3 bytes32 documentHash,
4 string calldata storageUri
5) external;
ParameterTypeDescription
didstringThe full DID string (e.g., did:adi:3f7a...)
documentHashbytes32SHA-256 hash of the DID Document
storageUristringIPFS URI for the full DID Document

Requirements:

  • DID must not already exist
  • msg.sender becomes the owner
  • Emits DIDRegistered event

resolveDID

Returns the on-chain record for a DID.

1function resolveDID(string calldata did) external view returns (DIDRecord memory);

Returns: Full DIDRecord struct including document hash, storage URI, version, and status.

updateDID

Updates the DID Document hash and storage URI.

1function updateDID(
2 string calldata did,
3 bytes32 newDocumentHash,
4 string calldata newStorageUri
5) external;

Requirements:

  • msg.sender must be the DID owner
  • DID must not be deactivated
  • Increments versionId
  • Emits DIDUpdated event

deactivateDID

Permanently deactivates a DID.

1function deactivateDID(string calldata did) external;

Requirements:

  • msg.sender must be the DID owner
  • DID must not already be deactivated
  • Sets deactivated = true
  • Emits DIDDeactivated event

Interaction Examples

Register a DID (ethers.js)

1import { ethers } from 'ethers';
2
3const registry = new ethers.Contract(DID_REGISTRY_ADDRESS, DID_REGISTRY_ABI, signer);
4
5const did = 'did:adi:3f7a9b2e1c4d5f6a8b0c2d4e6f8a0b2c...';
6const documentHash = ethers.keccak256(ethers.toUtf8Bytes(JSON.stringify(didDocument)));
7const storageUri = 'ipfs://QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco';
8
9const tx = await registry.registerDID(did, documentHash, storageUri);
10await tx.wait();
11console.log('DID registered:', tx.hash);

Resolve a DID

1const record = await registry.resolveDID('did:adi:3f7a9b2e1c4d...');
2console.log('Owner:', record.owner);
3console.log('Document hash:', record.documentHash);
4console.log('Storage URI:', record.storageUri);
5console.log('Version:', record.versionId.toString());
6console.log('Active:', !record.deactivated);

Gas Costs

OperationEstimated GasEstimated Cost (ADI)
registerDID~150,000~0.003 ADI
resolveDID0 (view)Free
updateDID~80,000~0.0016 ADI
deactivateDID~50,000~0.001 ADI
changeOwner~45,000~0.0009 ADI

Security Considerations

  • Only the DID owner can update or deactivate their DID
  • Deactivation is permanent and irreversible
  • The contract uses a nonce-based replay protection
  • All state changes emit events for off-chain indexing
  • The contract is upgradeable via a proxy pattern for bug fixes