0

The buildChainlinkRequest line no 47 takes 3 parameters:

  1. JobId
  2. Callback Address
  3. Function to callback to

I have smartcontract1 and smartcontract2. The below mentioned function is inside smartcontract2

function requestVolumeData(string memory _jobId, string memory addrsss, address callBackContract, bytes4 functionSelector) external returns (bytes32 requestId) {
   
    Chainlink.Request memory req = buildChainlinkRequest(
        stringToBytes32(_jobId),
        callBackContract,
        functionSelector
    );

    req.add("publicKey", addrsss);
    return sendChainlinkRequest(req, fee);
}

Code inside smartcontract1 given below,

interface OracleInterfacehere{
 function requestVolumeData(string memory _jobId, string memory addrsss, address callBackContract, bytes4 functionSelector) external returns (bytes32) ;
}


 function requestingdataFromOracle(string memory _jobId, string memory addrsss, address _smartcontract2) public  {
      OracleInterfacehere OracleOwnerGuard = OracleInterfacehere(_smartcontract2);
      OracleOwnerGuard.requestVolumeData(_jobId, addrsss,address(this), this.fulfill.selector);
 }

  function fulfill(
    bytes32 _requestId,
    bool _status
) public recordChainlinkFulfillment(_requestId) {
    status = _status;
}

What I am expecting is as smartcontract1 call "requestVolumeData" (inside smartcontract2) function, the oracle will send data back to "fulfill" function of smartcontract1. But this is not working as expected

Note : I have followed this approach(Mentioned in the answer by Patrick) StackExchange question

8
  • To clarify, are you saying in smartcontract1 if you pass through address(this) and this.fulfill.selector into your call of smartcontract2's buildChianlinkRequest that things are working? This sounds like the proper way to format the request.
    – Richard G
    Commented Mar 22, 2023 at 13:25
  • No, in smartcontract1 if i pass through address(this) and this.fulfill.selector into my call of smartcontract2's buildChianlinkRequest that things is not working. BUT, if I write these arguments in smartcontract2 buildChianlinkRequest itself, then its working fine
    – Dummy Mail
    Commented Mar 22, 2023 at 13:57
  • Could you update the question with the code you are using that isn't working
    – Richard G
    Commented Mar 22, 2023 at 14:45
  • Updated the question.
    – Dummy Mail
    Commented Mar 22, 2023 at 15:14
  • A couple more things to check. 1. Make sure both SmartContract1 and SmartContract2 have the necessary imports and are inheriting from the ChainlinkClient contract. 2. You mention requestVolumeData but are calling requestVolumeDataNext is that on purpose?
    – Richard G
    Commented Mar 23, 2023 at 0:11

3 Answers 3

1
Chainlink.Request memory req = buildChainlinkRequest(
        stringToBytes32(_jobId),
        callBackContract,
        functionSelector
 );

This function is present in the ChainlinkClient contract that you would be using but this is not the issue in the code.

When you call the function sendChainlinkRequest which is also present in the same contract and is the problem.

This functions body actually saves the address from which this function is actually called

bytes memory encodedRequest = abi.encodeWithSelector(
      ChainlinkRequestInterface.oracleRequest.selector,
      SENDER_OVERRIDE, // Sender value - overridden by onTokenTransfer by the requesting contract's address
      AMOUNT_OVERRIDE, // Amount value - overridden by onTokenTransfer by the actual amount of LINK sent
      req.id,
      address(this),
      req.callbackFunctionId,
      nonce,
      ORACLE_ARGS_VERSION,
      req.buf.buf
    );
5
  • Should i override it to "req.callbackAddress"? I thought security is a big concern while updating the chainlink smart contract.
    – Dummy Mail
    Commented Mar 24, 2023 at 8:37
  • If I'm understanding Lokesh the overrides would need to be the values for SC1. "This functions body actually saves the address from which this function is actually called" You'll need to pass in the proper address and callback. Can you share more of the code to show where you are passing the req in?
    – Richard G
    Commented Mar 27, 2023 at 0:36
  • @RichardG i have added more lines of code. Also please note I am following exactly the same approach mentioned here same question asked here
    – Dummy Mail
    Commented Mar 27, 2023 at 2:11
  • @RichardG even if i hardcode the value of callBackContract(address of smartcontract1) and pass it to requestVolumeData function of smartcontract2, then also its not working.
    – Dummy Mail
    Commented Mar 27, 2023 at 7:45
  • 1
    I have a smart contract built where I save the contract address as well as the callbackFunction signature while making the request. requestDetails[requestId] = RequestContractDetails({ responseContract: callerContract, responseFunctionId: callbackFunctionId }); And in the fulfil function: address callerAddress = requestDetails[requestId].responseContract; bytes4 callbackFunctionSignature = requestDetails[requestId].responseFunctionId; (bool success, ) = callerAddress.call(abi.encodeWithSelector(callbackFunctionSignature, requestId, data)); Commented Mar 28, 2023 at 18:56
0

I'm sorry to hear that the buildChainlinkRequest function is not working properly. Have you tried restarting the application or checking the logs to see if there are any errors? If you are still having trouble, please reach out to the Chainlink support team for more assistance.

2
  • yes i have restarted the system. no error logs. The only issue is that the "fulfill" function in smartcontract1 is not giving the result even after everything runs fine. If inside smartcontract2(sc2), requestVolumeData have address(this) (of sc2) and this.fulfill.selector (of sc2), then things works fine. Also I am exactly following the answer mentioned here . not sure whats the issue
    – Dummy Mail
    Commented Mar 23, 2023 at 6:44
  • Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
    – Community Bot
    Commented Mar 23, 2023 at 19:50
0

Can you remove the recordChainlinkFulfillment() modifier from the fulfill() function? One thing this modifier limits is who can call the function. When you call sendChainlinkRequest, it adds the oracle contract to the allow list.

I believe the issue is that SC2 knows about the address, but SC1 does not.

If you do this, anyone can call fulfill(). If you need to limit that, you could hardcode the oracle address or pass it through from SC2.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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