首页 > 解决方案 > 在持有者之间划分合约价值(实际上是代币合约)

问题描述

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

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。

问题是什么?!

标签: ethereumsolidity

解决方案


有两个问题:

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

  2. solidity 中的整数除法会截断结果,因此 9/10 返回 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);
    }
}

推荐阅读