#StackBounty: #solidity #contract-development #chainlink #randomness Including Chainlinks Verifiable Random Function in a "ask squ…

Bounty: 100

After building a Solidity contract that asks another Solidity contract to compute the square root of an Integer (100 in this case), I was wondering: How can I include a query to Chainlinks Verified Random Function to make the contract ask for the root of a random Integer (instead of 100)?

Solidity Contracts

To make the AskRoot contract testable, I’ve adopted a Waffle example called AmIRichYet.sol to also support the askRoot functionality. Its content is:

pragma solidity ^0.6.2;

interface IERC20 {
    function balanceOf(address account) external view returns (uint256);
}

contract AmIRichAlready {
    // define original variables
    IERC20 private tokenContract;
    uint public richness = 1000000 * 10 ** 18;

    // define askroot variables
    bool solved;    // Boolean to denote if contract is solved.
    address payable owner;  // Owner of the contract, first this is the sponser.
    uint expiry;        // Get the time when the contract expires.

    constructor (IERC20 _tokenContract) public {
        tokenContract = _tokenContract;
        
        // specify ask root constructor variables
        solved = false;         //  Boolean value to indicate if contract is already solved.
        owner = msg.sender;     //  Set the owner of the contract to the creator of the contract.
        expiry = 1612569800;    //  Unix timestamp of the moment of expiry.
    }

    function check() public view returns (bool) {
        uint balance = tokenContract.balanceOf(msg.sender);
        return balance > richness;
    }

    // IS THIS NEEDED???: NO
    function setRichness(uint256 _richness) public {
      richness = _richness;
    }
    
    
    // Include askroot functions
    //function test(address payable hunter) public payable {
    function differentFunctionName(address payable hunter) public payable {
        TemplateSolveContract solver = TemplateSolveContract(msg.sender); // The message sender is the contract activating the test function.
        uint x = 100;                                   // Sample input.
        uint16 y = 10;                                  // Sample expected output.
        require(y == solver.main(x), "Wrong output");   // Require the output of the main function to be y.
        solved = true;                                  // Set solved to true.
        owner = hunter;                                 // Set the ownership to the hunter.
        owner.transfer(address(this).balance);          // Transfer the bounty to the hunter.
    }

    // Getter function for the solved variable.
    function getSolved() public view returns (bool){   
        return solved;
    }
    
    // Getter function for the Ownership.
    function getOwner() public view returns (address) { 
        return owner;
    }
    
    // Getter function for the balance of the contract.
    function getBalance() public view returns (uint) {
        return address(this).balance;
    }
    
    // Refund method to claim the value of the contract after expiry.
    function refund() public {
        require(msg.sender == owner && block.timestamp >= expiry, "Contract is not expired yet");   // The sender must own the contract and the contract must be expired.
        selfdestruct(owner);    // Let the contract selfdestruct and move the value to the owner.
    }
}

// TemplateSolveContract so the TestContract knows the structure of the SolveContract.
abstract contract TemplateSolveContract {
    function main(uint x) public virtual returns (uint);
}

Additionally, I integrated a Chainlink VRF contract that is intended to return a random number, with content:

pragma solidity 0.6.2;

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

contract RandomNumberConsumer is VRFConsumerBase {
    
    bool forTestingPurposes;    // Boolean to run test on this contract
    
    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;
    }
    
    // Getter function for the forTestingPurposes boolean.
    function getForTestingPurposes() public view returns (bool){   
        return forTestingPurposes;
    }
}

Testing

And I can test the trival functions (e.g. getters and setters) fine. However when I test getRandomNumber() with:

// custom test in vrfContract
  it('Tests if a random number is returned', async () => {
    expect(await vrfContract.getRandomNumber()).to.be.equal(7);
  });

I do not get an error saying "the random number is not 7", instead, it returns:

Tests if a random number is returned:
     Error: cannot estimate gas; transaction may fail or may require manual gas limit (error={"name":"RuntimeError","results":{"0x0a0b028de6cf6e8446853a300061305501136cefa5f5eb3e96afd95dbd73dd92":{"error":"revert","program_counter":609,"return":"0x"}},"hashes":["0x0a0b028de6cf6e8446853a300061305501136cefa5f5eb3e96afd95dbd73dd92"],"message":"VM Exception while processing transaction: revert"}, tx={"data":"0xdbdff2c1","to":{},"from":"0x17ec8597ff92C3F44523bDc65BF0f1bE632917ff","gasPrice":{"type":"BigNumber","hex":"0x77359400"},"type":0,"nonce":{},"gasLimit":{},"chainId":{}}, code=UNPREDICTABLE_GAS_LIMIT, version=abstract-signer/5.4.1)
      at Logger.makeError (node_modules/@ethersproject/logger/src.ts/index.ts:225:28)
      at Logger.throwError (node_modules/@ethersproject/logger/src.ts/index.ts:237:20)
      at /home/name/git/trucol/tested/new_test/test_vrf3/node_modules/@ethersproject/abstract-signer/src.ts/index.ts:301:31
      at process._tickCallback (internal/process/next_tick.js:68:7)

From watching these instructions: https://docs.chain.link/docs/deploy-your-first-contract/ It seems that I did not fund the contracts with the right test tokens (I assume Ethereum from Ropsten Test Network, and Link from Kovan Test Network), however I do not exactly know which contract has which address yet.
So testing a function in the AmIRichYet.sol contract that calls getRandomNumber() is not yet practical.


Get this bounty!!!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.