Supported Data Types
LayerZero Read currently supports a variety of data types for reading external state via calldata
from EVMCallRequestV1
. The following types of calldata
methods are supported:
Public State Variables: Direct access to
public
state variables on target contracts.View or Pure Functions: Functions that do not modify the blockchain state and only return data.
Non-View or Pure Functions Returning Data: Functions that are not marked as
view
orpure
, but do not alter the on-chain state and only return data.
These supported data types enable developers to fetch and utilize external state data efficiently without incurring unnecessary gas costs or affecting the target blockchain's state.
Function Types
See the simple data type examples below for reference on how to implement EVMCallRequestV1
in your OAppRead
application.
State Variables
Public state variables in Solidity automatically generate getter
functions, making them easily accessible for read operations. LayerZero Read can directly interact with these getter
functions to retrieve the current state:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @title ExampleContract
* @notice A simple contract with a public state variable.
*/
contract ExampleContract {
// a public data variable on the target data chain to read from
uint256 public data;
constructor(uint256 _data) {
data = _data;
}
}
To read the data variable using lzRead
, you can encode the getter function call as follows:
bytes memory callData = abi.encodeWithSelector(ExampleContract.data.selector);
readRequests[i] = EVMCallRequestV1({
appRequestLabel: uint16(i + 1), // arbitrary request label, for OApp filtering purposes
targetEid: targetEid,
isBlockNum: false,
blockNumOrTimestamp: uint64(block.timestamp),
confirmations: 15, // Example set block confirmations to wait to 15 blocks
to: 0x1234567890123456789012345678901234567890, // Dummy address where ExampleContract is deployed
callData: callData
});
View or Pure Functions
view
and pure
functions are ideal for read operations as they do not modify the blockchain state. LayerZero Read can seamlessly interact with these functions to retrieve necessary data.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @title MathContract
* @notice A contract with a pure function for mathematical operations.
*/
contract MathContract {
/**
* @notice Adds two numbers.
* @param a First number.
* @param b Second number.
* @return sum The sum of a and b.
*/
function add(uint256 a, uint256 b) external pure returns (uint256 sum) {
return a + b;
}
}
To read the result of the add
function using lzRead
:
bytes memory callData = abi.encodeWithSelector(MathContract.add.selector, 5, 10);
readRequests[i] = EVMCallRequestV1({
appRequestLabel: uint16(i + 1),
targetEid: targetEid,
isBlockNum: false,
blockNumOrTimestamp: uint64(block.timestamp),
confirmations: 15, // Set to 15 blocks
to: 0x1234567890123456789012345678901234567890, // Dummy contract address
callData: callData
});
Non-View or Pure Functions Returning Data
Some functions are not marked as view
or pure
, but still do not modify the on-chain state. These functions can also be utilized with lzRead
as long as they only return data without performing state changes.
For example, Uniswap V3's IQuoterV2
relies on calling non-view functions and reverting to compute the result. This is not gas efficient and should not be called on-chain, making lzRead
a great option for retrieving the state:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/// @title QuoterV2 Interface
/// @notice Supports quoting the calculated amounts from exact input or exact output swaps.
/// @notice For each pool also tells you the number of initialized ticks crossed and the sqrt price of the pool after the swap.
/// @dev These functions are not marked view because they rely on calling non-view functions and reverting
/// to compute the result. They are also not gas efficient and should not be called on-chain.
interface IQuoterV2 {
/// @notice Returns the amount out received for a given exact input but for a swap of a single pool
/// @param params The params for the quote, encoded as `QuoteExactInputSingleParams`
/// tokenIn The token being swapped in
/// tokenOut The token being swapped out
/// fee The fee of the token pool to consider for the pair
/// amountIn The desired input amount
/// sqrtPriceLimitX96 The price limit of the pool that cannot be exceeded by the swap
/// @return amountOut The amount of `tokenOut` that would be received
/// @return sqrtPriceX96After The sqrt price of the pool after the swap
/// @return initializedTicksCrossed The number of initialized ticks that the swap crossed
/// @return gasEstimate The estimate of the gas that the swap consumes
function quoteExactInputSingle(QuoteExactInputSingleParams memory params)
external
returns (
uint256 amountOut,
uint160 sqrtPriceX96After,
uint32 initializedTicksCrossed,
uint256 gasEstimate
);
}
To read a quote for an amountOut
for a specific token pair function using lzRead
:
// Define the QuoteExactInputSingleParams
IQuoterV2.QuoteExactInputSingleParams memory params = IQuoterV2.QuoteExactInputSingleParams({
tokenIn: config.tokenInAddress,
tokenOut: config.tokenOutAddress,
amountIn: 1 ether, // amountIn: 1 WETH
fee: config.fee,
sqrtPriceLimitX96: 0 // No price limit
});
// @notice Encode the function call
// @dev From Uniswap Docs, this function is not marked view because it relies on calling non-view
// functions and reverting to compute the result. It is also not gas efficient and should not
// be called on-chain. We take advantage of lzRead to call this function off-chain and get the result
// returned back on-chain to the OApp's _lzReceive method.
// https://docs.uniswap.org/contracts/v3/reference/periphery/interfaces/IQuoterV2
bytes memory callData = abi.encodeWithSelector(IQuoterV2.quoteExactInputSingle.selector, params);
readRequests[i] = EVMCallRequestV1({
appRequestLabel: uint16(i + 1),
targetEid: targetEid,
isBlockNum: false,
blockNumOrTimestamp: uint64(block.timestamp),
confirmations: config.confirmations,
to: config.quoterAddress,
callData: callData
});