2

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

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() "?
    – JTConsulta
    Jun 5 at 16:31
  • What are you trying to send? typically the chainlink node is going to be the one calling that function. Jun 5 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.
    – JTConsulta
    Jun 5 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 at 17:42

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.