ERC-927 通用授权:把“谁能动我的资产”集中到一个合约里问 图 1
ERC-927 通用授权:把“谁能动我的资产”集中到一个合约里问 · 图 1

ERC-927 通用授权:把“谁能动我的资产”集中到一个合约里问

你授权某个市场动用你的一枚 NFT,用的可能是 ERC-721 的 approve;你在 ENS 里允许某个地址管理域名,用的是另一套接口;再换一个协议,又是第三套写法。2018 年 3 月 12 日,Nick Johnson 提交了 ERC-927,提议把所有“允许第三方代我办事”的判定收敛成一个通用问题。按 ercs 仓库记录,这份标准状态为 Stagnant。

canCall:一次询问四个参数

核心函数只有一个:canCall(owner, caller, callee, func)。owner 是资源的主人,caller 是当下发起调用的地址,callee 是被调用的合约,func 是被调用函数的四个字节签名。标准的例子很具体:Alice 授权 Bob 替她转代币,Bob 动手那一刻,Alice 是 owner,Bob 是 caller,代币合约是 callee,transfer 的函数签名是 func。提供方合约回答真或假。授权判定从“分散在每个代币合约的映射里”变成“集中问一次”。

ERC-927 通用授权:把“谁能动我的资产”集中到一个合约里问 图 2
ERC-927 通用授权:把“谁能动我的资产”集中到一个合约里问 · 图 2

登记表怎么被查询

ERC-927 建在 ERC-926 的地址元数据登记处之上,流程分两步:被调合约先到固定地址的登记表查出 owner 的元数据提供者,再调那个提供者的 canCall。返回假,被调合约就撤销执行。对普通账户而言,这是它们第一次不用部署任何代码,就能对“谁能替我干什么”给出可编程的回答。

授权与撤销的推荐接口

标准建议提供者实现一对函数供用户管理:authoriseCaller 建立授权、revokeCaller 撤销,参数含义与 canCall 相同。硬性要求是:调用者必须是 owner 本人,或者已被 owner 授权代为管理授权关系;当 owner 恰好等于 msg.sender 时这条必须天然成立。一个容易被忽视的语义:func 传零表示对 callee 全部函数的总括授权;若以“假值加零函数”调用撤销,只需清掉总括授权,针对单个函数的授权可以保留。这个设计与 OAuth 的委托思路一脉相承,标准自己也写明灵感来自 ds-auth 和 OAuth。

盲区在哪里

为什么值得再读一遍这份没落地的设计

动机部分把痛点说得很具体:智能合约几乎都需要“让第三方替用户做事”的入口——代币授权有 ERC-20 的 approve 和 ERC-777 的 operator,ENS 域名管理又是自定义的一套,每种标准各自重造同一套轮子,工具链于是永远凑不齐一张完整的授权视图。ERC-927 的答案是把这些判定收拢进元数据提供者,配合 ERC-926 的登记处,理论上任何合约在放行前都会先问同一张表。

按原文的编号流程重走一遍:被调合约第一步去固定地址的登记表查 owner 的提供者,第二步带着四参数问 canCall,返回假就撤销执行。标准对被调方只要求这一个动作,其余复杂度全部推给提供者一侧;而提供者要给用户用的 authoriseCallerrevokeCaller 被写成 SHOULD 而非 MUST,意思是“大家都该有”,但严格读来不提供也行。权限校验那句要求写得最硬:实现方必须确保 msg.sender 有权代 owner 改授权,owner 亲自调用时该条件恒真,其他代理者则要用同一套标准自查。全零函数签名的授权开关也留了不对称:授权时 func 为零放行 callee 的一切函数,撤销时传零只清总括授权、单点授权继续有效——想彻底断干净,就得逐函数逐个撤。

集中判定省掉了每个协议重造轮子,也带来新的信任点:提供者合约成了授权体系的心脏,它出错或被劫持,所有依赖它的被调合约一起失守。查询多两跳合约调用,Gas 与延迟都是成本;登记表本身当年并未成为标配。这份提案的示例实现一栏写的是“待补充”,也侧面解释了它为什么停在 Stagnant。它能说明的是一种授权接口的组织方式,不能说明任何一份具体授权是否安全。检查自己的授权敞口,仍要回到每条链、每个市场的实际 approve 记录逐项处理。本文为机制说明,不构成任何投资建议。