使用Chainlink VRF。
使用块哈希或类似方法作为随机播种方法存在许多问题。如果攻击者在你的合约之前知道区块哈希,他们可以使用该信息在你试图做的任何事情上获得恶意优势。预言机可以在这里提供帮助,但它们是失败的主要来源,必须能够证明它们是随机的。
您需要有一个预言机网络,它可以:
- 证明生成的数字是随机的。
- 拥有足够的预言机/节点,即使其中一个失败/损坏,您的智能合约也会持续存在。
此时,下面的例子展示了如何解决#1。您可以通过从足够数量的支持 Chainlink VRF 的节点中提取来解决 #2。
如需准确实现,see this answer from a similar question.
您需要使用一个函数向一个节点发出请求,该函数接收您生成的种子:
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);
}