Alert Source Discuss
⚠️ Review Standards Track: ERC

ERC-6617: 基于位的权限

一个基于位的权限和角色系统

Authors Chiro (@chiro-hiro), Victor Dusart (@vdusart)
Created 2023-02-27

摘要

这个 EIP 提供了一个用于构建基于位的权限和角色系统的标准。每个权限由单个位表示。通过使用 uint256,可以定义最多 $256$ 个权限和 $2^{256}$ 个角色。我们能够基于位的顺序来指定每个权限的重要性。

规范

本文档中的关键词 “MUST”,“MUST NOT”,“REQUIRED”,“SHALL”,“SHALL NOT”,“SHOULD”,“SHOULD NOT”,“RECOMMENDED”,“NOT RECOMMENDED”,“MAY” 和 “OPTIONAL” 应按照 RFC 2119 和 RFC 8174 中的描述进行解释。

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

参考接口描述如下:

pragma solidity ^0.8.7;

/**
    @title EIP-6617 基于位的权限
    @dev 参见 https://eips.ethereum.org/EIPS/eip-6617
*/
interface IEIP6617 {

    /**
        当权限被授予时必须触发。
        @param _grantor        权限授予者
        @param _permission     被授予的权限
        @param _user           接收权限的用户
    */
    event PermissionGranted(address indexed _grantor, uint256 indexed _permission, address indexed _user);

    /**
        当权限被撤销时必须触发。
        @param _revoker        权限撤销者
        @param _permission     被撤销的权限
        @param _user           失去权限的用户
    */
    event PermissionRevoked(address indexed _revoker, uint256 indexed _permission, address indexed _user);

    /**
        @notice 检查用户是否拥有权限
        @param _user                需要检查权限的用户的地址
        @param _requiredPermission  所需的权限
        @return                     如果 _permission 是 _requiredPermission 的超集,则返回 True,否则返回 False
    */
    function hasPermission(address _user, uint256 _requiredPermission)
        external
        view
        returns (bool);

    /**
        @notice 向用户添加权限
        @param _user                将要添加权限的用户的地址
        @param _permissionToAdd     将要添加的权限
        @return                     包含 _permissionToAdd 的新权限
    */
    function grantPermission(address _user, uint256 _permissionToAdd)
        external
        returns (bool);

    /**
        @notice 撤销用户的权限
        @param _user                将要撤销权限的用户的地址
        @param _permissionToRevoke  将要撤销的权限
        @return                     不包含 _permissionToRevoke 的新权限
    */
    function revokePermission(address _user, uint256 _permissionToRevoke)
        external
        returns (bool);
}
  • 兼容的合约必须实现 IEIP6617
  • 一个兼容的合约中的权限表示为一个 uint256。一个权限必须只占用一个 uint256 的一位,因此必须是 2 的幂。每个权限必须是唯一的,并且 0 必须用于表示没有权限。

元数据接口

建议兼容的合约实现可选的扩展 IEIP6617Meta

  • 它们应该为基本权限和主要组合定义名称和描述。

  • 它们不应该为所有可能的权限子组合定义描述。

/**
 * @dev 定义了 EIP6617 元数据的接口,可以不实现
 */
interface IEIP6617Meta {
    
    /**
        权限描述的结构体
        @param _permission     权限
        @param _name           权限的名称
        @param _description    权限的描述
    */
    struct PermissionDescription {
        uint256 permission;
        string name;
        string description;
    }

    /**
        当描述更新时必须触发。
        @param _permission     权限
        @param _name           权限的名称
        @param _description    权限的描述
    */
    event UpdatePermissionDescription(uint256 indexed _permission, string indexed _name, string indexed _description);

    /**
        返回给定 `_permission` 的描述。
        @param _permission     权限
    */
    function getPermissionDescription(uint256 _permission) external view returns (PermissionDescription memory description);

    /**
        如果描述被设置则返回 `true`,否则返回 `false`。它必须触发 `UpdatePermissionDescription` 事件。
        @param _permission     权限
        @param _name           权限的名称
        @param _description    权限的描述
    */
    function setPermissionDescription(uint256 _permission, string memory _name, string memory _description)
        external
        returns (bool success);
}

动机

目前,权限和访问控制是使用单个所有者 (ERC-173) 或使用 bytes32 角色 (ERC-5982) 来执行的。 然而,使用位运算和位掩码操作可以提高 gas 效率和灵活性。

Gas 成本效率

位运算非常便宜且快速。例如,对权限位掩码执行“与”位运算比调用任意数量的 LOAD 操作码便宜得多。

灵活性

有了 uint256 的 256 位,我们可以创建多达 256 种不同的权限,这将产生 $2^{256}$ 种独特的组合(又名角色)。 (角色是多个权限的组合)。 并非所有角色都必须预先定义。

由于权限被定义为无符号整数,我们可以使用二进制 OR 运算符来创建基于多个权限的新角色。

按重要性排序权限

我们可以使用最高有效位来表示最重要的权限,权限之间的比较可以很容易地完成,因为它们都是 uint256

关联含义

与通过 ERC-5982 管理的访问控制相比,此 EIP 不提供对权限或角色含义的直接和简单的理解。

为了解决这个问题,您可以设置元数据接口,该接口将名称和描述与每个权限或角色相关联。

参考实现

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

安全考虑

无安全考虑。

版权

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

Citation

Please cite this document as:

Chiro (@chiro-hiro), Victor Dusart (@vdusart), "ERC-6617: 基于位的权限 [DRAFT]," Ethereum Improvement Proposals, no. 6617, February 2023. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-6617.