Home Coins Chainlink (LINK) Random Number Generation in Solidity

Random Number Generation in Solidity

- Advertisement -

Random number generation (RNG) cannot be done natively in Solidity. To generate a truly verifiable random number on a blockchain, a smart contract must send a seed to an off-chain resource like an oracle, and the oracle must return the random number along with verifiable proof back to the smart contract, proving the random number was generated using the seed. With Chainlink VRF now live on Ethereum mainnet, developers can easily generate random numbers in Solidity in a safe, secure, and verifiable way. In this technical article, we’ll show you how to generate a random number in Solidity using Chainlink VRF.

Examples of generating safe random numbers in your smart contracts can be found in the Chainlink Documentation. Here is a Remix example of blockchain random number generation on the Kovan testnet for those looking to test it out now. Just remember to follow the request and receive methodology and fund your smart contract with LINK.

Chainlink VRF (Verifiable Random Function) is a provably-fair and verifiable source of randomness designed for smart contracts. Solidity developers can use it as a tamper-proof random number generator to build safe and reliable smart contracts for Ethereum applications that rely on unpredictable outcomes.

The first step in generating a random number in Solidity using Chainlink VRF is to determine a seed. It is extremely important to choose a seed that is difficult to influence or predict. If someone can influence or predict the seed, they could in theory try to collude with the oracle performing the request for randomness to give themselves a favorable result. Because of this, it’s advised to not use values derived from the state of the blockchain such as the block height or block timestamp.

This seed is then sent in a request to a Chainlink oracle. The oracle then generates a pseudo random number with the given seed, and returns the result back to the smart contract, along with cryptographic proof that the random number was generated using the seed. This cryptographic proof is created via public-key cryptography, a widely accepted feature of blockchain technology. It’s important that the result can be verified, because actors such as miners or oracles can try to influence the result of a random number for their own benefit.

This is a high-level overview of how Chainlink VRF works. More details of the underlying technical implementation can be found in our introduction to Chainlink VRF. However, as a developer, you don’t need to worry about anything except for obtaining a seed and then creating a request to a Chainlink oracle.

Creating the Consumer Contract

To obtain a random number in your Solidity smart contract, we should first inherit from the Chainlink VRFConsumerBase contract. Our contract should also contain variables for the random number result, the public key hash used to generate randomness, and the given fee to the oracle for fulfilling the request.

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

contract RandomNumberConsumer is VRFConsumerBase {
    
    bytes32 internal keyHash;
    uint256 internal fee;
    uint256 public randomResult;
    
}

Next, in the constructor we should initialize the Chainlink VRF coordinator. We do this by calling the VRFConsumerBase function, passing in the address of the VRF coordinator and the address of the Chainlink token for the given environment. We also need to set the keyHash variable, which is the public key against which randomness is generated. Environment specific values for these can be obtained in the Contract Addresses section of Chainlink VRF documentation. Finally, we need to set the LINK token payment amount. For the Kovan test environment, it’s 0.1 LINK.

   constructor() 
        VRFConsumerBase(
            0xdD3782915140c8f3b190B5D67eAc6dc5760C46E9, // VRF Coordinator
            0xa36085F69e2889c224210F603D836748e7dC0088  // LINK Token
        ) public
    {
        keyHash = 0x6c3699283bda56ad74f6b855546325b68d482e983852a7a82979cc4807b641f4;
        fee = 0.1 * 10 ** 18; // 0.1 LINK
    }

Next, we override the two functions ‘getRandomNumber’ and ‘fulfillRandomness’ in our contract.  The ‘getRandomNumber’ function should take the seed as an input parameter, and should simply call the VRFConsumerBase ‘requestRandomness’ function, passing in the keyHash, the fee amount, and the given seed.

  /** 
     * Requests randomness from a user-provided seed
     */
    function getRandomNumber(uint256 userProvidedSeed) public returns (bytes32 requestId) {
        require(LINK.balanceOf(address(this)) > fee, "Not enough LINK - fill contract with faucet");
        return requestRandomness(keyHash, fee, userProvidedSeed);
    }

When executed, this function sends the request to the given VRF Coordinator contract, which then builds up a final seed and sends it on to the Chainlink oracle for that VRF Coordinator. The final seed is built up with a hash of the following values:

  • The user supply seed
  • The public key hash of the Chainlink oracle fulfilling the request
  • The users nonce at the time of the request
  • The address of the contract that made the request
  • The current block number

The reason these extra values are used is to protect against the scenario of a contract getting the same result using the same seed more than once. The nonce helps protect against a contract doing multiple requests within the same block, so in theory a contract can do multiple requests within the same block using the same seed for each request, and they will still get back unique verifiable random numbers for each request.

The ‘fulfillRandomness’ function should simply accept the random number response as an unsigned integer, along with the ID of the request, and then store the given random number in the contract. This function is called by the VRFCoordinator contract when it receives and verifies a random number. More information on both these functions can be found in the Chainlink VRF documentation.

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

We now have a complete and working example of random number generation (RNG) in Solidity, and can now deploy and test the contract.

Testing the Random Number Generation Consumer Contract

The complete contract above can be easily opened, compiled, and deployed in Remix on the Kovan network. Once deployed, be sure to fund the contract with some LINK.

Once the contract has been funded with at least 0.1 LINK, we can call the ‘getRandomNumber’ function, passing in a number as a seed. This will send the request along with the seed to the VRF coordinator running on a Chainlink oracle.

getRandomNumber in Solidity

Once this transaction has been processed, we then wait a few seconds for the Chainlink oracle to fulfill the request for a random number, and then call the ‘fulfillRandomness’ function we created earlier to return the random number back to our consumer contract.

We can then call the ‘randomResult’ getter function to see the result of the verifiable random number that was generated by the Chainlink oracle with the given seed. We now have a verifiable random number that can be used throughout our consumer contract and any other applications that use it.

randomResult in Solidity

Verifying Randomness

Now that we have a random number returned to our contract, you may wonder how can we be sure that it was generated with the given seed and public key hash of the Chainlink oracle that performed the request. The answer when using Chainlink VRF is that you don’t need to. The verification happens automatically as part of the VRFCoordinator contract fulfilling the request.

If the validation fails, then the random number is not returned to the consuming contract, and the transaction is reverted. So blockchain developers that use Chainlink VRF can be confident that their random numbers obtained via Chainlink VRF are verifiably random. The underlying technical details of the verification can be found in our technical walkthrough of Chainlink VRF.

Summary

Chainlink VRF allows Solidity developers to quickly and easily generate random numbers in their smart contracts in a safe, secure and proven verifiable manner.

If you are a smart contract developer and want to take advantage of the Chainlink VRF feature, visit the Chainlink developer documentation and join the technical discussion on Discord. You can learn more about Chainlink by visiting the Chainlink website and following Chainlink on Twitter and Reddit.



Source link

- Advertisement -
Mr Bitcointe
Mr Bitcointehttps://www.bitcointe.com/
“Fact You Need To Know About Cryptocurrency - The first Bitcoin purchase was for pizza.” ― Mohsin Jameel
468FansLike
76FollowersFollow
4,567FollowersFollow
5,261FollowersFollow
1,558FollowersFollow
2,230SubscribersSubscribe
USD - United States Dollar
EUR
1.22
GBP
1.37
CHF
1.13
NOK
0.12
JPY
0.01
CAD
0.79
AUD
0.77

Most Popular

bitcoin
Bitcoin (BTC) $ 32,311.00
ethereum
Ethereum (ETH) $ 1,336.79
ripple
XRP (XRP) $ 0.266850
tether
Tether (USDT) $ 0.997667
bitcoin-cash
Bitcoin Cash (BCH) $ 428.66
bitcoin-cash-sv
Bitcoin SV (BSV) $ 174.06
litecoin
Litecoin (LTC) $ 134.70
eos
EOS (EOS) $ 2.63
binancecoin
Binance Coin (BNB) $ 41.23
okb
OKB (OKB) $ 5.60
tezos
Tezos (XTZ) $ 2.88
leo-token
LEO Token (LEO) $ 1.32
cardano
Cardano (ADA) $ 0.343735
monero
Monero (XMR) $ 138.76
stellar
Stellar (XLM) $ 0.259919
chainlink
Chainlink (LINK) $ 22.89
huobi-token
Huobi Token (HT) $ 5.63
tron
TRON (TRX) $ 0.029337
usd-coin
USD Coin (USDC) $ 1.00
dash
Dash (DASH) $ 104.47
neo
NEO (NEO) $ 23.29
iota
IOTA (MIOTA) $ 0.429190
nem
NEM (XEM) $ 0.236249
zcash
Zcash (ZEC) $ 87.10
maker
Maker (MKR) $ 1,400.59
paxos-standard
Paxos Standard (PAX) $ 1.00
ethereum-classic
Ethereum Classic (ETC) $ 7.37
vechain
VeChain (VET) $ 0.029469
true-usd
TrueUSD (TUSD) $ 1.00
ftx-token
FTX Token (FTT) $ 9.92
kucoin-shares
KuCoin Token (KCS) $ 1.14
waves
Waves (WAVES) $ 6.72