区块链研究实验室|停止使用Solidity的transfer()函数( 四 )

可重入性?(Reentrancy )

希望您在看到上述代码时首先考虑过这个问题 。 引入transfer()和send()的全部原因是为了解决DAO的黑客攻击的原因 。  其思想是2300 gas足以发出一个日志条目 , 但不足以发出一个可重入调用 , 然后修改存储 。

不过 , 请记住 , gas成本可能会发生变化 , 这意味着无论如何 , 这是解决重入问题的糟糕方法 。 今年早些时候 , 君士坦丁堡叉子被推迟了 , 因为降低gas成本导致先前安全的代码无法再进入 。

如果我们不再使用transfer()和send() , 我们将不得不以更健壮的方式防止重入 。 幸运的是 , 这个问题有很好的解决方案 。

检查 - 效果 - 交互模式

消除重入错误的最简单方法是使用检查-效果-交互模式 。 这是一个可重入错误的典型例子:

如果msg.sender是智能合约 , 它在第6行有机会在第7行发生之前再次调用withdraw() 。 在第二次调用中 , balanceOf [msg.sender

推荐阅读