0

The question says it all. Can I get an array of random numbers in solidity?

2 Answers 2

0

Getting a random number in solidity is tricky by itself because blockchains are deterministic. You'll want to reach outside the blockchain, but only with services that can prove their numbers are random. To do this, you'd want to use Chainlink VRF and return a whole array.

You can then create an expand function, that is a whole of array of random numbers based on the seed random number.

function expand(uint256 randomValue, uint256 n) public pure returns (uint256[] memory expandedValues) {
    expandedValues = new uint256[](n);
    for (uint256 i = 0; i < n; i++) {
        expandedValues[i] = uint256(keccak256(abi.encode(randomValue, i)));
    }
    return expandedValues;
}

For context, here is what a full contract on the kovan testnet would look like:


pragma solidity 0.6.6;

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

/**
 * THIS IS AN EXAMPLE CONTRACT WHICH USES HARDCODED VALUES FOR CLARITY.
 * PLEASE DO NOT USE THIS CODE IN PRODUCTION.
 */
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 (Varies by network)
    }
    
    /** 
     * Requests randomness 
     */
    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;
    }

    // function withdrawLink() external {} - Implement a withdraw function to avoid locking your LINK in the contract

function expand(uint256 randomValue, uint256 n) public pure returns (uint256[] memory expandedValues) {
    expandedValues = new uint256[](n);
    for (uint256 i = 0; i < n; i++) {
        expandedValues[i] = uint256(keccak256(abi.encode(randomValue, i)));
    }
    return expandedValues;
}
}
6
  • For context, I work on the chainlink protocol. Aug 9, 2021 at 15:14
  • 1
    I dont see how you are using expand() to get the array full of random numbers. I am confused as to where to call this function from so I can use it.
    – lopezdp
    Oct 24, 2021 at 8:16
  • Oh! You'd call the expand method separately after requesting the random number Oct 24, 2021 at 18:01
  • 1
    so using your example would it be something like: expand(randomness, 9); called from within the fulfillRandomness callback to get the array of random numbers I need? could you provide an example please? im assuming the result of that call is an array of course.
    – lopezdp
    Oct 24, 2021 at 21:34
  • You got it! I'm not sure what I'd offer as an example, you said exactly what you should do. Call expand(randomness, 9) Oct 24, 2021 at 21:46
0

This is what I used for my lottery smart contract to pick a random winner

    contract Lottery {
    
...
    
        address[] public players;
    
...
    
    function random() private view returns (uint256){
            return uint(keccak256(block.difficulty, now, players));
        }
    
    ...
    
     function pickWinner() public restricted {
    ...
    
           uint256 index = random() % players.length;
           players[index].transfer(this.balance);
        
        ...
    }

You can use sha3 as well

2
  • This is pseudo-random, not actually random. The block.difficulty can be manipulated. Aug 9, 2021 at 15:55
  • 1
    @PatrickCollins thank you for your reply. I am pretty new in the solidity world and this was the single method that I used for "random" things. I will try your method as well! Aug 9, 2021 at 16:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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