gpt4 book ai didi

ethereum - Solidity for 循环大量数据

转载 作者:行者123 更新时间:2023-12-01 03:17:11 26 4
gpt4 key购买 nike

我想使用一个函数来可靠地查找用户的所有 token ,因此我使用 for 循环遍历所有 token 并查看地址是否匹配。 token 的 totalSupply() 大约为 10Mio,这对于 for 循环来说似乎太多了。以下函数仅对小于 500000 的 totalSupply() 起作用,我不知道实际问题是什么。超过 500000 它运行该函数,但我得到的结果是空的,如果用户拥有 token 也是如此。 Solidity 是否存在巨大的 for 循环问题?

function tokensOfOwner(address _owner) external view returns(uint256[] ownerTokens) {
uint256 tokenCount = balanceOf(_owner);

if (tokenCount == 0) {
// Return an empty array
return new uint256[](0);
} else {
uint256[] memory result = new uint256[](tokenCount);
uint256 total = totalSupply();
uint256 resultIndex = 0;
uint256 id;

for (id = 1; id <= total; id++) {
if (IndexToOwner[id] == _owner) {
result[resultIndex] = id;
resultIndex++;
}
}
return result;
}
}

编辑:我做了一个测试函数来查看错误可能是什么,不知何故最大循环大小约为 3'840'000 次迭代,然后不知何故我总是返回 0。有谁知道是否有一个巨大的可靠性错误循环?
function testLoop(uint256 num) external view returns(uint256 res) {
uint256 i=0;
uint256 cnt=0;

for(i;i<num;i++) {
cnt++;
}

return cnt;
}

最佳答案

Does solidity have a problem with huge for loops?



是的,但这不是错误。您正在打 gas limit .

我想不出有什么理由让您想以您尝试的方式跟踪代币所有权。存储在 mapping(address => uint) 中的地址拥有的总余额还不够?这似乎类似于跟踪一美元钞票上的序列号,因此您可以审核拥有它的历史记录。

如果你绝对需要这样的东西,不要在方法中循环你的供应。只需将每个 ID 存储在 mapping(address => uint256[]) 中并在调用此函数时返回。即使采用这种方法,在 token 频繁转移时跟踪所有权状态也会花费大量交易费用。

编辑 - 解决评论:

常量/纯函数仅指示该函数是否可以写入/读取合约状态。执行这些功能仍然需要资源,因此会消耗gas。您所考虑的不同之处在于,可能不会向来电者收取汽油费。如果从具有本地、完全同步的非轻节点的客户端调用常量函数,则不会产生费用(毕竟,您使用的是自己的资源)。从事务中调用时,常量函数不是免费的。

请注意 Remix 中关于运行常量函数时成本的注释:

enter image description here

关于ethereum - Solidity for 循环大量数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48113615/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com