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


仍然是原始金额 , 因此将再次传输 。 这可以根据需要重复多次以消耗智能合约 。

检查 - 效果 - 交互模式的想法是确保所有交互(外部调用)最终发生 。 上述代码的典型修复方法如下:

请注意 , 在此代码中 , 余额在传输之前被清零 , 因此尝试对withdraw()进行可重入调用将不会使攻击者受益 。

使用Reentrancy 保护

防止重入的另一种方法是明确检查和拒绝此类调用 。 这是一个简单版本的reentrancy 保护 , 你可以看到这个想法:

使用此代码 , 如果尝试重入调用 , 第7行上的require将拒绝它 , 因为lock仍设置为true 。

在OpenZeppelin的ReentrancyGuard合同中可以找到一个更复杂、更省gas的版本 。 如果从ReentrancyGuard继承 , 则只需使用nonReentrant修饰函数以防止重入 。

请注意 , 此方法仅在显式将其应用于所有正确的函数时才保护您 。 由于需要在储存中保持一定的价值 , 这也增加了gas成本 。

推荐阅读