3

I need to call a function that returns the uint value requested by the oracle from another contract function.

I am trying the next... but I think I am going by the bad way. Any solution for that?

The Caller contract code:

pragma solidity 0.5.1;
// SPDX-License-Identifier: UNLICENSED

contract ETHPriceContract{ function getETHPrice() public view returns(bytes32);} 

contract CallerPriceRequest{
    
    uint256 public price;

    ETHPriceContract internal ETHPriceOracle;
 
    function initETHPrice(address ETHPriceAddress) public {
        ETHPriceOracle = ETHPriceContract( ETHPriceAddress );
    }
    
    function getETHPrice() public{
        ETHPriceOracle.getETHPrice();
    }
    
    function CallerFulfill(bytes32 _requestId, uint256 _price) public{
        price = _price;
    } 
}

The Oracle requester contract code:

pragma solidity ^0.5.1;

import "https://raw.githubusercontent.com/smartcontractkit/chainlink/develop/evm-contracts/src/v0.5/ChainlinkClient.sol";

// SPDX-License-Identifier: UNLICENSED

contract CallerPriceRequest{ function CallerFulfill(bytes32 _requestId, uint256 _price) public; }

contract ChainlinkRequestETHPrice is ChainlinkClient {
    
    address public CallerAddress = 0x5592675bf651ED82E30F78D5ebAfb1f7F5D851c7;
    uint256 public price;
    
    address private oracle;
    bytes32 private jobId;
    uint256 private fee;
    
    CallerPriceRequest internal Caller;
    
    constructor() public {
        Caller = CallerPriceRequest( CallerAddress );
        setPublicChainlinkToken();
        oracle = 0x2f90A6D021db21e1B2A077c5a37B3C7E75D15b7e;
        jobId = "29fa9aa13bf1468788b7cc4a500a45b8";
        fee = 0.1 * 10 ** 18; // 0.1 LINK
    }


    function getETHPrice() public returns (bytes32 requestId){
        Chainlink.Request memory req = buildChainlinkRequest(jobId, CallerAddress, Caller.CallerFulfill.selector);
        req.add("get", "https://min-api.cryptocompare.com/data/price?fsym=ETH&tsyms=USD");//{"USD":1797.12}
        req.add("path", "USD");
        req.addInt("times", 100);
        return sendChainlinkRequestTo(oracle, req, fee);
    }

}

1 Answer 1

2

The buildChainlinkRequest takes 3 parameters:

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

Add your caller contract to be the callback contract. Like so:

In the calling contract, pass the address of the callback address and the callback function. You could also just hardcode the addresses in the calling contract.

function getETHPrice() public{
        ETHPriceOracle.getETHPrice(address(this), this.CallerFulfill.selector);
    }

Then, use those parameters in the calling function:

 function getETHPrice(address callBackContract, bytes4 functionSelector) public returns (bytes32 requestId){
        Chainlink.Request memory req = buildChainlinkRequest(jobId, callBackContract, functionSelector);
// code here
    }
4
  • Thank you Patrick. Works in basics. How can I send parameters to the "CallerFulfill()" from the caller "getETHPrice() "?
    – JTCon
    Jun 5, 2021 at 16:31
  • What are you trying to send? typically the chainlink node is going to be the one calling that function. Jun 5, 2021 at 16:36
  • I need to request the ETHPrice from Caller and send my equivalent token amount to an address (msg.sender) and a fee amount to other address sent to the getETHPrice(address) function. I want to make all in one call.
    – JTCon
    Jun 5, 2021 at 17:16
  • In your function getETHPrice() public{ ETHPriceOracle.getETHPrice(address(this), this.CallerFulfill.selector); } function, you can just pass more parameters to the callee contract, and have that function pass variables to the fulfill function. Jun 5, 2021 at 17:42

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.