XCEPTION
XCEPTION

Reputation: 1753

What are the functions setPublicChainlinkToken & setChainlinkToken in Chainlink API call?

I was following the tutorial of Chainlink docs at https://docs.chain.link/docs/advanced-tutorial/ to make an API call from my smart contract. However, I am still not able to understand the function setPublicChainlinkToken() that is being called in the constructor of APIConsumer. I am trying to fetch the temperature of a city through the API call. But my contract gives an error in compilation saying:

APIConsumer hit a require or revert statement somewhere in its constructor

The above error is very generic and I am unable to understand what is the issue. Below is my contract code and the script which I am using to deploy it.

What params do I need to pass in the deploy script?

APIConsumer contract

// SPDX-License-Identifier: MIT
pragma solidity ^0.6.0;

import "@chainlink/contracts/src/v0.6/ChainlinkClient.sol";

/**
 * THIS IS AN EXAMPLE CONTRACT WHICH USES HARDCODED VALUES FOR CLARITY.
 * PLEASE DO NOT USE THIS CODE IN PRODUCTION.
 */
contract APIConsumer is ChainlinkClient {
    using Chainlink for Chainlink.Request;
  
    uint256 public temperature;
    
    address private oracle;
    bytes32 private jobId;
    uint256 private fee;
    
    constructor () public {
        setPublicChainlinkToken(); // Do I need to pass any params for this?
        // if (_link == address(0)) {
        //     setPublicChainlinkToken();
        // } else {
        //     setChainlinkToken(_link);
        // }
        // setPublicChainlinkToken();
        oracle = <oracle id>; // Removed oracle id and jobid values for post
        jobId = <job id>;
        fee = 0.1 * 10 ** 18; // 0.1 LINK (Varies by network and job)
    }
    
    /**
     * Create a Chainlink request to retrieve API response, find the target
     * data, then multiply by 1000000000000000000 (to remove decimal places from data).
     */
    function requestVolumeData() public returns (bytes32 requestId) 
    {
        Chainlink.Request memory request = buildChainlinkRequest(jobId, address(this), this.fulfill.selector);
        
        // Set the URL to perform the GET request on
        // "https://min-api.cryptocompare.com/data/pricemultifull?fsyms=ETH&tsyms=USD"
        
        request.add("get", "http://api.weatherstack.com/current?access_key=7940b0c1136901badcb304724132b234&query=Mumbai");
        
        // Set the path to find the desired data in the API response, where the response format is:
        // {"RAW":
        //   {"ETH":
        //    {"USD":
        //     {
        //      "VOLUME24HOUR": xxx.xxx,
        //     }
        //    }
        //   }
        //  }
        request.add("path", "current.temperature");
        
        // Multiply the result by 1000000000000000000 to remove decimals
        // int timesAmount = 10**18;
        // request.addInt("times", timesAmount);
        
        // Sends the request
        return sendChainlinkRequestTo(oracle, request, fee);
    }
    
    /**
     * Receive the response in the form of uint256
     */ 
    function fulfill(bytes32 _requestId, uint256 _temperature) public recordChainlinkFulfillment(_requestId)
    {
        temperature = _temperature;
    }

    // function withdrawLink() external {} - Implement a withdraw function to avoid locking your LINK in the contract
}

Javascript Script To Deploy:

const APIConsumer = artifacts.require("APIConsumer");
module.exports = async (deployer, network, [defaultAccount]) => {
  try {
    await deployer.deploy(APIConsumer);
  } catch (err) {
    console.error(err);
  }
};

Upvotes: 1

Views: 328

Answers (1)

Patrick Collins
Patrick Collins

Reputation: 6131

setChainlinkToken is a function that tells the oracle contract what it should use to accept LINK payments. It points to an ERC677 token for the contracts to use.

You have to know what the LINK token address is to use this function.

The setPublicChainlinkToken() is a way to set the LINK token address without knowing it's address. There is an on-chain contract (on specific chains) that has a pointer to a "link token contract" registry that points to the address of the LINK token on different chains. So this function gets the address by looking at this lookup table, then calls the setChainlinkToken function with this address.


You're then getting the error you specified, because the oracle contract you're interacting with doesn't know what the address of the LINK token is.

        // if (_link == address(0)) {
        //     setPublicChainlinkToken();
        // } else {
        //     setChainlinkToken(_link);
        // }
        // setPublicChainlinkToken();

Upvotes: 2

Related Questions