ERC-7546 可升级克隆:把合约拆成状态、字典和逻辑三份
EVM 里的合约账户其实由四样东西拼成:nonce、余额、字节码、存储。绝大多数合约把后两样焊死在同一个地址里,于是升级逻辑等于搬家,历史数据要么迁移要么封存。ERC-7546(Upgradeable Clone for Scalable Contracts)把这三样东西拆到三类合约里各管一段:代理合约守住状态与余额,字典合约当调度台按函数选择器指路,函数合约装真正的执行逻辑。按以太坊 ercs 仓库的记录,提案状态为 Draft,创建于 2023 年 10 月 25 日。
一次调用的旅程与那个固定存储槽
用户把交易发给代理合约。代理不含业务逻辑,它先去找字典合约:按 calldata 前四字节的选择器问“这个函数该交给谁”,拿到地址后 delegatecall 过去——关键点在 delegatecall 的语义:逻辑代码在代理的存储上下文里执行,读写的都是代理账户的数据,函数合约自己不落任何状态。字典合约因此成为整套架构的枢纽:它维护选择器到实现合约的映射,改映射就是升级,还能按标准发出 ImplementationUpgraded 与 DictionaryUpgraded 事件留下痕迹。为了让外部工具不用猜,标准约定代理合约应把字典地址存放在一个固定推导的存储槽里,查询者对着字节码和槽位值就能还原调度链。字典被单独拆出来的另一层好处是复用:克隆工厂可以部署一万个共享同一本字典的代理,升级字典等于给所有克隆同时换逻辑,这就是标题里“可升级克隆”的来由。

对 NFT 项目意味着什么,读合约时看哪里
安全考虑还有两个专节值得展开。字典管理权的信任假设写得很重:整套代理把每个调用的实现选择权都托付给字典合约的管理者,标准明确警告不要接不受信任管理者的字典,并建议实现保留切换到另一本字典的能力;但有个反直觉细节——把字典地址用不可变变量或常量硬编码进代码看似更安全,一旦字典管理方与代理管理方不是同一批人,更换实现的能力可能被永久锁死。存储冲突是另一根弦:多份函数合约共享同一份代理存储,两个实现不约而同动同一槽位就是事故现场,布局纪律只能靠约定与审计维持,编译器帮不了这个忙。
与普通透明代理、钻石模式放在一起,这套三合约架构的定位会更立体:透明代理升级简单但每次影响一个地址;钻石类方案按功能切分实现,但切分逻辑固化在每份代理里;7546 把路由表独立成共享字典,用一次换表推动成千上万个克隆,走的是“批量运维”路线。读法也跟着变:面对任意一个此类代理地址,正确的问题不再是它背后实现是什么版本,而是它指向的字典是哪一本、那本字典归谁管。项目方做尽调说明时,字典地址与治理方式其实应当像合约地址一样写进第一行。
批量发系列的 NFT 项目是这类架构的天然用户:每个系列一个轻量代理守持仓与授权数据,共享一个字典和一组函数合约,发新系列的 gas 被压到接近一次克隆创建。但读者要习惯新的核验路径:在区块浏览器上,这类地址的字节码很短,看到的“合约”其实只是个转发壳,真正的逻辑要顺着固定槽找字典、再按选择器找函数合约才能读到源码级审计对象。安全面也随之变形——字典地址的 setter 若掌握在一个单签管理员手里,等于一个人可以随时给一万个系列集体换逻辑;检查这类项目时,setImplementation 一类接口的权限归属、字典是否多签或时间锁治理,比函数实现本身的写法更值得先看。标准同时要求实现合约通过 supportsInterfaces 自报支持的接口,供 ERC-165 式探测。拆分换来了可维护性,也把信任从“代码即规则”部分移回“治理即规则”,这是读这类合约时最需要记住的视角切换。本文为机制说明,不构成任何投资建议。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。