Skip to main content

How It Works

The l2Read function is available through the SettlementPort contract deployed on your appchain. It takes a target address on the L2 and encoded function call data, then returns the result from the L2 contract.

Basic Usage

Here’s how to use l2Read in your appchain contract:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.29;

interface IL2Reader {
    function l2Read(address _to, bytes calldata _data) external view returns (bytes memory);
}

contract MyAppContract {
    address public immutable settlementPort;

    constructor(address _settlementPort) {
        settlementPort = _settlementPort;
    }

    function getL2TokenBalance(address tokenContract, address account) external view returns (uint256) {
        // Encode the balanceOf function call
        bytes memory data = abi.encodeWithSignature("balanceOf(address)", account);

        // Perform the L2 read
        bytes memory result = IL2Reader(settlementPort).l2Read(tokenContract, data);

        // Decode the result
        return abi.decode(result, (uint256));
    }

    function getL2ContractData(address targetContract, bytes calldata callData) external view returns (bytes memory) {
        // Direct L2 read with custom call data
        return IL2Reader(settlementPort).l2Read(targetContract, callData);
    }
}

Key Points

  • View Function: l2Read is a view function, so it doesn’t modify state
  • Synchronous: The read appears synchronous to your contract, but the data is pre-fetched by the sequencer
  • Error Handling: The function will revert if the L2 call fails

Common Use Cases

  • Reading token balances on L2
  • Checking L2 contract state
  • Accessing L2 price feeds
  • Reading L2 governance data
  • Cross-chain data validation

Integration Example

function processL2Data(address l2Contract) external view returns (bool) {
    try IL2Reader(settlementPort).l2Read(l2Contract, abi.encodeWithSignature("getStatus()")) returns (bytes memory result) {
        bool status = abi.decode(result, (bool));
        return status;
    } catch {
        // Handle L2 read failure
        return false;
    }
}
This pattern enables your appchain contracts to seamlessly integrate with L2 data while maintaining the performance benefits of your appchain.