> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.adid.dev/llms.txt.
> For full documentation content, see https://docs.adid.dev/llms-full.txt.

# DID Registry Smart Contract

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

## Contract Address

| Network      | Address                                      |
| ------------ | -------------------------------------------- |
| ADI Mainnet  | `0x...` (TBD)                                |
| ADI Testnet  | `0x5FbDB2315678afecb367f032d93F642f64180aa3` |
| Local Devnet | Deployed via `forge script`                  |

## Interface

```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

interface IDIDRegistry {
    struct DIDRecord {
        address owner;
        bytes32 documentHash;
        string storageUri;
        uint256 versionId;
        uint256 created;
        uint256 updated;
        bool deactivated;
        uint256 nonce;
    }

    event DIDRegistered(string indexed did, address indexed owner, bytes32 documentHash);
    event DIDUpdated(string indexed did, bytes32 newDocumentHash, uint256 versionId);
    event DIDDeactivated(string indexed did);
    event DIDOwnerChanged(string indexed did, address indexed newOwner);

    function registerDID(
        string calldata did,
        bytes32 documentHash,
        string calldata storageUri
    ) external;

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

    function updateDID(
        string calldata did,
        bytes32 newDocumentHash,
        string calldata newStorageUri
    ) external;

    function deactivateDID(string calldata did) external;

    function changeOwner(string calldata did, address newOwner) external;

    function getNonce(string calldata did) external view returns (uint256);

    function isActive(string calldata did) external view returns (bool);
}
```

## Key Functions

### registerDID

Registers a new DID on the blockchain.

```solidity
function registerDID(
    string calldata did,
    bytes32 documentHash,
    string calldata storageUri
) external;
```

| Parameter      | Type    | Description                                   |
| -------------- | ------- | --------------------------------------------- |
| `did`          | string  | The full DID string (e.g., `did:adi:3f7a...`) |
| `documentHash` | bytes32 | SHA-256 hash of the DID Document              |
| `storageUri`   | string  | IPFS 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.

```solidity
function 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.

```solidity
function updateDID(
    string calldata did,
    bytes32 newDocumentHash,
    string calldata newStorageUri
) external;
```

**Requirements:**

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

### deactivateDID

Permanently deactivates a DID.

```solidity
function 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)

```javascript
import { ethers } from 'ethers';

const registry = new ethers.Contract(DID_REGISTRY_ADDRESS, DID_REGISTRY_ABI, signer);

const did = 'did:adi:3f7a9b2e1c4d5f6a8b0c2d4e6f8a0b2c...';
const documentHash = ethers.keccak256(ethers.toUtf8Bytes(JSON.stringify(didDocument)));
const storageUri = 'ipfs://QmXoypizjW3WknFiJnKLwHCnL72vedxjQkDDP1mXWo6uco';

const tx = await registry.registerDID(did, documentHash, storageUri);
await tx.wait();
console.log('DID registered:', tx.hash);
```

### Resolve a DID

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

## Gas Costs

| Operation     | Estimated Gas | Estimated Cost (ADI) |
| ------------- | ------------- | -------------------- |
| registerDID   | \~150,000     | \~0.003 ADI          |
| resolveDID    | 0 (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