Randomness in deterministic systems.
Tags: solidity, chainlink, blockchain, web3
Published: 2022-02-01 17:56:06

**What is the use case for randomness ?**

After defi, blockchain gaming  is probably the largest use case for blockchains right now. Blockchain gaming basically depends on users going to a smart contract that guarantees that a user will be fairly treated and whatever manipulation happens in a centralized version of that same game can't occur with the user. So for example the creator of the contract can't manipulate money away from users that deserve to get it according to the contract's condition, or if there is some kind of digital good generated by the contract, the contact creator can't simple take it away from a user. 

The most common design pattern for blockchain gaming is the use of randomness. Randomness often generates payouts to users in crypto currency or generates digital goods or any type of events that games rely on. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8e46i9td81rlozi7q3ib.png)
 
The design patterns we see in blockchain gaming so far, sometimes don't deliver the full potential and end to end security that defi is now seeking to deliver to its users through the use of highly reliable oracles.

In certain scenarios the creator of the blockchain game also runs the random number generation service, so on the one hand the smart contract and the conditions of the game and possibly the owner of digital goods is on a blockchain and therefore not gameable, but the random number generation that determines the amount or the value of the relationship between that contract and the user and the currency they put into that contract is controller by the game's creator.

This leads to not the certainty but the unfortunate possibility  that there is a chance that the game's creator could have the same problems either by having his service compromised by an adversary or by compromising it themselves or whatever collection of problems that might occur. 

This is why it is important to have a verifiable source of randomness that can't be gamed and that is outside the control of any interested party such as the player or even the creator of the game. 


**Randomness in deterministic systems**

Getting truly random numbers in a deterministic system is impossible. You cannot create truly random numbers but you can pseudo-random numbers. Blockchain is a deterministic system so we have to make sure that each node must be given the same random number. Determinism is fundamental because it is vital that regardless of where the smart contract code executes, it produces the same result every time and everywhere.

For example, Timestamp vulnerability is quite common. Usually, the timestamp of a block is accessed via `block.timestamp` but this timestamp can be manipulated by miners, leading to influencing the outcome of some function that relies on timestamps. The timestamp is used as a source of randomness in lottery games to select the next winner. Thus, it might be possible for a miner to modify the timestamp in such a way that its chances of becoming the next winner increase.

In order to get the true random number we have to look at outside the blockchain. We need to use oracle services to get the true random number. If you do not have your true random number in your smart contract, your smart contract can get hacked.


**What is chainlink VRF ?**

Chainlink VRF is an external source of randomness for smart contracts as a key input that is cryptographically proven to be unbiased and developers and users can safely rely on it. The benefit of Chainlink VRF is that it is built to use the unique capabilities of blockchains to verify that proof and signatures which no other randomness generator does. 

There are a number of applications that use randomness in very meaningful ways to be able to securely exist. It is of of those input that pulling that input from some other off chain source is sometimes problematic because it is not necessarily build for a blockchain or using all the capabilities of a blockchain to provide security to the application developer and the user.


**Show me the code!**

```
pragma solidity ^0.8.7;

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

/**
 * THIS IS AN EXAMPLE CONTRACT WHICH USES HARDCODED VALUES FOR CLARITY.
 * PLEASE DO NOT USE THIS CODE IN PRODUCTION.
 */

/**
 * Request testnet LINK and ETH here: https://faucets.chain.link/
 * Find information on LINK Token Contracts and get the latest ETH and LINK faucets here: https://docs.chain.link/docs/link-token-contracts/
 */
 
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
        )
    {
        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
}
```

My name is Javier Acrich and you can find me at [LinkedIn](https://www.linkedin.com/in/javieracrich/)