如何生成一个随机数? [英] How to generate a random number in solidity?

查看:153
本文介绍了如何生成一个随机数?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有几个keccaks,如果我能找到一种便宜的方法来获取所创建uint的一部分的话,可以减少到一个.

I have a couple of keccaks, which could be reduced to one, if I would find a cheap way to get parts of the created uint.

pragma solidity ^0.4.19;

contract test {
  function test() {

  }

function sup() returns (uint test) {
    uint _test = uint(keccak256("wow"));
    return _test;
  }
}

这给了我一个甜美的随机数:13483274892375982735325

This returns me a sweet random number: 13483274892375982735325

现在的计划是,与其用不同的种子"打电话给keccak 5次,我可以将这个数字分开并得到类似的结果: 1348、3274、8923等. 然后将其用于我的随机数,例如:1348%10

Now the plan is that instead of calling keccak 5 times with different "seeds", I could take that number apart and get something like: 1348, 3274, 8923 etc. which I then use for my random number e.g.: 1348 % 10

但是,团结不能仅仅做到这一点.有没有便宜的东西可以工作?

But solidity can't just do that. Is there anything cheap that could work?

推荐答案

实体合同是确定性的.弄清楚合同如何产生随机性的任何人都可以预期其结果,并使用此信息来利用您的应用程序.

Solidity contracts are deterministic. Anyone who figures out how your contract produces randomness can anticipate its results and use this information to exploit your application.

一种选择是在链下产生随机性(无法预测),并在智能合约中使用它. Chainlink VRF 是一种易于实现的解决方案,用于在智能合约中使用随机数据.这是请求&的示例代码段接收随机数据:

One option is to produce randomness off-chain (where it cannot be predicted) and use it in your smart contract. Chainlink VRF is an easy-to-implement solution for using random data in smart contracts. Here's an example snippet to request & receive random data:

requestRandomness(keyHash, fee, seed);

您的合同请求通过回调函数完成:

Your contract's request is fulfilled in a callback function:

function fulfillRandomness(bytes32 requestId, uint256 randomness) external override {
  // Do something with randomness
}

实现随机数的完整合同的示例为:

An example of a full contract that implements a random number would be:

pragma solidity 0.6.2;

import "https://raw.githubusercontent.com/smartcontractkit/chainlink/develop/evm-contracts/src/v0.6/VRFConsumerBase.sol";

contract Verifiable6SidedDiceRoll is VRFConsumerBase {
    using SafeMath for uint;

    bytes32 internal keyHash;
    uint256 internal fee;

    event RequestRandomness(
        bytes32 indexed requestId,
        bytes32 keyHash,
        uint256 seed
    );

    event RequestRandomnessFulfilled(
        bytes32 indexed requestId,
        uint256 randomness
    );

    /**
     * @notice Constructor inherits VRFConsumerBase
     * @dev Ropsten deployment params:
     * @dev   _vrfCoordinator: 0xf720CF1B963e0e7bE9F58fd471EFa67e7bF00cfb
     * @dev   _link:           0x20fE562d797A42Dcb3399062AE9546cd06f63280
     */
    constructor(address _vrfCoordinator, address _link)
        VRFConsumerBase(_vrfCoordinator, _link) public
    {
        vrfCoordinator = _vrfCoordinator;
        LINK = LinkTokenInterface(_link);
        keyHash = 0xced103054e349b8dfb51352f0f8fa9b5d20dde3d06f9f43cb2b85bc64b238205; // hard-coded for Ropsten
        fee = 10 ** 18; // 1 LINK hard-coded for Ropsten
    }

    /** 
     * @notice Requests randomness from a user-provided seed
     * @dev The user-provided seed is hashed with the current blockhash as an additional precaution.
     * @dev   1. In case of block re-orgs, the revealed answers will not be re-used again.
     * @dev   2. In case of predictable user-provided seeds, the seed is mixed with the less predictable blockhash.
     * @dev This is only an example implementation and not necessarily suitable for mainnet.
     * @dev You must review your implementation details with extreme care.
     */
    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;
    }

    function fulfillRandomness(bytes32 requestId, uint256 randomness) external override {
        uint256 d6Result = randomness.mod(6).add(1);
        emit RequestRandomnessFulfilled(requestId, randomness);
    }

}

这篇关于如何生成一个随机数?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆