0

Loading the fetch code from documentation: https://docs.chain.link/docs/api-array-response/

This particular example fetched string id from that endpoint, works fine...

If instead of fetching the string id, I try to fetch current price, the fetch fails, price always displays 0

I'm using remix

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

import '@chainlink/contracts/src/v0.8/ChainlinkClient.sol';
import '@chainlink/contracts/src/v0.8/ConfirmedOwner.sol';

/**
 * Request testnet LINK and ETH here: https://faucets.chain.link/
 * Find information on LINK Token Contracts and get the latest ETH and LINK faucets here: https://docs.chain.link/docs/link-token-contracts/
 */

/**
 * THIS IS AN EXAMPLE CONTRACT WHICH USES HARDCODED VALUES FOR CLARITY.
 * PLEASE DO NOT USE THIS CODE IN PRODUCTION.
 */
contract FetchFromArray is ChainlinkClient, ConfirmedOwner {
    using Chainlink for Chainlink.Request;

    uint public price;

    bytes32 private jobId;
    uint256 private fee;

    event RequestPrice(bytes32 indexed requestId, uint price);

    /**
     * @notice Initialize the link token and target oracle
     *
     * Rinkeby Testnet details:
     * Link Token: 0x01BE23585060835E02B77ef475b0Cc51aA1e0709
     * Oracle: 0xf3FBB7f3391F62C8fe53f89B41dFC8159EE9653f (Chainlink DevRel)
     * jobId: 7d80a6386ef543a3abb52817f6707e3b
     *
     */
    constructor() ConfirmedOwner(msg.sender) {
        setChainlinkToken(0x01BE23585060835E02B77ef475b0Cc51aA1e0709);
        setChainlinkOracle(0xf3FBB7f3391F62C8fe53f89B41dFC8159EE9653f);
        jobId = '7d80a6386ef543a3abb52817f6707e3b';
        fee = (1 * LINK_DIVISIBILITY) / 10; // 0,1 * 10**18 (Varies by network and job)
    }

    /**
     * Create a Chainlink request to retrieve API response, find the target
     * data which is located in a list
     */
    function requestPrice() public returns (bytes32 requestId) {
        Chainlink.Request memory req = buildChainlinkRequest(jobId, address(this), this.fulfill.selector);

        // Set the URL to perform the GET request on
        // API docs: https://www.coingecko.com/en/api/documentation?
        req.add('get', 'https://api.coingecko.com/api/v3/coins/markets?vs_currency=usd&per_page=1');

        // Set the path to find the desired data in the API response, where the response format is:
        // [{
        //  "id": "bitcoin",
        //  "symbol": btc",
        //  "current_price": 22555,
        // ...
        // },
        //{
        // ...
        // .. }]
        // request.add("path", "0.id"); // Chainlink nodes prior to 1.0.0 support this format
        req.add('path', '0,current_price'); // Chainlink nodes 1.0.0 and later support this format
        // Sends the request
        return sendChainlinkRequest(req, fee);
    }

    /**
     * Receive the response in the form of string
     */
    function fulfill(bytes32 _requestId, uint _current_price) public recordChainlinkFulfillment(_requestId) {
        emit RequestPrice(_requestId, _current_price);
        price = _current_price;
    }

    /**
     * Allow withdraw of Link tokens from the contract
     */
    function withdrawLink() public onlyOwner {
        LinkTokenInterface link = LinkTokenInterface(chainlinkTokenAddress());
        require(link.transfer(msg.sender, link.balanceOf(address(this))), 'Unable to transfer');
    }
}


1 Answer 1

0

This is for a couple of reasons. You're using a job ID that returns a string but what you're trying to get back is a uint256. You referred to https://docs.chain.link/docs/api-array-response/ which returns a string value pulled out of the data object returned by the API call.

Instead you want a uint256. You can get the correct JobIDs for the testnet oracles from this link

Change as follows:

// jobId = '7d80a6386ef543a3abb52817f6707e3b'; --> returns string
jobId = 'ca98366cc7314957b8c012c72f05aeeb'; ----> returns uint256

This jobId is used in this example but note that the tasks/steps are a bit different.

At the URL that sets out the JobIds, the table under "JOBS" includes the a "TASKS" column that specifies the tasks (steps) to be done. When you return a uint256 you need to include an additional task in your code - the Multiply Task (its linked in the table).

So to yourrequestPrice() method you need to also add:

...

req.add('path', '0,current_price'); // Chainlink nodes 1.0.0 and later support this format

// Multiply the result by 1 to get the int returned in the response.
req.addInt('times', 1);        ---------> add this
...

The addInt method documentation is here

By making these two changes I was able to make it work.

1
  • Thank you, exactly right!
    – stack5
    Jul 29 at 6:54

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.