2

Is it possible for a token contract to call an oracle to fetch data once every so many hours? Let's say the token was going to use a random number for some decision it was going to make in its execution and that random number needed updated once a day. Calling the Chainlink VRF to get the random number is easy enough, but is it possible that call only happens once a day?

2

Yes.

You'd want to use the sleep adapter from a network of chainlink nodes. This will allow you to call a function every X minutes.

Note, in version 0.6 of solidity its a little tricky to get the VRF and Alarm in the same contract. So an easy work around is to just put them in two separate contracts and have them call each other. Here is an example of a repo that does that.

Here is an example from remix on the kovan testnet.

/** This example code is designed to quickly deploy an example contract using Remix.
 *  If you have never used Remix, try our example walkthrough: https://docs.chain.link/docs/example-walkthrough
 *  You will need testnet ETH and LINK.
 *     - Kovan ETH faucet: https://faucet.kovan.network/
 *     - Kovan LINK faucet: https://kovan.chain.link/
 */

pragma solidity ^0.6.0;

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

contract AlarmClockSample is ChainlinkClient {
  
    bool public alarmDone;
    
    address private oracle;
    bytes32 private jobId;
    uint256 private fee;
    
    /**
     * Network: Kovan
     * Oracle: Chainlink - 0xAA1DC356dc4B18f30C347798FD5379F3D77ABC5b
     * Job ID: Chainlink - 982105d690504c5d9ce374d040c08654
     * Fee: 0.1 LINK
     */
    constructor() public {
        setPublicChainlinkToken();
        oracle = 0xAA1DC356dc4B18f30C347798FD5379F3D77ABC5b;
        jobId = "982105d690504c5d9ce374d040c08654";
        fee = 0.1 * 10 ** 18; // 0.1 LINK
        alarmDone = false;
    }
    
    /**
     * Create a Chainlink request to start an alarm and after
     * the time in seconds is up, return throught the fulfillAlarm
     * function
     */
    function requestAlarmClock(uint256 durationInSeconds) public returns (bytes32 requestId) 
    {
        Chainlink.Request memory request = buildChainlinkRequest(jobId, address(this), this.fulfillAlarm.selector);
        // This will return in 90 seconds
        request.addUint("until", block.timestamp + durationInSeconds);
        return sendChainlinkRequestTo(oracle, request, fee);
    }
    
    /**
     * Receive the response in the form of uint256
     */ 
    function fulfillAlarm(bytes32 _requestId, uint256 _volume) public recordChainlinkFulfillment(_requestId)
    {
        alarmDone = true;
    }

You could also set up a network of cron jobs to call it at every X hour using the chainlink cron initiators.

2
  • 1
    Thank you so much Patrick Collins, this was perfect. Lets say in the code example above I wanted to use Rinkeby instead of Kovan, how can I go about finding the oracle hash and jobId? (I am very much a noob when it comes to both solidity and even more so when it comes to Chainlink integrations)
    – esastincy
    Dec 11 '20 at 17:39
  • You'd need a different link address, oracle address, and jobId. You can find examples of all testnets here: docs.chain.link/docs/chainlink-alarm-clock Dec 11 '20 at 21:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.