场景简介
外部合约引用是合约复用的一种高效方式,但是任何合约的地址都可以被强转为任何合约类型,所以这里也是作恶者常会利用的地方。
合约介绍
银行合约
上面这个银行合约提供了两个基础的功能:deposit 和 withdraw, 即存钱和取钱,不同点处是合约的初始化逻辑中会构造一个 log实例,log逻辑如下:
日志合约
上面有两个日志合约,第一个是正常的(给用户看)合约,记录历史交易信息。第二个是搞破坏的,主要作用是禁止用户提款的合约。部署者可以在部署银行合约的同时,随意选择第一个或者第二个日志合约。
测试逻辑
测试逻辑将测试正常和异常的两种情况,测试代码如下:
测试脚本
如上图所示,第一次先部署正常的日志合约攻击,第二次部署破坏性的日志合约攻击,测试结果如下:
测试结果
可以看出,第一次攻击成功了,但是第二次失败了,而且还损失了 1 ether, 这就是蜜罐合约,攻击者偷鸡不成蚀把米。
防范措施
如果合约中私有化外部合约的地址变量,那么合约拥有者就有了作恶的可能性。所以正常的合约应该硬编码外部引用合约的地址,或者使用new 关键字初始化外部合约。