ERC-7406 - Multi-Namespace Onchain Registry

Created 2023-07-23
Status Draft
Category ERC
Type Standards Track
Authors
Requires

Abstract

This EIP proposes a universally accepted description for onchain registry entries with support for multi-namespaces, where each entry is structured as a mapping type. The multi-namespace registry enables the storage of a collection of key-value mappings within the blockchain, serving as a definitive source of information with a traceable history of changes. These mapping records act as pointers combined with onchain assets, offering enhanced versatility in various use cases by encapsulating extensive details. The proposed solution introduces a general mapping data structure that is flexible enough to support and be compatible with different situations, providing a more scalable and powerful alternative to current ENS-like registries.

Motivation

Blockchain-based registries are fundamental components for decentralized applications, enabling the storage and retrieval of essential information. Existing solutions, like the ENS registry, serve specific use cases but may lack the necessary flexibility to accommodate more complex scenarios. The need for a more general mapping data structure with multi-namespace support arises to empower developers with a single registry capable of handling diverse use cases efficiently.

The proposed multi-namespace registry offers several key advantages:

Specification

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

Registry specification

The multi namespace registry contract exposes the following functions:

function owner(bytes32 namespace, bytes32 key) external view returns (address);
function resolver(bytes32 namespace, bytes32 key) external view returns (address);
function setOwner(bytes32 namespace, bytes32 key, address newOwner) external;
function createNamespace(bytes32 namespace) external;
function setResolver(bytes32 namespace, bytes32 key, address newResolver) external;

Resolver specification

The multi-namespace resolver contract can utilize the same specification as defined in ERC-137.

Rationale

By supporting multiple namespaces, the registry caters to various use cases, including but not limited to identity management, session management, record tracking, and decentralized content publishing. This flexibility enables developers to design and implement more complex decentralized applications with ease.

Backwards Compatibility

As this EIP introduces a new feature and does not modify any existing behaviors, there are no backwards compatibility issues.

Reference Implementation

Appendix A: Registry Implementation

pragma solidity ^0.8.12;

import "./IERC7406Interface.sol";

contract ERC7406 {
    struct Record {
        address owner;
        address resolver;
    }


    // A map is used to record namespace existence
    mapping(byte32=>uint) namespaces;
    mapping(bytes32=>mapping(bytes32=>Record)) records;

    event NewOwner(bytes32 indexed namespace, bytes32 indexed key, address owner);
    event Transfer(bytes32 indexed namespace, bytes32 indexed key, address owner);
    event NewResolver(bytes32 indexed namespace, bytes32 indexed key, address resolver);
    event NewNamespace(bytes32 namespace)

    modifier only_owner(bytes32 namespace, bytes32 key) {
        if(records[namespace][key].owner != msg.sender) throw;
        _
    }

    modifier only_approver() {
        if(records[0][0].owner != msg.sender) throw;
        _
    }

    function ERC7406(address approver) {
        records[0][0].owner = approver;
    }

    function owner(bytes32 namespace, bytes32 key) constant returns (address) {
        return records[namespace][key].owner;
    }

    function createNamespace(bytes32 namespace) only_approver() {
       if (status == 0) throw;
       NewNamespace(namespace);
       if (namespaces[namespace] != 0) {
           return;
       }
       namespaces[namespace] = 1;
    }

    function resolver(bytes32 namespace, bytes32 key) constant returns (address) {
        if (namespaces[namespace] == 0) throw;
        return records[namespace][key].resolver;
    }

    function setOwner(bytes32 namespace, bytes32 key, address owner) only_owner(namespace, key) {
        Transfer(key, namespace, owner);
        records[namespace][key].owner = owner;
    }

    function setResolver(bytes32 namespace, bytes32 key, address resolver) only_approver() {
        if (namespaces[namespace] == 0) {
            this.createNamespace(namespace, 1);
        }
        NewResolver(key, namespace, resolver);
        records[namespace][key].resolver = resolver;
    }
}

Security Considerations

The proposed multi-namespace registry introduces several security considerations due to its ability to manage various namespaces and access controls. Thorough testing, auditing, and peer reviews will be conducted to identify and mitigate potential attack vectors and vulnerabilities. Security-conscious developers are encouraged to contribute to the audit process.

Copyright

Copyright and related rights waived via CC0.