Cant see the (Chainlink)requested data in my smartcontract

68 Views Asked by At

I'm trying to get data in my smartcontract, with is fetched from a Chainlink external adapter:

fetch bridge "{"data":{"result":{"id":"UCAl9Ld79qaZxp9JzEOwd3aA","statistics":{"subscriberCount":"209000"}}},"jobRunId":"0x84aae6f7b7144fbc8196230158918797","statusCode":200}"

name: yutu

requestData: {"id": $(jobSpec.externalJobID), "data": { "chid": $(decode_cbor.chid)},"key": $(decode_cbor.key)}

parse jsonparse "209000"

path: data,result,statistics,subscriberCount

data: $(fetch)

encode_data ethabiencode "0x0000000000000000000000000000000000000000000000000000000000033068"

abi: (uint256 value)

data: { "value": $(parse) }

encode_tx ethabiencode "0x4ab0d1902a02a37be17119894c2d9400f9bcf563bd4be47496af9a493a96eb412676916c0000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000002e495ea15b191aff2dea171abba537dc597d6f117642d37500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006571ad180000000000000000000000000000000000000000000000000000000000033068"

abi: fulfillOracleRequest(bytes32 requestId, uint256 payment, address callbackAddress, bytes4 callbackFunctionId, uint256 expiration, bytes32 data)

data: {"requestId": $(decode_log.requestId), "payment": $(decode_log.payment), "callbackAddress": $(decode_log.callbackAddr), "callbackFunctionId": $(decode_log.callbackFunctionId), "expiration": $(decode_log.cancelExpiration), "data": $(encode_data)}

submit_tx ethtx to: 0x34b33d85A6a642A6Eaa1fE554f576c6122FF64b6

data: $(encode_tx)

I'm trying to get the subscribercount in the below smartcontract: // 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";

/**

  • THIS IS AN EXAMPLE CONTRACT THAT USES UN-AUDITED CODE.
  • DO NOT USE THIS CODE IN PRODUCTION. */

contract ConsumerContract is ChainlinkClient, ConfirmedOwner { using Chainlink for Chainlink.Request;

uint256 private constant ORACLE_PAYMENT = 1 * LINK_DIVISIBILITY; // 1 * 10**18
uint256 public lastRetrievedSubscriberCount;

event RequestForSubscriberCountFulfilled(
    bytes32 indexed requestId,
    uint256 indexed subscriberCount
);

/**
 *  Goerli
 * @dev LINK address in Sepholia network: 0x779877A7B0D9E8603169DdbD7836e478b4624789
 * @dev Check https://docs.chain.link/docs/link-token-contracts/ for LINK address for the right network
 */
constructor() ConfirmedOwner(msg.sender) {
    setChainlinkToken(0x779877A7B0D9E8603169DdbD7836e478b4624789);
}

function requestSubscriberCount(
    address _oracle,
    string memory _jobId,
    string memory channelId,
    string memory apiKey
) public onlyOwner {
    Chainlink.Request memory req = buildOperatorRequest(
        stringToBytes32(_jobId),
        this.fulfillRequestInfo.selector
    );

    req.add("chid", channelId);
    req.add("key", apiKey);
    sendOperatorRequestTo(_oracle, req, ORACLE_PAYMENT);
}

function fulfillRequestInfo(bytes32 _requestId, string memory _info)
    public
    recordChainlinkFulfillment(_requestId)
{
    // Parse the JSON data to extract the subscriberCount
    (uint256 subscriberCount, ) = abi.decode(bytes(_info), (uint256, uint256));

    emit RequestForSubscriberCountFulfilled(_requestId, subscriberCount);
    lastRetrievedSubscriberCount = subscriberCount;
}

function getSubscriberCount() public view returns (uint256) {
    return lastRetrievedSubscriberCount;
}

/*
========= UTILITY FUNCTIONS ==========
*/

function contractBalances()
    public
    view
    returns (uint256 eth, uint256 link)
{
    eth = address(this).balance;

    LinkTokenInterface linkContract = LinkTokenInterface(
        chainlinkTokenAddress()
    );
    link = linkContract.balanceOf(address(this));
}

function getChainlinkToken() public view returns (address) {
    return chainlinkTokenAddress();
}

function withdrawLink() public onlyOwner {
    LinkTokenInterface link = LinkTokenInterface(chainlinkTokenAddress());
    require(
        link.transfer(msg.sender, link.balanceOf(address(this))),
        "Unable to transfer Link"
    );
}

function withdrawBalance() public onlyOwner {
    payable(msg.sender).transfer(address(this).balance);
}

function cancelRequest(
    bytes32 _requestId,
    uint256 _payment,
    bytes4 _callbackFunctionId,
    uint256 _expiration
) public onlyOwner {
    cancelChainlinkRequest(
        _requestId,
        _payment,
        _callbackFunctionId,
        _expiration
    );
}

function stringToBytes32(string memory source)
    private
    pure
    returns (bytes32 result)
{
    bytes memory tempEmptyStringTest = bytes(source);
    if (tempEmptyStringTest.length == 0) {
        return 0x0;
    }

    assembly {
        // solhint-disable-line no-inline-assembly
        result := mload(add(source, 32))
    }
}

}

2

There are 2 best solutions below

2
On BEST ANSWER

Can you point us to your request transaction, and the oracle address to which you are making it?

Based on context, I am assuming you are making a request against Chainlink's ETH Sepolia testnet oracle at 0x34b33d85a6a642a6eaa1fe554f576c6122ff64b6.

Based on the timing of your question, I am assuming that one of these failed oracle fulfill transactions is yours:

  1. https://sepolia.etherscan.io/tx/0x7a440e81964e7552ba7784d7246fdd6b35b310f910c3639a8f88372e007640a4
  2. https://sepolia.etherscan.io/tx/0x45862741e98669d733f6645f53b2078ab9359d9f0a46798ccab26d87ce6ba29a
  3. https://sepolia.etherscan.io/tx/0xac2ce4aca4fbe7fff50234c3de568a4dbdaeea249a7e881d9f46152f4e93a7f5
  4. https://sepolia.etherscan.io/tx/0xa50050fb9c77b40ebcb22dad25f095c4c9bdbd7ee22f52ffd2aa7f1e87c9d2ed

If you look at any of the above fulfill transactions, you'll see the contract execution error Data versions must match.

Looking at the Operator.sol (oracle) contract, here is the failed condition: https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.7/Operator.sol#L480

What version of ChainlinkClient.sol are you importing into your smart contract? I suggest you use the latest version to see if this makes a difference here.

1
On

I'm almost sure something is wrong with my way to encode the fetched data in the TOML job:

parse        [type=jsonparse path="data,result,statistics,subscriberCount" data="$(fetch)"]
        encode_data  [type=ethabiencode abi="(bytes32 requestId,string info)" data="{\\"requestId\\": $(decode_log.requestId),\\"info\\": $(parse) }"]
        encode_tx    [type=ethabiencode
                      abi="fulfillOracleRequest2(bytes32 requestId, uint256 payment, address callbackAddress, bytes4 callbackFunctionId, uint256 expiration, bytes calldata data)"
                      data="{\\"requestId\\": $(decode_log.requestId), \\"payment\\": $(decode_log.payment), \\"callbackAddress\\": $(decode_log.callbackAddr), \\"callbackFunctionId\\": $(decode_log.callbackFunctionId), \\"expiration\\": $(decode_log.cancelExpiration), \\"data\\": $(encode_data)}"]
        submit_tx    [type=ethtx to="0x34b33d85A6a642A6Eaa1fE554f576c6122FF64b6" data="$(encode_tx)"]
    
        decode_log -> decode_cbor -> fetch -> parse -> encode_data -> encode_tx -> submit_tx
    """