Alert Source Discuss
⚠️ Review Standards Track: ERC

ERC-5982: 基于角色的访问控制

智能合约中基于角色的访问控制接口。

Authors Zainan Victor Zhou (@xinbenlv)
Created 2022-11-15
Requires EIP-165, EIP-5750

摘要

本 EIP 定义了智能合约中基于角色的访问控制的接口。角色被定义为 byte32。该接口指定了如何读取、授予、创建和销毁角色。它以调用给定方法的能力的形式指定了角色权限的意义,该方法由 bytes4 方法选择器标识。它还指定了如何表示角色的元数据。

动机

有很多方法可以为特权操作建立访问控制。一种常见的模式是“基于角色”的访问控制,其中一个或多个用户被分配到一个或多个“角色”,这些角色授予对特权操作的访问权限。这种模式比基于所有权的访问控制更安全、更灵活,因为它允许根据最小权限原则向多人授予权限。

规范

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

参考接口描述如下:

interface IERC_ACL_CORE {
    function hasRole(bytes32 role, address account) external view returns (bool);
    function grantRole(bytes32 role, address account) external;
    function revokeRole(bytes32 role, address account) external;
}
interface IERC_ACL_GENERAL {
    event RoleGranted(address indexed grantor, bytes32 indexed role, address indexed grantee, bytes _data);
    event RoleRevoked(address indexed revoker, bytes32 indexed role, address indexed revokee, bytes _data);

    event RoleCreated(address indexed roleGrantor, bytes32 role, bytes32 adminOfRole, string name, string desc, string uri, bytes32 calldata _data);
    event RoleDestroyed(address indexed roleDestroyer, bytes32 role, bytes32 calldata _data);
    event RolePowerSet(address indexed rolePowerSetter, bytes32 role, bytes4 methods, bytes calldata _data);

    function grantRole(bytes32 role, address account, bytes calldata _data) external;
    function revokeRole(bytes32 role, address account, bytes calldata _data) external;

    function createRole(bytes32 role, bytes32 adminOfRole, string name, string desc, string uri, bytes32 calldata _data) external;
    function destroyRole(bytes32 role, bytes32 calldata _data) external;
    function setRolePower(bytes32 role, bytes4 methods, bytes calldata _data) view external returns(bool);

    function hasRole(bytes32 role, address account, bytes calldata _data) external view returns (bool);
    function canGrantRole(bytes32 grantor, bytes32 grantee, bytes calldata _data) view external returns(bool);
    function canRevokeRole(bytes32 revoker, bytes32 revokee, address account, bytes calldata _data) view external returns(bool);
    function canExecute(bytes32 executor, bytes4 methods, bytes32 calldata payload, bytes calldata _data) view external returns(bool);
}
interface IERC_ACL_METADATA {
    function roleName(bytes32) external view returns(string);
    function roleDescription(bytes32) external view returns(string);
    function roleURI(bytes32) external view returns(string);
}
  1. 兼容合约必须实现 IERC_ACL_CORE
  2. 建议兼容合约实现可选扩展 IERC_ACL_GENERAL
  3. 兼容合约可以实现可选扩展 IERC_ACL_METADATA
  4. 兼容智能合约中的角色以 bytes32 的格式表示。建议此角色的值计算为角色名称字符串的 keccak256 哈希值,格式如下:bytes32 role = keccak256("<role_name>")。例如 bytes32 role = keccak256("MINTER")
  5. 兼容合约应该实现 ERC-165 标识符。

原理

  1. 选择 IERC_ACL_CORE 中方法的名称和参数是为了允许与 OpenZeppelin 的实现向后兼容。
  2. IERC_ACL_GENERAL 中的方法符合 ERC-5750 以允许扩展。
  3. renounceRole 方法未被采纳,而是与 revokeRole 合并以简化接口。

向后兼容性

需要讨论。

安全注意事项

需要讨论。

版权

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

Citation

Please cite this document as:

Zainan Victor Zhou (@xinbenlv), "ERC-5982: 基于角色的访问控制 [DRAFT]," Ethereum Improvement Proposals, no. 5982, November 2022. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-5982.