【发布时间】:2021-07-24 18:06:45
【问题描述】:
我有一个公共的 uint 变量,表示它是“哪一轮”,以及一个推进轮次并在轮次推进的同时进行处理的函数:
uint public round;
function completeRound() public inPaused() inRound() {
if (round == 6) {
// win
} else {
reduceByHalf();
round.add(1);
}
}
如果我在 remix 中运行它,它运行了 4 次,然后在第 5 次始终失败,表明一个函数突然需要支付:
交易到 Playingwithsmartcontracts.completeRound 错误:VM 错误:还原。 revert 事务已恢复到初始状态。注意:如果您发送值并且您发送的值应该小于您当前的余额,则调用的函数应该是应付的。调试事务以获取更多信息。
如果我在调用 reduceByHalf 的地方注释掉 round.add(1),代码就会整天工作。我可以在 Remix 中无限期地单击它而不会出错。
奇怪的是,这开始是一个 Enum 来跟踪回合,并且有同样的问题。在推进枚举的同时,我可以在上述失败之前执行 5 次并将其注释掉,一切正常。
reduceByHalf 代码似乎不是问题,但如果它与问题有关,则显示如下:
struct Foo {
address owner;
uint mintedRound;
uint winningRound;
}
struct FooOwner {
uint[] foos;
uint totalWinningFoos;
}
uint[][5] roundFoos;
uint[][5] roundWinners;
mapping(uint => Foo) public winningFoos;
mapping(address => FooOwner) public fooOwners;
uint totalWinningFoos;
function shuffleFoos (uint256[] memory _array) internal view returns(uint[] memory){
uint[] memory clone = cloneArray(_array, _array.length);
for (uint256 i = 0; i < clone.length; i++) {
uint256 n = i + uint256(keccak256(abi.encodePacked(msg.sender, block.timestamp))) % (clone.length - i);
uint256 temp = clone[n];
clone[n] = clone[i];
clone[i] = temp;
}
return clone;
}
function cloneArray(uint256[] memory _array, uint256 _length) internal pure returns (uint256[] memory) {
uint256[] memory array = new uint256[](_length);
for (uint256 i = 0; i < _length; i++) {
array[i] = _array[i];
}
return array;
}
function reduceByHalf() internal {
uint[] memory clone = shuffleFoos(roundFoos[round]);
uint halfLength = 0;
halfLength = roundFoos[round].length.div(2);
for (uint w = 0; w < halfLength; w++) {
uint fooId = clone[w];
roundWinners[round].push(fooId);
winningFoos[round].winningRound = round;
address fooOwner = winningFoos[fooId].owner;
fooOwners[fooOwner].totalWinningFoos = fooOwners[fooOwner].totalWinningFoos.add(1);
}
totalWinningFoos = totalWinningFoos.add(halfLength);
}
据我所知,我没有发送价值,也不知道为什么它只认为我在交易执行 5 时发送价值。
有人能帮我理解 Remix/Solidity 对什么感到疯狂吗?
我完全不能理解某些东西,但它看起来像是关于数字 5 的东西......我可以将回合推进到 6,但是一旦我将 uint 值设置为 5,我就会开始看到这些问题。 ……好诡异……
【问题讨论】:
标签: blockchain ethereum solidity remix