当我调用这个智能合约时,希望它返回7或8个独一无二的随机数,范围在1到100之间。获取这样的结果最好的方法是什么?
当我调用这个智能合约时,希望它返回7或8个独一无二的随机数,范围在1到100之间。获取这样的结果最好的方法是什么?
使用像Oraclize这样的外部预言机,智能合约可以从Web API(如货币汇率、天气预报和股票价格(如random.org))请求数据。这种方法的主要缺点是它是集中化的。Oraclize守护程序会篡改结果吗?我们可以相信random.org吗?
除了Oraclize之外,我们还可以使用BTCRelay,它是以太坊和比特币区块链之间的桥梁。使用BTCRelay,以太坊区块链中的智能合约可以请求未来的比特币块哈希并将其用作熵源。
Signidice是一种基于加密签名的算法,可用于涉及两个方:玩家和庄家的智能合约中的随机数生成。该算法的工作原理如下:
Commit-reveal方法由两个阶段组成:
使用Chainlink VRF进行操作。
使用区块哈希或类似方法作为随机种子存在一些问题。如果攻击者在您的合约之前就知道了区块哈希,他们可以利用这个信息在您试图处理的任何事情上获得恶意优势。此时,预言机可以提供帮助,但它们是中心化的易于出错,并且必须能够证明它们是随机的。
您需要拥有一个预言机网络,该网络可以:
当前示例演示如何解决第1点要求。您可以通过从支持Chainlink VRF的足够数量的节点提取来满足第2点要求。
有关精确实现,请参阅类似问题的回答。
您需要向一个具有由您生成的种子的函数的节点发出请求:
function rollDice(uint256 userProvidedSeed) public returns (bytes32 requestId) {
require(LINK.balanceOf(address(this)) > fee, "Not enough LINK - fill contract with faucet");
uint256 seed = uint256(keccak256(abi.encode(userProvidedSeed, blockhash(block.number)))); // Hash user seed and blockhash
bytes32 _requestId = requestRandomness(keyHash, fee, seed);
emit RequestRandomness(_requestId, keyHash, seed);
return _requestId;
}
当函数返回值后,您需要对其进行取余100并加1。如果您需要7或8个随机数,则需要调用此函数7或8次。
function fulfillRandomness(bytes32 requestId, uint256 randomness) external override {
uint256 d6Result = randomness.mod(100).add(1);
emit RequestRandomnessFulfilled(requestId, randomness);
}