一个自带金库的智能合约
2016 年春天,一个叫 The DAO 的链上基金在以太坊上众筹上线:持有者用 ETH 换取 DAO 代币,凭代币对投资项目投票。它没有公司、没有经理,规则全部写在合约里,上线数周聚拢了当时看规模惊人的上千万 ETH。支撑它的信念很纯粹:代码即规则,链上状态不可篡改。
6 月,研究者发现这个合约的提现逻辑存在“重入”缺陷:提取函数在更新内部余额之前就把控制权交回给调用方,攻击者可以在同一个调用里反复进入提取步骤,把同一个余额反复“取出”。攻击者利用这个缺陷持续抽走资金。当时的以太坊尚年轻,链上第一次出现如此大额的失窃,社区被迫直面一个从没认真想过的问题:如果合约写错了,账本能不能改?
摊牌:回滚还是不回滚
社区的讨论最终收成两派。一派认为应该硬分叉,把被转走的资金恢复到攻击前的状态——技术上这很直接:让所有节点在某个高度执行一次约定的状态变更,把 The DAO(包括攻击者控制的地址)里的资金集中转入一个退款合约,原持有者之后可以按快照领回。另一派认为这等于推翻了“链上记录不可篡改”的立身之本,今天能回滚失窃,明天就能回滚任何不合心意的交易。经过密集辩论与社区投票性质的表态,支持回滚的一方占优。2016 年 7 月 20 日(UTC),高度 1,920,000 块执行了这次“非常规状态变更”,约一千二百万 ETH 从相关合约移入退款合约——这个数字与事后统计的攻击者所得和白帽提取额大体对应,以太坊基金会当时的公告也给出了同一口径。
分叉之后:一条链变成两条链
关键细节常被忽略:硬分叉只改变了“升级客户端的那条链”的规则。绝大多数矿工接受新规则继续出块,这就是今天以太坊主线的前身;拒绝升级的一派继续按旧规则挖原样的链,最初称作“经典链”,后来定型为以太坊经典(ETC),两条链从分叉高度起永久分家。这给所有人上了一堂直观的课:硬分叉不是把账本改掉,而是让同意的人分出去另起一本账——“回滚”的本质是多数人带着原始历史去了一条新链,而被丢弃的那本账本并没有消失。
留给行业的三样东西
第一,漏洞类型的教科书:重入攻击此后成为智能合约审计的头号基础题,防护模式(先改状态再转账、或使用互斥锁)写进了每一本合约开发指南。第二,治理先例:链上损失能否被链下协调修复,从此有了可引用的判例,支持者的底线是“由社区协调、公开透明、只处理这一事件”,反对者的担忧是“先例一开,边界难守”。第三,身份认同实验:同一段历史长出两条链、两种价值观,各自存续至今,在加密史上独一无二。回头看,The DAO 事件的技术含量其实不高,真正改变行业的是它把“不可篡改”从一个物理定律式的口号,变成了一个需要说明边界的制度承诺。
快速问答
当时被偷的币后来怎么处理? 退款合约里的资金按持币快照返还给了 The DAO 代币持有者。重入攻击还能再发生吗? 老式写法仍可能中招,现代合约框架已把防护内置,但“先扣钱后转账”类逻辑错误依然时常出现在审计报告里。
常见误区
第一,把 7 月 20 日的分叉说成“把交易从账本里删掉”——更准确的描述是多数节点在同一高度执行约定的状态变更,选择守旧的那条链上原交易从未消失,两种说法对应完全不同的世界观。第二,把以太坊经典当“测试网残骸”——它此后持续独立出块多年,是一条活着的平行链。第三,把重入漏洞归咎于“智能合约天生不安全”——缺陷出在这份合约把转账放到了改账之前,同一平台后来跑着成千上万份正确处理顺序的合约。
风险提示:本文为历史与机制梳理,不构成投资建议;智能合约存在代码漏洞等技术风险,与任何合约交互前请独立评估。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。