ERC-5982 角色权限接口:合约里的角色怎么创建、授予和撤销
很多链上事故复盘到最后,问题不在代码逻辑,而在”谁有权调用这个函数”:升级函数握在一个早已离职的多签手里,暂停权限被发给了一个遗忘在配置文件里的热钱包。传统的做法是每个项目自己发明一套 owner 加一堆 bool 开关,权限地图散落各处。ERC-5982 尝试把权限整理成标准的角色账本:角色是一个 bytes32 标识,人和角色的关系、角色和函数的关系都用统一函数查询。按照以太坊 ercs 仓库的记录,这份提案状态为 Review,创建于 2022 年 11 月 15 日。
一份接口拆成三个子协议
标准把接口切成三块。核心接口 IERC_ACL_CORE 管基本关系:hasRole(role, account) 查某人是否拥有某角色,grantRole 与 revokeRole 负责授予和收回。通用接口 IERC_ACL_GENERAL 是完整操作面:createRole 与 destroyRole 负责角色的生与死,setRolePower 把角色与 bytes4 函数选择器绑定,canExecute(executor, method, payload, data) 回答”这个角色能不能调用这个函数”——标准原文明确角色权限的语义就是围绕函数选择器定义的,这让权限从抽象头衔变成了具体到函数的白名单;canGrantRole 与 canRevokeRole 则把”谁有资格授予或收回某角色”本身也变成可查询的权限。元数据接口 IERC_ACL_METADATA 给角色配了 roleName、roleDescription、roleURI 三个可读字段,让权限账本至少在人读层面不再是一串十六进制。

五种事件构成权限审计的时间线
标准定义了 RoleCreated、RoleDestroyed、RoleGranted、RoleRevoked、RolePowerSet 五种事件。审计一个合约的权限史,方法就是按事件重放:什么时候创建了什么角色、哪个地址在哪个区块被授予、又在什么时候被收回。与只写 OwnerChanged 一个事件的旧式合约相比,角色模型的最大好处是权限变动可以做到”最小颗粒度可追溯”——你能精确回答”暂停功能在事故区块之前由三个地址持有,其中一个是三个月前授予的”这类问题,而不用翻治理论坛考古。
查权限的实际路径
拿到一个合约,按 ERC-5982 的接口可以这样走:先对敏感函数(升级、铸造、暂停、提取)逐个用 canExecute 结合候选角色做笛卡尔查询,列出”函数到角色”的映射;再用 hasRole 把每个角色反查到人,得到”角色到地址”的映射;两层拼起来就是完整权限地图。合约如果同时实现了元数据接口,roleName 和 roleDescription 能把这轮查询的结果直接翻译成人话。对没有实现这套标准的合约,同样的动作要退化成读代码加翻事件,工作量数倍增长——这正是标准化的意义。
权限查询的一次完整演练
拿一个声明支持该标准的治理合约举例:运营者先 createRole 建出金库、升级、暂停三类角色,用 setRolePower 把提取函数、代理切换函数、紧急暂停函数分别绑给对应角色,再把成员地址逐一分派。此后任何人做尽调都不需要读源码——遍历候选角色查 canExecute,再对每个角色跑 hasRole,两张查询表一拼接,“谁在什么条件下能动哪笔钱”就摊在明面上。标准甚至在 canGrantRole 一类函数里预留了委托授予的判定:某地址能否把某角色授给别人,本身也是链上可查询的权限,而非口口相传的惯例。
标准化的权限不等于安全的权限
两点提醒。其一,bytes32 角色标识意味着角色本身没有名字约束,一个名为”零号角色”的东西可能是核心管理员也可能是历史遗留,可读性要靠元数据接口和维护纪律兜底。其二,接口标准只解决”查得到”,不解决”配得对”:过宽的角色配置、销毁角色后残留的 power 映射、grantRole 权限本身没被保护,都是标准管不了的实现缺陷。按 ercs 仓库口径,ERC-5982 处于 Review 阶段,尚未定稿,主流合约权限库仍以 Ownable 与 AccessControl 变体居多,查权限时先确认目标合约实现了哪个版本的接口再逐项调用。本文为机制说明,不构成任何投资建议。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。