权限登记放上一张公共表:ERC-7820 访问控制注册表的用法 图 1
权限登记放上一张公共表:ERC-7820 访问控制注册表的用法 · 图 1

权限登记放上一张公共表:ERC-7820 访问控制注册表的用法

项目方管理合约权限的传统方式是“谁家的孩子谁管”:每个合约各自带一份角色表,链外工具想知道“这条 NFT 线谁能暂停、谁能改元数据”,就要逐合约逐角色去翻事件。ERC-7820 访问控制注册表(Access Control Registry)把登记这件事抽出来:一份公共合约记录哪些合约选择入表、每个合约的管理员是谁、角色发给了谁。标准状态为 Final,创建于 2024 年 11 月 19 日。

一张表的动作清单

接口分两组。登记组:registerContract(_admin) 把一个合约挂进注册表并指定它的管理员地址,unRegisterContract(_contract) 把不再使用的合约摘除登记;标准明确要求拒绝把零地址注册进来。查询组:getContractInfo(_contract) 返回该合约是否处于激活状态及其管理员地址——合约不存在时查询必须回退,所以“回退还是返回假”本身能区分“从未注册”与“注册后注销”。授权组是这套标准最有辨识度的设计:grantRolerevokeRole 的参数都是数组——targetContractsrolesaccounts 三条列表并列,一次调用可以跨多个合约给多个账户发或收多个角色,文档把这定为减少 gas 与简化大型系统角色分配的批处理设计。四个动作各有事件:ContractRegisteredContractUnregisteredRoleGrantedRoleRevoked,把每一次权限交接留在链上。

权限登记放上一张公共表:ERC-7820 访问控制注册表的用法 图 2
权限登记放上一张公共表:ERC-7820 访问控制注册表的用法 · 图 2

没有中央 owner:注册表自己的权力观

安全考量一节有一句话值得反复读:没有中央 owner 可以替别人注册合约——设计选择是去中心化登记,每个合约对自己的注册与管理负责;合约自己调用 registerContract 入表,其管理员(表里记录的 admin 地址)通过 onlyAdmin 类修饰器行使授权权。换句话说,这份注册表不是“权限的发行局”,而是“权限的自我公示处”:它降低的是观察成本,不是信任成本。由此产生一个必须写进尽调清单的事实:一个合约可能压根不在这张表里,也可能登记与实际执行脱节——登记表管的是“申报”,真正的放行判断仍发生在各合约自己的代码里。

对 NFT 生态的含义很具体:一个多合约项目(铸造、市场对接、版税、升级代理各一个合约)把全家都登记进来后,“这个多签在生态里持有哪些角色”“某个升级角色过去一年在几个合约间流转”这类问题,从逐合约考古变成一次按表查询加事件回放;RoleGranted/RoleRevoked 的时间序列还是发现异常的最便宜探针——例如升级角色突然被授予一个从没出现过的地址,值得立刻警觉。

使用建议与局限

如果你是参与者,最实用的动作:找到项目公布的注册表合约地址(与仿冒地址严格区分),用事件历史画一张权限地图——哪些合约注册、每个关键角色当前归谁、注销记录是否异常。查不到的合约不代表没有权限,只代表它没来这里公示,两类都要标注。局限也要说明:接口只有查询与授权,没有“角色语义”的定义——role 是 bytes32 的自由值,暂停权、版税权、升级权全靠各项目自己约定哈希;跨生态不存在统一的角色命名空间,横向对比不同项目时要先看各自的角色说明文档。

标准给这件事下了个恰切的定位:标准化的不是权限本身,而是关于权限的元数据登记。读得懂登记,你就有了一张随时更新的生态控制面草图;但别把草图当安全证书。

批量接口还提醒一件事:grantRolerevokeRole 的三个数组参数要求长度对齐、语义一一对应,跨合约批量发牌时配错顺序,等于把甲合约的权限发给乙合约的账户——治理脚本提交前应当在测试网用同参数预演,逐条核对 RoleGranted 事件的三元组,再上主网。 最后提醒:本文讲权限登记机制,不构成投资建议;判断控制权以合约实际逻辑与事件历史为准,所有地址以项目官方公布为源头。