如何通过智能合约提款启用正确的用户识别?

How to enable correct user recognition by the smart contract withdraw?

通过这个智能合约,用户可以存入以太币和取出以太币。合约应存储每个用户和存款,允许随时提取金额。代码中没有错误,但不幸的是,提款功能无法正常工作,事实上,以太币保留在合同中,不会返还给所有者。

   contract vaultCoin {
        uint amount; 
        address user;
        uint amountDeposit;
    
        function vaultCoin() public {
            dev = msg.sender;                    
        }
    
        address public dev;                          
        address[] public users;                   
        uint[] public totalDeposited;                
    
        mapping(address => uint) balances;
        
        function sendToken() public payable {
            balances[msg.sender] = amount;
            require(msg.value > 0.001 ether); 
            
            user = msg.sender;               
            amountDeposit = msg.value;      
            
            users.push(user);                     
            totalDeposited.push(amountDeposit);     
        }
    
        function getUsers() public view returns (address[]) {    
            return users;
        }
    
        function getAmount() public view returns (uint[]) {
            return totalDeposited;
        }
    
        function retireMyCoins() public payable {
            require(msg.sender == user);
            require(msg.value == amountDeposit);
            balances[msg.sender] = 0; 
            msg.sender.transfer(balances[msg.sender]); 
        }
    }
balances[msg.sender] = 0;

您的代码首先将余额设置为 0

msg.sender.transfer(balances[msg.sender]);

然后将已经 zeroed-out 的价值转移给用户。


解决方案:

  1. 在内存变量中记录余额
  2. 将存储值清零
  3. 从内存变量中传输值
uint256 balance = balances[msg.sender];
balances[msg.sender] = 0; 
msg.sender.transfer(balance); 

这个中间步骤可以防止 reentrancy 攻击。