docs
CrossChain calls
Setup Inputs

Setup Inputs for CrossChain Calls

eyeOracle, in addition to making external API requests, is also capable of performing cross-chain requests to contracts on different blockchains. This is very useful when a specific piece of data is needed or when it is necessary to call a specific function in a contract on a different blockchain.

In this section, you will learn how to prepare your RequestContractCall object to perform cross-blockchain function calls.

OracleRequest.sol
    struct RequestContractCall {
        string requestCallType; // <-- Avaliable options 'view' or 'state'
        string jsonAbi; // <-- Abi of the function you want to call 
        string targetContractAddress; // <-- Target contract address 
        string targetChainId; // <-- Target ChainId (uses same Id as metamask) for ex for sepolia pass "11155111"
        string jsonInputParams; // <-- Input params of your call, 
    }

Json ABI

For any call to a contract, the following are primarily required:

  • Contract address.
  • ABI of the function to be called.

When calling the function responsible for invoking an external function on another blockchain, eyeOracle will only need the target address of the contract and the ABI of the specific function to be called; DO NOT USE the entire ABI of the contract, or the oracle will return an error. This is designed to simplify calls and optimize gas usage in the requests.

Let's assume we want to call a function of this ultra-simple contract:

pragma solidity ^0.8.19;
 
contract ExampleTargetContract {
    uint256 public testerUint = 666;
    string public testerString = 'hello';
}

you can extract the Abi json and you will get:

"abi": [
    {
      "inputs": [],
      "name": "testerString",
      "outputs": [
        {
          "internalType": "string",
          "name": "",
          "type": "string"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    },
    {
      "inputs": [],
      "name": "testerUint",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    }
  ],

In this case, if you only want to call TesterUint, then we’ll only use the ABI related to the function that retrieves the uint256, and then convert it to a JSON string using JavaScript, for example:

const targetFunctionAbi ={
      "inputs": [],
      "name": "testerUint",
      "outputs": [
        {
          "internalType": "uint256",
          "name": "",
          "type": "uint256"
        }
      ],
      "stateMutability": "view",
      "type": "function"
    }
 
const jsonFunctionAbi = JSON.stringify(targetFunctionAbi);
 

Now you can use jsonFunctionAbi in the function parameter to pass it to the encoder before sending it to the oracle.

ExampleContract.sol
    function exampleSendRequestCallContractView(
        uint256 fulfillGasUsed,
        string memory _jsonAbi, //<-- You can use jsonFunctionAbi here
        string memory _targetChainId,
        string memory _targetContractAddress,
        string memory _jsonInputParams
    ) external payable nonReentrant {
        uint256 gasCost = gasCostFulfill(fulfillGasUsed);
        require(
            msg.value > gasCost,
            "ETH sent is less than gas cost for the callback"
        );
 
        OracleRequest.RequestContractCall memory req;
 
        req.jsonAbi = _jsonAbi; //<-- This will add ABI to request struct, allowing oracle to use it
        req.targetChainId = _targetChainId;
        req.targetContractAddress = _targetContractAddress;
        req.jsonInputParams = _jsonInputParams;
 
        bytes memory requestData = req.encodeCrossChainCallCBOR();
 
        uint256 requestId = _sendRequest(requestData, fulfillGasUsed); //this will emit a event on OracleRouter that nodes will caputure
    }

jsonInput Parameters

To pass the inputs to the function you want to call, we will use the same nomenclature that we usually use for making API calls, that is, a JSON string of the inputs array. For example:

This is correct

'["0","0x8542743bfB9F49f378366662A3a96215F7A45Ae1"]';

This is wrong

"['0','0x8542743bfB9F49f378366662A3a96215F7A45Ae1']";

Note --> Since the ABI is also being passed, it is not necessary to specify the data types of the inputs, as eyeOracle can derive them from the ABI itself. All the data within the jsonString will be passed as strings.

At this time, you can also pass an array as an argument; however, eyeOracle cannot yet process arrays with more than one level of depth.

For example, you can pass an array as agument:

'[["0x8542743bfB9F49f378366662A3a96215F7A45Ae1","0x1A19EC530055635F366B54a37c711C5174f2219F"],"1"]';