Alert Source Discuss
⚠️ Review Standards Track: ERC

ERC-4824: DAO 的通用接口

分布式自治组织 (DAO) 的 API。

Authors Joshua Tan (@thelastjosh), Isaac Patka (@ipatka), Ido Gershtein <ido@daostack.io>, Eyal Eithcowich <eyal@deepdao.io>, Michael Zargham (@mzargham), Sam Furter (@nivida)
Created 2022-02-17

摘要

分布式自治组织 (DAO) 的 API 标准,重点是关联链上和链下的成员资格和提案的表示。

动机

自以太坊白皮书中被调用以来,DAO 的定义一直很模糊。这导致了各种各样的模式,但新兴的框架和工具之间几乎没有标准化或互操作性。标准化和互操作性对于支持各种用例是必要的。特别是,类似于 ERC-721 中的 tokenURI 的标准 daoURI 将增强 DAO 的可发现性、可读性、提案模拟以及工具之间的互操作性。跨生态系统更一致的数据也是未来 DAO 标准的先决条件。

规范

本文档中的关键词“必须”、“禁止”、“必需”、“应”、“不应”、“应该”、“不应该”、“推荐”、“可以”和“可选”应按照 RFC 2119 中的描述进行解释。

每个实现此 EIP 的合约必须实现下面的 IERC4824 接口:

pragma solidity ^0.8.1;

/// @title ERC-4824 DAOs
/// @dev See <https://eips.ethereum.org/EIPS/eip-4824>
interface IERC4824 {
    event DAOURIUpdate(address daoAddress, string daoURI);

    /// @notice 指向遵循 "ERC-4824 DAO JSON-LD Schema" 的 JSON 对象的不同统一资源标识符 (URI)。此 JSON 文件分为四个附属 URI:membersURI、proposalsURI、activityLogURI 和 governanceURI。membersURI 应该指向符合 "ERC-4824 Members JSON-LD Schema" 的 JSON 文件。proposalsURI 应该指向符合 "ERC-4824 Proposals JSON-LD Schema" 的 JSON 文件。activityLogURI 应该指向符合 "ERC-4824 Activity Log JSON-LD Schema" 的 JSON 文件。governanceURI 应该指向一个平面文件,通常是一个 .md 文件。上面命名的每个 JSON 文件都可以是静态托管或动态生成的。附属 JSON 文件的内容可以直接嵌入为顶级 DAO JSON 中的 JSON 对象,在这种情况下,相关字段必须重命名以删除 "URI" 后缀。例如,"membersURI" 将重命名为 "members","proposalsURI" 将重命名为 "proposals",依此类推。
    function daoURI() external view returns (string memory _daoURI);
}

上面提到的 DAO JSON-LD Schema:

{
    "@context": "http://www.daostar.org/schemas",
    "type": "DAO",
    "name": "<DAO 的名称>",
    "description": "<描述>",
    "membersURI": "<URI>",
    "proposalsURI": "<URI>",
    "activityLogURI": "<URI>",
    "governanceURI": "<URI>",
    "contractsURI": "<URI>"
}

DAO 可以继承上面的 IERC4824 接口,也可以创建一个符合此 EIP 的外部注册合约。无论 DAO 继承上面的接口还是使用外部注册合约,DAO 都应该定义一种方法并实现一些访问控制逻辑,以实现高效的 daoURI 更新。如果 DAO 创建一个外部注册合约,则注册合约必须存储 DAO 的主要地址,通常是主要治理合约的地址。请参阅附加到此 EIP 的资产文件夹中外部注册合约的参考实现。

在 DAO JSON-LD Schema 中报告信息时,如果给定字段没有值(例如,description),则应该将其删除,而不是保留为空或 null 值。

索引

如果 DAO 从符合 4824 规范的 DAO 工厂继承了 IERC4824 接口,那么 DAO 工厂应该将对索引器合约的调用作为 DAO 初始化的一部分,以实现高效的网络索引。如果 DAO 符合 ERC-165,则工厂可以在没有额外权限的情况下执行此操作。如果 DAO 符合 ERC-165,则工厂应首先获得对索引器合约的访问控制权限,然后使用新 DAO 的地址和新 DAO 的 daoURI 直接调用 logRegistration。请注意,任何用户,包括 DAO 本身,都可以调用 logRegistration 并提交一个继承了 IERC4824 接口并且也符合 ERC-165 的 DAO 的注册。

pragma solidity ^0.8.1;

error ERC4824InterfaceNotSupported();

contract ERC4824Index is AccessControl {
    using ERC165Checker for address;

    bytes32 public constant REGISTRATION_ROLE = keccak256("REGISTRATION_ROLE");

    event DAOURIRegistered(address daoAddress);

    constructor() {
        _grantRole(DEFAULT_ADMIN_ROLE, msg.sender);
        _grantRole(REGISTRATION_ROLE, msg.sender);
    }

    function logRegistrationPermissioned(
        address daoAddress
    ) external onlyRole(REGISTRATION_ROLE) {
        emit DAOURIRegistered(daoAddress);
    }

    function logRegistration(address daoAddress) external {
        if (!daoAddress.supportsInterface(type(IERC4824).interfaceId))
            revert ERC4824InterfaceNotSupported();
        emit DAOURIRegistered(daoAddress);
    }
}

如果 DAO 使用外部注册合约,则 DAO 应该使用链接到公共索引器的公共注册工厂合约,以实现高效的网络索引。请参阅附加到此 EIP 的资产文件夹中工厂合约的参考实现。

索引优先级

daoURIs 可以直接在 DAO 的合约中发布,也可以通过调用公共注册工厂合约来发布。在两种情况都发生时,通过调用注册工厂合约发布的 daoURI(以及所有子 URI)应该优先。如果有多个注册,则最近的注册应该优先。

成员

Members JSON-LD Schema。每个实现此 EIP 的合约都应该实现一个指向满足此 schema 的 JSON 对象的 membersURI。下面,DID 指的是 Decentralized Identifiers

{
    "@context": "https://www.daostar.org/schemas",
    "type": "DAO",
    "members": [
        {
            "id": "<CAIP-10 地址、DID 地址或其他 URI 标识符>"
        },
        {
            "id": "<CAIP-10 地址、DID 地址或其他 URI 标识符>"
        }
    ]
}

例如,对于以太坊主网上的地址,CAIP-10 地址的形式为 eip155:1:0x1234abcd,而 DID 地址的形式为 did:ethr:0x1234abcd

提案

Proposals JSON-LD Schema。每个实现此 EIP 的合约都应该实现一个指向满足此 schema 的 JSON 对象的 proposalsURI。

特别是,任何链上提案都必须与 CAIP10_ADDRESS + “?proposalId=” + PROPOSAL_COUNTER 形式的 id 相关联,其中 CAIP10_ADDRESS 是遵循 CAIP-10 标准的地址,PROPOSAL_COUNTER 是一个任意标识符,例如 uint256 计数器或在每个 CAIP-10 地址本地唯一的哈希。链下提案可以使用类似的 id 格式,其中 CAIP10_ADDRESS 被替换为适当的 URI 或 URL。

{
    "@context": "https://www.daostar.org/schemas",
    "proposals": [
        {
            "type": "proposal",
            "id": "<提案 ID>",
            "name": "<提案的名称或标题>",
            "contentURI": "<提案内容/文本的 URI>",
            "discussionURI": "<提案讨论或主题的 URI>",
            "status": "<提案的状态>",
            "calls": [
                {
                    "type": "CallDataEVM",
                    "operation": "<调用或委托调用>",
                    "from": "<EthereumAddress>",
                    "to": "<EthereumAddress>",
                    "value": "<value>",
                    "data": "<调用数据>"
                }
            ]
        }
    ]
}

当被取消引用时,contentURI 应该返回提案的内容(即文本)。类似地,discussionURI 应该返回一个讨论链接,无论是论坛帖子、Discord 频道还是 Twitter 帖子。

活动日志

Activity Log JSON-LD Schema。每个实现此 EIP 的合约都应该实现一个指向满足此 schema 的 JSON 对象的 activityLogURI。

{
    "@context": "https://www.daostar.org/schemas",
    "activities": [
        {
            "id": "<活动 ID>",
            "type": "activity",
            "proposal": {
                "type": "proposal"
                "id": "<提案 ID>",
            },
            "member": {
                "id": "<CAIP-10 地址、DID 地址或其他 URI 标识符>"
            }
        } 
    ]
}

合约

Contracts JSON-LD Schema。每个实现此 EIP 的合约都应该实现一个指向满足此 schema 的 JSON 对象的 contractsURI。

对于在多个不同合约(可能跨多个链)上发生的不同或去中心化治理的 DAO 来说,contractsURI 尤其重要。多个地址可能会报告相同的 daoURI。

为了防止垃圾邮件或欺骗,所有采用此规范的 DAO 都应该通过 contractsURI 发布与 DAO 关联的每个合约的地址,包括但不限于那些继承了 IERC4824 接口的合约或那些与注册工厂合约交互的合约。请注意,这包括通过注册工厂部署的任何实际注册合约的合约地址。

{
    "@context": "https://www.daostar.org/schemas",
    "contracts": [
        {
            "id": "<CAIP-10 地址、DID 地址或其他 URI 标识符>"
            "name": "<名称,例如国库>",
            "description": "<描述,例如 DAO 的主要运营国库>"
        },
        {
            "id": "<CAIP-10 地址、DID 地址或其他 URI 标识符>"
            "name": "<名称,例如治理代币>",
            "description": "<描述,例如 ERC20 治理代币合约>"
        },
        {
            "id": "<CAIP-10 地址、DID 地址或其他 URI 标识符>"
            "name": "<名称,例如注册合约>",
            "description": "<描述,例如 ERC-4824 注册合约>"
        }
    ]
}

URI 字段

附属 JSON 文件的内容可以直接嵌入为顶级 DAO JSON 中的 JSON 对象,在这种情况下,相关字段必须重命名以删除 “URI” 后缀。例如,membersURI 将重命名为 membersproposalsURI 将重命名为 proposals,依此类推。在所有情况下,嵌入的 JSON 对象都必须符合相关的 schema。给定的字段和带有 URI 后缀的字段(例如,membersURImembers)不应该出现在同一个 JSON-LD 中;如果它们出现,则没有 URI 后缀的字段必须优先。

未附加 URI 的字段可以附加 URI,例如,namedescription 可以重命名为 nameURIdescriptionURI,在这种情况下,取消引用的 URI 必须返回一个包含 \"@context\": \"https://www.daostar.org/schemas\" 字段和原始键值对的 JSON-LD 对象。

例如,descriptionURI 应该返回:

{
    "@context": "https://www.daostar.org/schemas",
    "description": "<描述>"
}

不是 DAO 的实体

不是 DAO 或不希望被识别为 DAO 的实体仍然可以发布 daoURIs。如果是这样,它们应该为 type 字段使用与 “DAO” 不同的值,例如 “Organization”、”Foundation”、”Person” 或最广泛的 “Entity”。

不是 DAO 或不希望被识别为 DAO 的实体也可以通过链下 orgURI 或 entityURI 发布元数据信息,它们是 daoURI 的别名。但是,如果这些实体通过链上智能合约或注册报告其 URI,则它们必须保留 IERC4824 的 daoURI 才能启用网络索引。

Entity JSON-LD Schema:

{
    "@context": "https://www.daostar.org/schemas",
    "type": "<实体类型>",
    "name": "<实体名称>",
    "description": "<描述>",
    "membersURI": "<URI>",
    "proposalsURI": "<URI>",
    "activityLogURI": "<URI>",
    "governanceURI": "<URI>",
    "contractsURI": "<URI>"
}

原理

在本标准中,我们假设所有 DAO 至少拥有两个基元:成员资格行为成员资格 由一组地址定义。行为 由一组可能的合约操作定义,包括对外部合约的调用和对内部函数的调用。提案 关联成员资格和行为;它们是成员可以与之交互的对象,并且如果执行,则会成为 DAO 的行为。

API、URI 和链下数据

DAO 本身有许多现有的和新兴的用例。但是几乎所有的 DAO 都需要出于多种原因在链下发布数据:与成员沟通和招募成员,协调活动,为用户界面和治理应用程序(如 Snapshot 或 Tally)提供支持,或通过 DeepDAO、Messari 和 Etherscan 等平台启用搜索和发现。拥有一个标准化的 schema,用于组织跨多个 URI 的数据,即 API 规范,将加强 DAO 的现有用例,帮助扩展整个生态系统的工具和框架,并构建对其他形式的互操作性的支持。

虽然我们考虑在此标准中标准化 DAO 的链上方面,特别是链上提案对象和提案 ID,但我们认为这种标准化为时过早,因为 (1) 用例的相对不成熟,例如多 DAO 提案或主从合约,这些将受益于这种标准化,(2) 提案系统和治理之间的紧密联系,我们不想标准化(见下面的“governanceURI”),以及 (3) DAO 中链下和 L2 投票和提案系统的普遍存在(见下面的“proposalsURI”)。此外,标准的 URI 接口相对容易采用,并且已被框架积极要求(见下面的“社区共识”)。

我们添加了附加或删除 URI 后缀的功能,以使取消引用的 daoURI 更容易解析,尤其是在某些不想维护多个服务或平面文件的应用程序中。如果存在冲突,我们认为没有 URI 后缀的字段应该优先,因为它们更直接地连接到 daoURI 的初始发布。

在索引方面:我们认为发布 daoURI 最值得信赖的方式是通过链上注册合约,因为它是 DAO 主动意愿的最清晰反映。这也是 DAO“覆盖”先前通过任何方式发布的任何其他 daoURI 的主要方式。如果 DAO 通过其合约直接继承 daoURI,那么此信息也是值得信赖的,但略逊一筹,因为它通常反映了 DAO 框架的决策而不是 DAO 本身。

membersURI

DAO 中的成员资格方法差异很大。一些 DAO 和 DAO 框架(例如 Gnosis Safe、Tribute)维护了一组显式的链上成员,有时称为所有者或管理者。但是许多 DAO 的结构使得成员资格基于代币的所有权(例如 Moloch、Compound、DAOstack、1Hive Gardens)。在这些 DAO 中,计算当前成员列表通常需要对事件进行某种形式的链下索引。

在选择仅要求成员的(链下)JSON schema 时,我们牺牲了一些链上功能以换取更多的灵活性和效率。我们希望不同的 DAO 以不同的方式使用 membersURI:提供链上成员资格数据的静态副本,关联链上数据(例如,许多 Gnosis Safe 管理者不会说他们是 DAO 的唯一成员),为由多个合约组成的 DAO 提供一致的成员资格,或指向计算列表的外部服务,以及许多其他可能性。我们还希望许多 DAO 框架提供计算此 JSON 文件的标准端点,我们在实现部分提供了一些此类端点的示例。

我们鼓励扩展 Membership JSON-LD Schema,例如,对于希望创建捕获活跃/非活跃状态或不同成员级别的状态变量的 DAO。

proposalsURI

提案已成为 DAO 成员触发链上操作的标准方式,例如,发送代币作为赠款的一部分或在外部合约中执行任意代码。然而,在实践中,许多 DAO 受到 Discourse、Discord 或 Snapshot 等平台上的链下决策系统的管理,其中链下提案可以用作管理员的信号机制或作为稍后链上投票的先决条件。(需要明确的是,链上投票也可以用作非约束性信号机制或导致某种链下执行的“约束性”信号。)我们提出的 schema 旨在支持链上和链下提案,尽管 DAO 本身可以选择仅报告链上、仅报告链下或某些自定义的提案类型组合。

提案 ID。在规范中,我们声明每个唯一的链上提案都必须与 CAIP10_ADDRESS + “?proposalId=” + PROPOSAL_COUNTER 形式的提案 ID 相关联,其中 PROPOSAL_COUNTER 是每个 CAIP10_ADDRESS 唯一的任意字符串。请注意,PROPOSAL_COUNTER 可能与提案的链上表示形式不同;但是,每个 PROPOSAL_COUNTER 对于每个 CAIP10_ADDRESS 应该是唯一的,以便提案 ID 是一个全局唯一的标识符。我们支持 CAIP-10 标准以支持多链/第 2 层提案,并支持 “?proposalId=” 查询语法以建议链下使用。

ContentURI。在许多情况下,提案将具有一些(链下)内容,例如论坛帖子或投票平台上的描述,这些内容早于或伴随实际提案。

状态。几乎所有提案都有一个状态,但实际状态与治理系统相关联,并且现有 DAO 之间对于这些状态应该是什么没有明确的共识(请参阅下表)。因此,我们定义了一个带有通用自由文本描述字段的“状态”属性。

项目 提案状态
Aragon 未指定
Colony [‘Null’, ‘Staking’, ‘Submit’, ‘Reveal’, ‘Closed’, ‘Finalizable’, ‘Finalized’, ‘Failed’]
Compound [‘Pending’, ‘Active’, ‘Canceled’, ‘Defeated’, ‘Succeeded’, ‘Queued’, ‘Expired’, ‘Executed’]
DAOstack/ Alchemy [‘None’, ‘ExpiredInQueue’, ‘Executed’, ‘Queued’, ‘PreBoosted’, ‘Boosted’, ‘QuietEndingPeriod’]
Moloch v2 [sponsored, processed, didPass, cancelled, whitelist, guildkick]
Tribute [‘EXISTS’, ‘SPONSORED’, ‘PROCESSED’]

ExecutionData。对于具有非空执行的链上提案,我们包含一个数组字段以公开调用数据。此数据的主要用例是提案的执行模拟。

activityLogURI

活动日志 JSON 旨在捕获 DAO 成员与给定提案之间的相互作用。活动示例包括提案的创建/提交、对提案的投票、对提案的质疑等等。

我们考虑过的替代方案:history、interactions

governanceURI

成员资格,要有意义,通常意味着某种权利和便利,例如,对提案进行投票的权利、ragequit 的权利、否决提案的权利等等。但是,许多成员资格的权利和便利都是在链下实现的(例如,在 Snapshot 上投票的权利、对 Discord 的门控访问)。我们认为,与其尝试标准化这些广泛的做法或强迫 DAO 在链上找到对这些权利的描述,不如说平面文件代表了传达成员资格的含义以及提案如何运作的最简单和最广泛接受的机制。然后,这些平面文件可以被 Etherscan 等服务使用,从而支持 DAO 的可发现性和可读性。

我们选择“治理”一词作为适当的词,它可以反映 (1) 该词在 DAO 生态系统中的广泛使用,以及 (2) 在开源软件项目中发出 governance.md 文件的常见做法。

考虑的其他名称:description、readme、constitution

contractsURI

在社区对话的过程中,多方提出了报告、审计和索引属于给定 DAO 的不同合约的需求。其中一些合约是作为单个 DAO 框架的模块化设计的一部分部署的,例如 Open Zeppelin / Compound Governor 中的核心、投票和时间锁合约。在其他情况下,DAO 可能会部署多个 multsig 作为国库和/或多个实际上由 DAO 控制的 subDAO。contractsURI 提供了一种声明这些工具的通用方法,以便索引器可以有效地聚合它们。

contractsURI 对于防止垃圾邮件或欺骗也很重要。一些 DAO 可能会将治理权力和控制权分散到多个不同的治理合约中,这些合约可能跨多个链。为了捕捉到这一现实,多个地址可能希望报告相同的 daoURI,或者使用相同名称的不同 daoURI。但是,未经授权的地址可能会尝试报告相同的 daoURI 或名称。其他合约信息可以通过允许索引器剔除垃圾邮件信息来防止此类攻击。

考虑的其他名称:contractsRegistry、contractsList

为什么选择 JSON-LD

我们选择使用 JSON-LD 而不是更广泛且更简单的 JSON 标准,因为 (1) 我们希望支持 DAO 希望包括使用除其以太坊地址以外的其他形式的识别的成员的用例,并且 (2) 我们希望此标准与未来的多链标准兼容。任何一种用例都需要我们为地址实现上下文和类型,这已经在 JSON-LD 中实现。

此外,鉴于诸如 subDAO 和大型组织(如 Synthetix)中的 DAO of DAO 以及 L2 和多链用例等模式的出现,我们预计某些组织会将多个 DAO 指向相同的 URI,这将作为来自多个合约和服务的数据的网关。选择 JSON-LD 可以更轻松地扩展和管理该数据。

社区共识

最初的草案标准是作为 DAOstar 圆桌会议系列的一部分开发的,其中包括来自所有主要的基于 EVM 的 DAO 框架(Aragon、Compound、DAOstack、Gnosis、Moloch、OpenZeppelin 和 Tribute)的代表、各种各样的 DAO 工具开发人员以及几个主要的 DAO。感谢所有圆桌会议的参与者。我们特别感谢 Snapshot 的 Fabien、Jake Hartnell、Auryn Macmillan、Selim Imoberdorf、Lucia Korpas 和 Mehdi Salehi 的贡献。

用于社区评论的面对面活动于 Schelling Point 2022、ETHDenver 2022、ETHDenver 2023、DAO Harvard 2023、DAO Stanford 2023(也称为区块链科学会议 DAO 工作坊)举行。该团队还作为 DAOstar 项目的一部分举办了 50 多个双周社区电话会议。

向后兼容性

不希望使用此规范的现有合约不受影响。希望采用该标准而无需更新或迁移合约的 DAO 可以通过外部注册合约来做到这一点。

安全考虑

此标准定义了 DAO URI 的接口,但没有指定设置 URI 的规则或准备数据的方式。实施此标准的开发人员应考虑如何以与 DAO 的治理模型一致的方式更新此数据,并以最大限度地减少对集中式服务提供商的依赖的方式保持数据新鲜。

依赖于 URI 返回的数据的索引器应谨慎,如果 DAO 从 URI 返回可执行代码。此可执行代码可能旨在获取有关成员资格、提案和活动日志的最新信息,但它也可能用于运行不相关的任务。

版权

通过 CC0 放弃版权和相关权利。

Citation

Please cite this document as:

Joshua Tan (@thelastjosh), Isaac Patka (@ipatka), Ido Gershtein <ido@daostack.io>, Eyal Eithcowich <eyal@deepdao.io>, Michael Zargham (@mzargham), Sam Furter (@nivida), "ERC-4824: DAO 的通用接口 [DRAFT]," Ethereum Improvement Proposals, no. 4824, February 2022. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-4824.