ethereum - 在持有者之间划分合约价值(实际上是代币合约)
问题描述
这是我的代码的一部分(代币合约的一部分):
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。
问题是什么?!
解决方案
有两个问题:
每次转账后合约余额都会更新
address(this).balance.
所以如果你想在 10 个地址之间分配 10 wei,第一个地址会看到 10 wei/10,但第二个会看到 9 wei /10。solidity 中的整数除法会截断结果,因此 9/10 返回 0。计算结果为
EtherBalance * (TokenBalance / TotalSupply)
. 持有人超过 1 人时TokenBalance < TotalSupply
,TokenBalance / 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);
}
}
推荐阅读
- python - Python中的浮动RMS
- python - 字符串中的 Python 错误(无效语法),如 ""$xyz""
- angular - 从 Angular 服务更新一个 scss 变量
- jmeter - JMeter 更喜欢协商而不是 NTLM
- php - 合并 2 个具有完全不同表结构的数据库
- html - 在 Bootstrap 3 中的图像上添加文本的正确方法
- sql - SQL - 使用连接添加查询参数
- java - 我可以在 JPA 实体构造函数中使用 use 'System.IdentityHashCode()' 吗?
- spring-boot - Livereload 不会在 chrome 上为 spring 重新加载静态文件
- kubernetes - ClusterIP 是否能够负载平衡多个 pod 的流量?