首页 > 解决方案 > 无法在 Remix 和 Metamask 上向用户退还多余的以太币

问题描述

构建众筹应用程序。一旦达到目标,对项目的任何以太贡献都将通过 msg.sender.transfer(excess) 或 msg.sender.send(excess) 退还。

在 Remix 和 Metamask 上进行了广泛的测试(通过 Web3 部署)。关键问题是多余的资金会从发件人的账户中全额扣除,并且不会退还给发件人。

pragma solidity ^0.5.0;

contract Funds {
    uint public maximumValue = 100;
    uint public currentValue = 0;

    // addFunds function that takes in amount in ether
    function addFunds (uint _amount) public payable {
        // Converts wei (msg.value) to ether
        require(msg.value / 1000000000000000000 == _amount);
        // if the sum of currentValue and amount is greater than maximum value, refund the excess
        if (currentValue + _amount > maximumValue){
            uint excess = currentValue + _amount - maximumValue;
            currentValue = maximumValue;
            msg.sender.transfer(excess);
        } else {
            currentValue += _amount;
        }
    }
}

标签: ethereumsoliditymetamask

解决方案


看起来你的合约中的所有值都是以太币,所以你可能想要msg.sender.transfer(excess * 1 ether). 我的猜测是退款是有效的,但它会退回您没有注意到的少量 wei。

IMO,更好的解决方法是在任何地方使用 wei:

pragma solidity ^0.5.0;

contract Funds {
    uint public maximumValue = 100 ether;
    uint public currentValue = 0;

    function addFunds() external payable {
        // if the sum of currentValue and amount is greater than maximum value, refund the excess
        if (currentValue + msg.value > maximumValue){
            uint excess = currentValue + msg.value - maximumValue;
            currentValue = maximumValue;
            msg.sender.transfer(excess);
        } else {
            currentValue += msg.value;
        }
    }
}

推荐阅读