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?

3
  • 1
    Does this question works for you? ethereum.stackexchange.com/questions/96342/…
    – Ismael
    Sep 5, 2021 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: 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 7, 2021 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 docs.chain.link/docs/vrf-contracts. For the ETH/gas required, the wallet address performing the transaction pays for that at the time Sep 9, 2021 at 4:10

0

Your Answer

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