打钱的姿态,决定了危险是否发生
以太坊的转账不是原子点钞机:从合约向外转 ETH,用的是 CALL 类机制,钱进对方账户的同时,对方合约里的接收逻辑也会被立刻执行——哪怕你根本没打算让它跑任何代码。恶意合约正是利用这个”顺手执行”,在接收 ETH 的瞬间回调转出方,制造重入事故(机制详见 重入攻击是什么?智能合约如何被“先取钱后记账”掏空)。EIP-5065 在 2022 年 4 月 30 日提交,瞄准的就是这个耦合:提案要求新增一条指令,只把 ETH 从一个账户挪到另一个账户,绝不把执行流交给收款方。状态至今 Stagnant。它的动机部分有句话很值得引用:执行流永远不应该被移交给一个不受信任的合约——而旧规则下做不到这一点。

提案给的指令规格与账本
这条暂定名为 AIRDROP 的指令接收两个栈参数:目标地址和以 wei 计的金额。Gas 计费由提案逐项写死:静态成本 6700,这个数字是把普通 CALL 在带价值调用时的 9000 减去 2300 的执行补贴得来的——既然不再给对方执行代码,那 2300 也就不必预付。动态部分两条:目标地址若在本笔交易里第一次碰到,按冷访问计 2600,否则按热访问 100,这套冷热计价正是 2929 建立的体系;收款方若是空账户且金额非零,还要加收 25000 的账户创建费——余额、nonce、代码三者皆空才算空账户。提案自述这些数字来自 2022 年写作时的参数,后续升级可能变动,引用时应以当期规范为准。
自毁转账技巧:它想替代的那个昂贵绕行
在 5065 之前,合约开发者想要”只转钱不触发对方代码”,存在一个著名但荒唐的绕行:先部署一个空合约,把要转的 ETH 精确转入它,再对它调用 SELFDESTRUCT,让协议把余额原样搬到最终收款方——自毁转账不会调用接收方。提案在 Rationale 里直说这条路”贵得离谱”,因为它把部署与自毁的全套开销都花在了一个纯粹的中转动作上。5065 相当于承认:开发者早就在用脚投票表达”我需要这条指令”,只是被迫用最贵的方式实现。这也是该提案作为安全原语的说服力所在——需求不是假设出来的,是已经拿真金白银验证过的。
它为什么停在 Stagnant
协议每加一条指令,都要走完全部客户端实现、形式化验证、审计与升级协调,而 5065 的收益可以用软件纪律逼近:转出方先改账本再转账(checks-effects-interactions 顺序)、加防重入锁、给接收方类型设白名单,都能压缩事故面。更关键的是,重入问题的重心早已从”ETH 原生转账”转向代币合约的内部记账——ERC-20 转余额本来就不触发接收方代码,风险被记账模型天然隔开。于是一条只服务”合约往外推 ETH”场景的操作码,很难在升级议程里挤进位置。此外自毁语义在 2022 年后被大幅收紧,那条绕路的存续本身也变得不确定,这是提案成文时未料到的变量。
顺带澄清两个容易混淆的概念,避免把这条指令与其他同名事物搞错。其一,提案草稿里暂定的指令名与空投活动无关:它不涉及任何代币发放,只管 ETH 本位价值的静默搬运,“免费领币”语境里的 air-drop 与之没有半点关系。其二,它与普通转账在结果上看起来相同——余额从 A 挪到 B——差别只在过程:有没有打开接收方的代码大门。安全分析里”结果相同、过程不同”的这对性质,正是所有资产桥接、存管合约审计时反复检查的维度,一条指令如此,一个产品的设计同样如此。
用户侧值得记住的三条边界
第一,向一个合约地址直接转 ETH 前,先意识到这可能触发对方代码——若对方是收款即做事的合约(比如自动入池),转账本身就是业务动作,金额与目标地址都要按签名内容核对。第二,合约钱包与脚本合约收到 ETH 后未必”自动入账”:有些合约没有可写的接收逻辑,纯转账可能滞留在合约账户里而非你的可用余额,转账前确认收款方类型是普通钱包地址还是合约地址,是浏览器上两分钟就能完成的自查(读法见 区块浏览器怎么读:确认数、失败原因和交易状态逐项解释)。第三,凡教程教你”把 ETH 转到某个合约地址激活空投”,其结构等价于你主动送执行流进对方地盘,风险判断按陌生合约的标准处理。本文为机制科普,不构成投资建议。
发表评论
还没有评论,来说两句吧。
评论区为展示样式,提交不会被处理。