合约账户的“不速之客”:智能合约的隐形陷阱第一部分:起源这事儿就发生在昨天。听Tiny熊老师讲课后练习的Bank合约,当听到"这个Bank合约不应该维护一个'总存款金额'"时,我心里咯噔一下——这说的不就是我吗?CPU开始高速运转:去掉总金额的状态变量确实能省gas,代码复杂
这事儿就发生在昨天。
听 Tiny 熊老师讲课后练习的 Bank 合约,当听到"这个 Bank 合约不应该维护一个'总存款金额'"时,我心里咯噔一下——这说的不就是我吗?
CPU 开始高速运转:去掉总金额的状态变量确实能省 gas,代码复杂度也能降低。
但接下来的一句直接让我 CPU 烧了:"有人会转 eth 到我这个合约账户,又不会触发我的 receive 或者 fallback"。
还有这种操作?事出反常必有妖,这妖我必须揪出来看看。
1. 自毁(selfdestruct)
这是以太坊协议与生俱来的"核按钮"。
从创世区块就存在的操作码,直到合并后才被标记为废弃,但功能依旧能用。
在 PoW 时代,这是制造"账实不符"漏洞的主要因素。
2. 挖矿的目标地址(coinbase address)
这是协议层的"空投"。
矿工挖出新区块的奖励,直接从以太坊供应中"无中生有",可以指定发送到任何地址——包括我的合约。
这波操作完全绕过交易逻辑,receive/fallback 函数直接装死。
3. 合约部署前发送
这是EVM 的"预言"特性。
由于合约地址是可预测的(由部署者地址+nonce决定),在合约正式上链前,任何人都能先打钱过去。
合约诞生时就自带"第一桶金",但这个过程同样不会触发任何回调。
4. Solidity 0.4 版本前发送
这是上古版本的"历史遗留问题"。
在 payable 关键字出现前,合约接收以太币的逻辑相当模糊,很多老合约在不知不觉中就成了"收钱账户"。
技术需求驱动
selfdestruct
:设计是用来清理废弃合约的,避免资产被永久锁死经济效率驱动
coinbase address
:矿工直连钱包,省去交易费,简单粗暴历史包袱
✅ 依然有效的
❌ 已经失效的
技术层面
selfdestruct
:仍然是合约"自毁"并转移资金的唯一合法途径安全考量
selfdestruct
制造数据不一致,造成问题📌 重点提醒
在 PoS 时代,重点防范对象就俩:selfdestruct
和 合约部署前发送。
这是导致合约"账实不符"的主要元凶。
CPU 散热完毕,是时候来个总结了。
谁能想到,一个看似简单的 Bank 合约,背后居然藏着这么多"骚操作"。
就像你家明明装了防盗门,结果发现有人能从房顶烟囱、地下管道甚至某个平行时空把钱扔进你的保险箱。
心里默念:别相信"应该",要相信"可能"。
探索过程中涉及的资料:
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!