合约升级不再搬数据:ERC-1504 的 Handler 与 Data 两段拆分 图 1
合约升级不再搬数据:ERC-1504 的 Handler 与 Data 两段拆分 · 图 1

合约升级不再搬数据:ERC-1504 的 Handler 与 Data 两段拆分

智能合约部署后不可更改,但代码会出漏洞。ERC-1504 的动机部分从历史讲起:过去几年以太坊合约出过安全问题,修复代价高昂,它点名 2016 年 6 月的 DAO 事件造成巨大资金损失并以硬分叉收场,结论是协议级的补救太重,应该在合约结构上留出修补通道。文档创建于 2018 年 10 月 17 日,仓库记录状态为 Stagnant,属于长期无人推进的归档方案。

三层结构各管一摊

这份设计把合约切成三个部分。第一部分 Handler 合约,实现一份 Handler 接口,定义业务操作、提供服务,它是唯一允许被换掉的部分。第二部分 Data 合约,保存数据、由 Handler 控制,常驻不动。第三部分 Upgrader 合约,可选组件,内置投票机制负责换 Handler,投票人名单由合约属主预先设定。原文给的例子很直白:一只 ERC-20 代币合约被用户发现漏洞,没有升级设计的团队要么部署新合约搬家、要么带着漏洞硬扛;有了这套结构,只需要换 Handler,Data 合约原地不动,余额账本一行都不用迁移——搬家风险从升级流程里被整个删除。三层各自有配套的权限机关:Data 合约一侧挂着 onlyHandler、allowedAddress、ready 等修饰符,分别管住“只有当前生效逻辑能动数据”“名单内地址才碰得到敏感入口”“系统就绪才开门”,把拆分后的职责边界钉在语法层面,而不是靠文档约定。

合约升级不再搬数据:ERC-1504 的 Handler 与 Data 两段拆分 图 2
合约升级不再搬数据:ERC-1504 的 Handler 与 Data 两段拆分 · 图 2

接口里的两个自检机关

Handler 接口的注释解释了一个实现细节:正因为有 live 函数,IHandler 被设计成抽象合约而不是真正的接口。函数清单里,initialize(string _str, uint256 _int, uint16[] _array) 供数据合约一次性初始化结构;registerUpgrader(address)isUpgraderRegistered() 维护升级代理的登记关系;done() 标记阶段完成。Handler 侧的 live() 返回布尔,作为“我是当前生效逻辑”的自检——数据合约在处理任何调用前查一下当前 Handler 是否 live,被替换下来的旧逻辑就再也指挥不动数据。这一问一答是整个拆分设计的安全阀:换逻辑的成败不靠约定,靠数据层主动核验。

升级流程:提案期、预设投票人、状态机

数据合约侧的写路径收敛到 setHandler(address _handlerAddr, address _originalHandlerAddr),且带 onlyHandler 类修饰符;进入升级轨道的入口是 startUpgrading(address _upgraderAddr)。Upgrader 合约暴露一组治理参数:getProposalPeriodsetProposalPeriod 读写提案期长度,注意规范给这对函数加了 allowedAddress 之类的修饰符——能看和能改提案期的名单同样由合约控制;canBeUpgraded(address) 返回一个升级状态枚举,回答目标逻辑当前是否可替换;Upgrader 自身还有 startProposal()getResolution() 驱动提案与裁定。

把这条链读顺,会看到这份 2018 年方案的信任假设相当集中:投票人由属主预设,谁能升级 Handler 本质上是一条属主写的名单。文档末尾还留了一句坦白:示例里的投票机制是最简版本,属主想更复杂可以自行改造,但过期机制(Upgrader 合约里的 notExpired 修饰符及配套函数)和升级校验被明确标为强制项——即便治理可以换皮,防陈旧提案生效的闸门不许拆。它防住的是“无人掌舵时逻辑被悄悄换掉”,防不住“属主名单本身作恶”。

和今天代理模式的对照

ERC-1504 没有走出来,主流升级路线收敛到代理合约形态:常驻代理保存数据或指向逻辑,升级是改指针,治理形态则分裂成管理员直改、时间锁与多签三类。对照读这份归档文本有三个现成的用途。其一,判断一个合约“可升级”到底可升级什么:是仅逻辑可换(本提案与代理模式),还是数据也能被迁移或清空——数据可动的升级,安全含义完全不同。其二,核查被换逻辑的失效手段:本设计靠数据层每笔查 live,常见代理模式靠代理指向,两者都要求用户侧工具去读代理合约而不是旧地址。其三,看升级门禁:属主预设名单、开放投票还是时间锁延迟生效。DAO 事件的教训在规范里被引用,但它给出的解法提醒的是另一层:升级机制解决的是修复速度问题,权力归谁永远是另一个独立问题。本文为机制说明,不构成任何投资建议。