有谁能告诉我为什么在将这个函数放入Remix时会产生上述警告?
function doFlip() public{
uint256 blockValue = uint256(blockhash(block.number - 1));
uint256 coinFlip = uint256(uint256(blockValue)/FACTOR);
side = coinFlip == 1 ? true : false;
flipper.flip(side);
}
合同全文如下:
//SPDX-License-Identifier: Unlicensed
pragma solidity ^0.6.0;
import "@openzeppelin/contracts-ethereum-package/contracts/math/SafeMath.sol";
interface CoinFlip {
function flip(bool guess) external returns (bool);
}
contract Flipper {
using SafeMath for uint256;
uint256 FACTOR = 57896044618658097711785492504343953926634992332820282019728792003956564819968;
bool public side;
CoinFlip public flipper;
constructor() public {
flipper = CoinFlip(xxxxxxxxxx);
}
function doFlip() public{
uint256 blockValue = uint256(blockhash(block.number - 1));
uint256 coinFlip = uint256(uint256(blockValue)/FACTOR);
side = coinFlip == 1 ? true : false;
flipper.flip(side);
}
}
CoinFlip合约如下:
/ SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;
import '@openzeppelin/contracts/math/SafeMath.sol';
contract CoinFlip {
using SafeMath for uint256;
uint256 public consecutiveWins;
uint256 lastHash;
uint256 FACTOR = 57896044618658097711785492504343953926634992332820282019728792003956564819968;
constructor() public {
consecutiveWins = 0;
}
function flip(bool _guess) public returns (bool) {
uint256 blockValue = uint256(blockhash(block.number.sub(1)));
if (lastHash == blockValue) {
revert();
}
lastHash = blockValue;
uint256 coinFlip = blockValue.div(FACTOR);
bool side = coinFlip == 1 ? true : false;
if (side == _guess) {
consecutiveWins++;
return true;
} else {
consecutiveWins = 0;
return false;
}
}
}
似乎EVM的Remix JavaScript模拟器存在持续的问题,无法计算blockhash()
。
我可以重现这个问题:
pragma solidity ^0.8;
contract MyContract {
function foo() external returns (bytes32) {
return blockhash(1); // fails in Remix JS VM
}
}
并在以太坊StackExchange上找到了这个答案,链接到一个已删除的问题。
所以如果你需要你的合同在Remix JS VM中工作,我建议你改变合同逻辑,这样它就不会使用失败的blockhash()
功能。