3

Locally testing Chainlinks VRF

While trying to locally test a contract that calls a Chainlink VRF contract, I'm experiencing some difficulties in setting up the contract balances. I have a CallChainlink contract that calls the ChainlinkVRF contract. They are initialised (and tested) using the following Waffle test:

Test Code

import {expect, use} from 'chai';
import {Contract, utils, Wallet} from 'ethers';
import {deployContract, deployMockContract, MockProvider, solidity} from 'ethereum-waffle';

import IERC20 from '../build/IERC20.json'; import CallChainlink from '../build/CallChainlink.json'; import SomeOtherContract from '../build/SomeOtherContract.json'; import ChainlinkVRF from '../build/ChainlinkVRF.json';

use(solidity);

describe('Am I Rich Already', () => { // Declare contracts let mockERC20: Contract; let callChainlink: Contract; let someOtherContract: Contract; let chainlinkVRFContract: Contract;

// Declare wallets
let mockWallet: Wallet;
let callChainlinkWallet: Wallet;
let someOtherWallet: Wallet;
let chainlinkVRFWallet: Wallet;

beforeEach(async () => {

    // generate random wallets or random origin 
    //const [mockWallet, callChainlinkWallet, someOtherWallet, chainlinkVRFWallet] = Wallet.createRandom();
    //const original = Wallet.createRandom();

    // specify wallet balances
    const provider = new MockProvider(
        {
            ganacheOptions: {
                // The private key is used to generate the four respective wallet addresses.
                accounts: [
                    {balance: '168626800000000000000001', secretKey: '0x706618637b8ca922f6290ce1ecd4c31247e9ab75cf0530a0ac95c0332173d7c1'}, 
                    {balance: '168626800000000000000002', secretKey: '0x706618637b8ca922f6290ce1ecd4c31247e9ab75cf0530a0ac95c0332173d7c2'}, 
                    {balance: '168626800000000000000003', secretKey: '0x706618637b8ca922f6290ce1ecd4c31247e9ab75cf0530a0ac95c0332173d7c3'},
                    {balance: '168626800000000000000004', secretKey: '0x706618637b8ca922f6290ce1ecd4c31247e9ab75cf0530a0ac95c0332173d7c4'}
                ]
            }
        }
    );

    [mockWallet, callChainlinkWallet, someOtherWallet, chainlinkVRFWallet] = provider.getWallets();
    mockERC20 = await deployMockContract(mockWallet, IERC20.abi);
    someOtherContract = await deployContract(someOtherWallet, SomeOtherContract, [mockERC20.address]);
    chainlinkVRFContract = await deployContract(chainlinkVRFWallet, ChainlinkVRF);
    callChainlink = await deployContract(callChainlinkWallet, CallChainlink, [chainlinkVRFContract.address]);
});

// custom test in AskRoot contract
it('checks callChainlink address is returned correctly', async () => {
    expect(await callChainlink.getAddressThis()).to.be.equal('0x82A666453d8aa239eEBE4578E83cD0988D62c83F');

    // This test fails, so the contract address is different than the accompanying wallet addres.
    //expect(await callChainlink.getAddressThis()).to.be.equal(callChainlinkWallet.address);
});



// custom test in AskRoot contract
it('checks callChainlinkWallet address balance is returned correctly', async () => {
    expect(await callChainlink.getAddressThisBalance()).to.be.equal(9001);
});


// custom test in VRF contract
it('checks someOtherContract wallet address is returned correctly', async () => {
    expect(await someOtherContract.getAddressThis()).to.be.equal('0x63E505e173BdbdD1b5DDB39dfAD716ed150e3466');
});

// custom test in AskRoot contract for SolveRoot Contract
it('checks callChainlink calls a function from SolveRoot correctly and returns the right answer', async () => {
    //expect(await callChainlink.callHelloWorld(await someOtherContract.getAddressThis())).to.be.equal('hello World');
    //expect(await callChainlink.callHelloWorld('0x63E505e173BdbdD1b5DDB39dfAD716ed150e3466')).to.be.equal('hello World');
    //expect(await callChainlink.callHelloWorld("0x63E505e173BdbdD1b5DDB39dfAD716ed150e3466")).to.be.equal('hello World');
    expect(await callChainlink.callHelloWorld(someOtherContract.address)).to.be.equal('hello World');
});


// custom test in AskRoot contract for SolveRoot Contract
it('checks someOtherContract calls a function from SolveRoot correctly', async () => {
    //await token.balanceOf(wallet.address)
    //await callChainlink.callHelloWord(someOtherWallet.address)
    await callChainlink.callHelloWorld("0x63E505e173BdbdD1b5DDB39dfAD716ed150e3466")
    expect('helloWorld').to.be.calledOnContract(someOtherContract);
});


// custom test in AskRoot contract for VRF contract
it('checks callChainlink calls a function from VRF Contract correctly and returns the right answer', async () => {
    expect(await callChainlink.callHelloUniverse(chainlinkVRFContract.address)).to.be.equal('hello Universe');
});


// custom test in AskRoot contract for VRF contract
it('checks someOtherContract calls a function from VRF Contract correctly', async () => {
    await callChainlink.callHelloUniverse(chainlinkVRFContract.address)
    expect('helloUniverse').to.be.calledOnContract(chainlinkVRFContract);
});


// custom test in AskRoot contract for VRF contract
it('checks callChainlink calls a function from VRF Contract correctly and returns the a Uint16', async () => { 
    expect(await callChainlink.callUintSmallSquareFromVRFContract(chainlinkVRFContract.address)).to.be.equal(144);
});


// custom test in AskRoot contract for VRF contract
it('checks someOtherContract calls a function from VRF Contract correctly', async () => {
    await callChainlink.callUintSmallSquareFromVRFContract(chainlinkVRFContract.address)
    expect('returnSomeSquare').to.be.calledOnContract(chainlinkVRFContract);
});


// custom test in AskRoot contract for VRF contract
it('Check if a Uint16 can be read from the VRF contract.', async () => { 
    expect(await callChainlink.getVal()).to.be.equal(144);
});

});

Test results

I verified these pairs of contracts work in Remix, by manually transfering some Kovan network test Eth to the address of the deployed CallChainlink address, and by transfering 2 LINK to the address of the deployed ChainlinkVRF contract. However, the balances of the respective wallets is 0 instead of 168626800000000000000001 once run the Wallet addresses, and I do not exactly know how to to set a LINK balance on the contracts that are created using Waffle.

Question

Hence I would like to ask: How can I set the wallet balances in Kovan test Ethereum and LINK in Waffle (or Hardhat) such that I can run the tests and CI without requiring manual action?

a.t.
  • 65
  • 8
  • 1
    Does this question works for you? https://ethereum.stackexchange.com/questions/96342/fulfillrandomness-in-chainlink-vrf/96358#96358 – Ismael Sep 05 '21 at 18:20
  • Not yet, first I was working on testing the AskRoot contact, such that when I am able to call the Chainlink VRF, I can see what is happening. I can now test the basic functions of AskRoot, but I can not yet see the account balances change if the contract is fulfilled in the tests: https://github.com/a-t-2/test_vrf3/tree/test-vrf . I also included a random number generation contract and I am able to deploy it and test a basic function from that Chainlink VRF contract as well. So far, with any non-trival (on-chain) function, I get Error: cannot estimate gas; in my test setup. – a.t. Sep 07 '21 at 22:10
  • @a.t.the contract performing the VRF request needs to have enough LINK in it to pay the VRF node. Can you confirm that it's sufficiently funded as per the required amounts listed here https://docs.chain.link/docs/vrf-contracts/. For the ETH/gas required, the wallet address performing the transaction pays for that at the time – Harry Papacharissiou Sep 09 '21 at 04:10

0 Answers0