在持有人之间划分合约价值(实际上是代币合约)

Dividing contract value (actually it is token contract) between holders

这是我的代码的一部分(代币合约的一部分):

contract SpeadTheGainContract{
    uint public _totalSupply;
    mapping(address => uint) public balances;
    uint public indexedAddressesCounter = 0;
    mapping(address=>bool) ifAdressExisted;
    mapping(uint=>address) ownersAddresses;
    uint requiredAmount = 1 wei;
    
    function spreadTheGain() external{
        for (uint i = 0; i < indexedAddressesCounter; i++){
            payable(ownersAddresses[i]).transfer(address(this).balance*(balances[ownersAddresses[i]]/_totalSupply));
        }
    }
    
    function increaseValue() external payable{
        require(msg.value >= requiredAmount, "Can't send 0 value!");
    }
}

通过每次令牌传输,新的接收者地址将添加到 ownersAddresses

使用 increaseValue(),合约接收一定数量的 ETH 并将其存储。

随着 spreadTheGain(),合约存储的 ETH 将在代币持有者之间传播。

问题是当有 1 个代币持有者(所有者)时它工作正常,但如果有另一个持有者,它就不起作用并在不发送任何 ETH 的情况下执行该功能。

在交易详情中,它向持有人显示向持有人发送 ETH 的内部交易金额,但发送值为 0 ETH。

有什么问题吗?!

有两个问题:

  1. 每次转账后合约余额都会更新address(this).balance. 所以如果你想在 10 个地址之间分配 10 wei,第一个会看到 10 wei/10,但是第二个会看到9 wei /10.

  2. solidity 中的整数除法会截断结果,因此 9/10 为 returns 0。计算结果为 EtherBalance * (TokenBalance / TotalSupply)。当有超过 1 个持有人 TokenBalance < TotalSupplyTokenBalance / TotalSupply = 0.

要解决第一个问题,请在进入循环之前将余额保存在一个变量中。第二个问题可以通过重新排序先做乘积然后除法的操作来解决 (EtherBalance * TokenBalance) / TotalSupply.

function spreadTheGain() external {
    uint256 totalBalance = address(this).balance;
    for (uint i = 0; i < indexedAddressesCounter; i++) {
        uint256 amount = (totalBalance * balances[ownersAddresses[i]]) / _totalSupply;
        payable(ownersAddresses[i]).transfer(amount);
    }
}