0

I am trying to use a chainlink request to make an api call, then update the volume variable with the result of the api call.

The api call should retrieve a string. After deploying and funding the smart contract it seems I am able to make the api call successfully (although I'm not sure about this). The problem is the volume variable isn't updating.

I adapted the code from a chainlink tutorial. The original tutorial code works, to my mind the changes I made should also work. Can anyone help with this?

contract APIConsumer is ChainlinkClient {
using Chainlink for Chainlink.Request;

string public volume;

address private oracle;
bytes32 private jobId;
uint256 private fee;

/**
 * Network: Kovan
 * Oracle: 0xc57B33452b4F7BB189bB5AfaE9cc4aBa1f7a4FD8 (Chainlink Devrel   
 * Node)
 * Job ID: d5270d1c311941d0b08bead21fea7747
 * Fee: 0.1 LINK
 */
constructor() {
    setPublicChainlinkToken();
    oracle = 0xF405B99ACa8578B9eb989ee2b69D518aaDb90c1F;
    jobId = "c51694e71fa94217b0f4a71b2a6b565a";
    fee = 0.1 * 10 ** 18; // (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
    request.add("get", "https://min-api.cryptocompare.com/data/pricemultifull?fsyms=ETH&tsyms=USD");
    
    // 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", "RAW.ETH.USD.MARKET");
    
    // // 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, bytes32 _volume) public recordChainlinkFulfillment(_requestId)
{
    volume = bytes32ToString(_volume);
    
}


function bytes32ToString(bytes32 _bytes32) public pure returns (string memory) {
    uint8 i = 0;
    while(i < 32 && _bytes32[i] != 0) {
        i++;
    }
    bytes memory bytesArray = new bytes(i);
    for (i = 0; i < 32 && _bytes32[i] != 0; i++) {
        bytesArray[i] = _bytes32[i];
    }
    return string(bytesArray);
}

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

}

0

To return a string, you actually have to return a bytes32 and cast it to a string on-chain.

You can use something like this, to turn a bytes32 to string:

function bytes32ToString(bytes32 _bytes32) public pure returns (string memory) {
        uint8 i = 0;
        while(i < 32 && _bytes32[i] != 0) {
            i++;
        }
        bytes memory bytesArray = new bytes(i);
        for (i = 0; i < 32 && _bytes32[i] != 0; i++) {
            bytesArray[i] = _bytes32[i];
        }
        return string(bytesArray);
    }

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.