4
function random() internal returns (uint) {
    uint random = uint(keccak256(now, msg.sender, nonce)) % 1000;
    nonce++;
    return random;
}

In this way, you can generate random numbers, but there will be less than 100, how to solve, thank you

3 Answers 3

5

What you want is a random number within a range of 900 options.

So do this:

function random() internal returns (uint) {
    uint randomnumber = uint(keccak256(abi.encodePacked(now, msg.sender, nonce))) % 900;
    randomnumber = randomnumber + 100;
    nonce++;
    return randomnumber;
}

Basically you get a number from 0 - 899, and then add 100 to match your offset.

9
  • cool!!!!!!!!!!!!
    – Kido
    Oct 16, 2018 at 17:34
  • BTW, notice how I changed the name of your randomnumber variable. You will want to keep it different from your function name. Additionally, you should use abi.encodePacked() before hashing the 3 values, as I have demonstrated above. Oct 16, 2018 at 17:35
  • why need "you should use abi.encodePacked() before hashing the 3 values"?
    – Kido
    Oct 16, 2018 at 17:37
  • You can take a look here for some details: Deprecate variable argument mode of keccak256/sha256. Ultimately, it is best practice to do it this way. Oct 16, 2018 at 17:48
  • 6
    Be careful. That random number is 100% predictable so not suitable for a game of chance or any situation in which a participant is presumed to not be able to guess it. Oct 16, 2018 at 18:06
8

Since you're using the blockhash as your random number seed, this is actually a pseudo-random implementation. See this post for more information. To do this correctly, you'd want a decentralized oracle with provably random verification. A Chainlink VRF is your answer.

Here is a kovan implementation of your request, you can deploy it to remix with this link. You can look at the Chainlink docs to run an example walkthrough to learn how to make Chainlink requests.

pragma solidity 0.6.6;

import "@chainlink/contracts/src/v0.6/VRFConsumerBase.sol";

contract RandomNumberConsumer is VRFConsumerBase {
    
    bytes32 internal keyHash;
    uint256 internal fee;
    
    uint256 public randomResult;
    
    /**
     * Constructor inherits VRFConsumerBase
     * 
     * Network: Kovan
     * Chainlink VRF Coordinator address: 0xdD3782915140c8f3b190B5D67eAc6dc5760C46E9
     * LINK token address:                0xa36085F69e2889c224210F603D836748e7dC0088
     * Key Hash: 0x6c3699283bda56ad74f6b855546325b68d482e983852a7a82979cc4807b641f4
     */
    constructor() 
        VRFConsumerBase(
            0xdD3782915140c8f3b190B5D67eAc6dc5760C46E9, // VRF Coordinator
            0xa36085F69e2889c224210F603D836748e7dC0088  // LINK Token
        ) public
    {
        keyHash = 0x6c3699283bda56ad74f6b855546325b68d482e983852a7a82979cc4807b641f4;
        fee = 0.1 * 10 ** 18; // 0.1 LINK
    }
    
    /** 
     * Requests randomness from a user-provided seed
     */
function getRandomNumber() public returns (bytes32 requestId) {
        require(LINK.balanceOf(address(this)) >= fee, "Not enough LINK - fill contract with faucet");
        return requestRandomness(keyHash, fee);
    }

    /**
     * Callback function used by VRF Coordinator
     */
    function fulfillRandomness(bytes32 requestId, uint256 randomness) internal override {
        randomResult = randomness;
    }
}
0
4

Between min and max:

randomness % (max - min + 1) + min

Between 1 and max:

randomness % max + 1

Where randomness is uint obtained from Chainlink VRF or from any other source

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.