似乎有两种不同的方式来编写一个withdrawal函数来从您已经部署的合同中获得ETH资金。我想知道哪一种方法更好--或者说“更安全”(2022年)。
下面是我遇到的两个版本的撤回方法:
// Version 1:
function withdraw() public onlyOwner {
uint balance = address(this).balance;
msg.sender.transfer(balance);
}
// Version 2:
function withdrawMoney() external onlyOwner {
(bool success, ) = msg.sender.call{ value: address(this).balance } ("");
require(success, "Transfer failed.");
}我还注意到,两个版本似乎都没有处理或使用reentrancy。这是因为两者都使用onlyOwner修饰符,所以不需要担心reentrancy?
(我很明显很好奇,为什么用这些方法中的一种比另一种更好。)
发布于 2022-11-20 21:01:36
不,onlyOwner的使用没有必要防止重入攻击。假设您有一个名为setOwner的公共函数,它将调用方设置为所有者,然后通过调用setOwner函数,调用方成为所有者,并且仍然可能发生重入攻击。
第二种方法是向合同发送ETH的推荐方法。空参数(“”)触发接收地址的回退函数。通过使用call,还可以触发合同中定义的其他函数,并发送固定数量的气体来执行该功能。事务状态作为布尔值发送,返回值在数据变量中发送。
请参见:
https://medium.com/coinmonks/solidity-transfer-vs-send-vs-call-function-64c92cfc878a
https://ethereum.stackexchange.com/questions/139726
复制相似问题