ERC-8167 分发代理:按函数选择器把调用路由给各模块
一个 NFT 项目长大了,铸造逻辑、版税逻辑、质押逻辑挤在一个合约里会撞代码体积上限,还牵一发动全身。模块化代理是解法之一:用户地址不变,调用进来后按函数选择器分发给不同的逻辑模块。钻石代理(ERC-2535)把这件事做得很完整也很重,ERC-8167 则走了另一条路——一个尽量小的分发代理标准,让工具至少能回答”这个函数选择器现在由哪个地址执行、历史上换过没有”。按 ercs 仓库记录,这份提案创建于 2026 年 2 月 16 日,状态 Last Call,是目前这条路线上流程最靠前的极简方案。
接口小到只有两个函数
提案的查询面只有两个:selectors(bytes4 selector) 返回给定函数选择器的 (address implementation, bytes32 facet),即当前由哪个实现地址执行、归属哪个模块标识;implementation(address) 反向返回某模块当前被委托的选择器列表与模块标识。写侧是事件 SelectorDelegated:每个选择器被委托或改道时都会发出记录,把目标地址与 facet 一并入日志。提案有意不提供批量变更的复杂状态机——一次委托一笔事件,历史即日志,审计时把事件流重放一遍就能还原任何时点的路由表。代理收到调用时按当前路由表把 calldata 原样转发给对应实现地址,返回值原路带回;未路由的选择器直接 revert,避免落到某个兜底函数里悄悄执行。

与钻石、Beacon 代理的分工
三者解决同一类问题,信任结构不同。ERC-1967 透明代理或 UUPS 是一整块实现合约整体换版;Beacon 代理把版本指针集中到一个信标合约,一批代理一起升级;钻石用 facet 与选择器登记表支持细粒度多模块拼装,接口和工具链最丰富也最复杂。ERC-8167 站到中间位置:保留”按选择器分模块”的粒度,只承诺最小可审计性——没有注册表合约、没有分组权限模型、没有升级队列。对小团队与 NFT 项目这种”几个模块分家、审计预算有限”的场景,这份接口便宜且够用;代价是提案不规定路由权的转让流程,治理规则全在项目自己的实现里,持有人要把这部分当自定义代码逐行看。
把这条核验路线与钻石代理时代对比着记,会更容易形成本能。ERC-2535 时代审计一个 Diamond 合约,要拉出 diamondLoupe 类枚举与登记结构,确认每个选择器只被登记一次、没有落在默认回退里的暗函数,工具链不熟的人常被 facet 术语劝退。ERC-8167 把同样的问题缩窄成两个只读函数加一条事件流,代价是治理能力被让渡给项目自写代码:谁有权改路由、改路由要不要时间锁、批量换模块能不能原子生效,标准一律不管。于是一个微妙的取舍浮出水面——标准越薄,实现方自由度越大,持有人的检查负担越具体。务实的验收姿势是把它当”带说明书的半成品”:先跑通两个查询证明路由透明,再逐条追问路由权的归属与约束,最好看到变更被时间锁或治理合约接管。若一个 NFT 项目用分发代理但答不出”升级由谁批准”,它至少暴露了一个比代码更根本的问题:模块可以换人,规则却没人管。
持有人视角的核验清单
遇到使用分发代理的 NFT 合约(合约地址与铸造页看起来”一切正常”,背后可能是七八个模块),值得按接口逐项自查:先调 selectors 问几个关键函数(mint、setApprovalForAll、版税相关)当前指向哪个实现地址,再打开那个地址看源码是否验证、是否与项目方公布的模块清单一致;用 implementation 反查各模块,确认没有未声明的暗模块在路由表里挂着;追一遍 SelectorDelegated 事件历史,比对已发生的路由变更是否与公开公告、治理投票对得上。三问全部干净,模块化对你是透明层;任何一问含糊——比如选择器指向未验证合约、事件里有无法解释的改道记录——都说明升级治理没被约束,届时”合约不可升级”的宣传和现实之间就存在缺口,需要主动把风险计入。本文为机制说明,不构成任何投资建议。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。