Alert Source Discuss
⚠️ Review Standards Track: ERC

ERC-6366: 权限 Token

一种用于存储地址在生态系统中的权限的 token

Authors Chiro (@chiro-hiro), Victor Dusart (@vdusart)
Created 2022-01-19
Requires EIP-6617

摘要

本 EIP 提供了一种访问控制列表 (ACL) 的替代方案,用于授予授权和增强安全性。一个 uint256 用于存储给定地址在生态系统中的权限。每个权限由 uint256 中的单个位表示,如 ERC-6617 中所述。位运算符和位掩码用于确定访问权限,这比 stringkeccak256 比较要有效和灵活得多。

动机

OwnerOperatorManagerValidator 等特殊角色在许多智能合约中很常见,因为经过许可的地址用于管理它们。审计和维护这些系统很困难,因为这些权限不是在单个智能合约中管理的。

由于权限和角色通过给定生态系统中相关帐户的权限 token 余额反映,因此许多生态系统之间的交叉交互将会变得更简单。

规范

本文档中的关键词“必须 (MUST)”,“不得 (MUST NOT)”,“必需 (REQUIRED)”,“应 (SHALL)”,“不应 (SHALL NOT)”,“应该 (SHOULD)”,“不应该 (SHOULD NOT)”,“推荐 (RECOMMENDED)”,“不推荐 (NOT RECOMMENDED)”,“可以 (MAY)”和“可选 (OPTIONAL)”按照 RFC 2119 和 RFC 8174 中的描述进行解释。

注意 以下规范使用 Solidity 0.8.7(或以上版本)的语法

核心接口

符合规范的合约必须实现 IEIP6366Core

建议将每个权限定义为 2 的幂,以便我们可以使用 ERC-6617 检查权限集之间的关系。

interface IEIP6366Core {
  /**
   * 当 `_permission` 被转移时必须触发,包括 `zero` 权限转移。
   * @param _from           权限所有者
   * @param _to             权限接收者
   * @param _permission     权限所有者的已转移的权限子集
   */
  event Transfer(address indexed _from, address indexed _to, uint256 indexed _permission);

  /**
   * 必须在任何成功调用 `approve(address _delegatee, uint256 _permission)` 时触发。
   * @param _owner          权限所有者
   * @param _delegatee      被委托者
   * @param _permission     权限所有者批准的权限子集
   */
  event Approval(address indexed _owner, address indexed _delegatee, uint256 indexed _permission);

  /**
   * 将权限的子集 `_permission` 转移到地址 `_to`。
   * 如果消息调用者的帐户权限不具有转移权限的子集,则该函数应该 revert。如果任何转移的权限存在于目标 `_to` 地址上,则该函数应该 revert。
   * @param _to             权限接收者
   * @param _permission     权限所有者的权限子集
   */
  function transfer(address _to, uint256 _permission) external returns (bool success);

  /**
   * 允许 `_delegatee` 代表权限所有者行事,最高达到 `_permission`。
   * 如果再次调用此函数,它将覆盖当前授予的 `_permission`。
   * 如果授予 `_permission` 权限不是权限所有者所有可用权限的子集,则 `approve()` 方法应该 `revert`。
   * @param _delegatee      被委托者
   * @param _permission     权限所有者的权限子集
   */
  function approve(address _delegatee, uint256 _permission) external returns (bool success);

  /**
   * 返回给定 `_owner` 地址的权限。
   */
  function permissionOf(address _owner) external view returns (uint256 permission);

  /**
   * 如果 `_required` 是 `_permission` 的子集,则返回 `true`,否则返回 `false`。
   * @param _permission     正在检查的权限集
   * @param _required       所需的权限集
   */
  function permissionRequire(uint256 _permission, uint256 _required) external view returns (bool isPermissioned);

  /**
   * 如果 `_required` 权限是 `_actor` 权限的子集,或者是 `_owner` 授予的委托权限的子集,则返回 `true`。
   * @param _owner          权限所有者
   * @param _actor          代表所有者行事的行为者
   * @param _required       所需的权限集
   */
  function hasPermission(address _owner, address _actor, uint256 _required) external view returns (bool isPermissioned);

  /**
   * 返回授予 `_delegatee` 地址的 `_owner` 地址的权限子集。
   * @param _owner          权限所有者
   * @param _delegatee      被委托者
   */
  function delegated(address _owner, address _delegatee) external view returns (uint256 permission);
}

元数据接口

建议符合规范的合约实现可选扩展 IEIP6617Meta

应该为基本权限和主要组合定义描述。

不应该为每个可能的权限子组合定义描述。

错误接口

兼容的 token 可以实现如下定义的 IEIP6366Error

interface IEIP6366Error {
  /**
   * 所有者或行为者没有所需的权限
   */
  error AccessDenied(address _owner, address _actor, uint256 _permission);

  /**
   * 权限集之间的冲突
   */
  error DuplicatedPermission(uint256 _permission);

  /**
   * 数据超出范围
   */
  error OutOfRange();
}

理由

需要讨论。

参考实现

第一个实现可以在这里找到:

安全注意事项

需要更多讨论。

版权

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

Citation

Please cite this document as:

Chiro (@chiro-hiro), Victor Dusart (@vdusart), "ERC-6366: 权限 Token [DRAFT]," Ethereum Improvement Proposals, no. 6366, January 2022. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-6366.