# IEVMTransaction

> Relay a transaction from an EVM chain.

> For the complete documentation index, see [llms.txt](/llms.txt). Markdown versions of documentation pages are available by appending `.md` to the page URL.

Source: https://dev.flare.network/fdc/reference/IEVMTransaction

An interface to relay and verify transactions from EVM-compatible blockchains.

Sourced from `IEVMTransaction.sol` on [GitHub](https://github.com/flare-foundation/flare-smart-contracts-v2/blob/main/contracts/userInterfaces/fdc/IEVMTransaction.sol).

## Overview[​](#overview "Direct link to Overview")

The IEVMTransaction interface enables smart contracts on Flare networks to access and verify transaction data from other EVM-compatible blockchains. This attestation type provides access to transaction details, including associated events (logs), allowing cross-chain verification and integration of data from external EVM chains.

## Supported Chains[​](#supported-chains "Direct link to Supported Chains")

Network Type

Supported Chains

**Mainnet**

`ETH` (Ethereum), `FLR` (Flare), `SGB` (Songbird)

**Testnet**

`testETH` (Ethereum Sepolia), `testFLR` (Flare Testnet Coston2), `testSGB` (Songbird Testnet Coston)

## Interface Definition[​](#interface-definition "Direct link to Interface Definition")

```
// SPDX-License-Identifier: MITpragma solidity >=0.7.6 <0.9;/** * @custom:name IEVMTransaction * @custom:id 0x06 * @custom:supported ETH, FLR, SGB * @author Flare * @notice A relay of a transaction from an EVM chain. * This type is only relevant for EVM-compatible chains. * @custom:verification If a transaction with the `transactionId` is in a block on the main branch with * at least `requiredConfirmations`, the specified data is relayed. * If an indicated event does not exist, the request is rejected. * @custom:lut `timestamp` * @custom:lutlimit `0x41eb00`, `0x41eb00`, `0x41eb00` */interface IEVMTransaction {    /**     * @notice Toplevel request     * @param attestationType ID of the attestation type.     * @param sourceId ID of the data source.     * @param messageIntegrityCode `MessageIntegrityCode` that is derived from the expected response.     * @param requestBody Data defining the request. Type (struct) and interpretation is     * determined by the `attestationType`.     */    struct Request {        bytes32 attestationType;        bytes32 sourceId;        bytes32 messageIntegrityCode;        RequestBody requestBody;    }    /**     * @notice Toplevel response     * @param attestationType Extracted from the request.     * @param sourceId Extracted from the request.     * @param votingRound The ID of the FDC round in which the request was considered.     * @param lowestUsedTimestamp The lowest timestamp used to generate the response.     * @param requestBody Extracted from the request.     * @param responseBody Data defining the response. The verification rules for the construction     * of the response body and the type are defined per specific `attestationType`.     */    struct Response {        bytes32 attestationType;        bytes32 sourceId;        uint64 votingRound;        uint64 lowestUsedTimestamp;        RequestBody requestBody;        ResponseBody responseBody;    }    /**     * @notice Toplevel proof     * @param merkleProof Merkle proof corresponding to the attestation response.     * @param data Attestation response.     */    struct Proof {        bytes32[] merkleProof;        Response data;    }    /**     * @notice Request body for EVM transaction attestation type     * @custom:below Note that events (logs) are indexed in block not in each transaction.     * The contract that uses the attestation should specify the order of event logs as needed and the requestor should     * sort `logIndices` with respect to the set specifications.     * If possible, the contact should require one `logIndex`.     * @param transactionHash Hash of the transaction(transactionHash).     * @param requiredConfirmations The height at which a block is considered confirmed by the requestor.     * @param provideInput If true, "input" field is included in the response.     * @param listEvents If true, events indicated by `logIndices` are included in the response.     * Otherwise, no events are included in the response.     * @param logIndices If `listEvents` is `false`, this should be an empty list, otherwise,     * the request is rejected. If `listEvents` is `true`, this is the list of indices (logIndex)     * of the events to be relayed (sorted by the requestor). The array should contain at most 50 indices.     * If empty, it indicates all events in order capped by 50.     */    struct RequestBody {        bytes32 transactionHash;        uint16 requiredConfirmations;        bool provideInput;        bool listEvents;        uint32[] logIndices;    }    /**     * @notice Response body for EVM transaction attestation type     * @custom:below The fields are in line with transaction provided by EVM node.     * @param blockNumber Number of the block in which the transaction is included.     * @param timestamp Timestamp of the block in which the transaction is included.     * @param sourceAddress The address (from) that signed the transaction.     * @param isDeployment Indicate whether it is a contract creation transaction.     * @param receivingAddress The address (to) of the receiver of the initial transaction.     * Zero address if `isDeployment` is `true`.     * @param value The value transferred by the initial transaction in wei.     * @param input If `provideInput`, this is the data send along with the initial transaction.     * Otherwise it is the default value `0x00`.     * @param status Status of the transaction 1 - success, 0 - failure.     * @param events If `listEvents` is `true`, an array of the requested events.     * Sorted by the logIndex in the same order as `logIndices`. Otherwise, an empty array.     */    struct ResponseBody {        uint64 blockNumber;        uint64 timestamp;        address sourceAddress;        bool isDeployment;        address receivingAddress;        uint256 value;        bytes input;        uint8 status;        Event[] events;    }    /**     * @notice Event log record     * @custom:above An `Event` is a struct with the following fields:     * @custom:below The fields are in line with EVM event logs.     * @param logIndex The consecutive number of the event in block.     * @param emitterAddress The address of the contract that emitted the event.     * @param topics An array of up to four 32-byte strings of indexed log arguments.     * @param data Concatenated 32-byte strings of non-indexed log arguments. At least 32 bytes long.     * @param removed It is `true` if the log was removed due to a chain reorganization     * and `false` if it is a valid log.     */    struct Event {        uint32 logIndex;        address emitterAddress;        bytes32[] topics;        bytes data;        bool removed;    }}
```

## Structs[​](#structs "Direct link to Structs")

### Request[​](#request "Direct link to Request")

Toplevel request structure.

#### Parameters[​](#parameters "Direct link to Parameters")

-   `attestationType`: ID of the attestation type (0x06 for EVMTransaction)
-   `sourceId`: ID of the data source (e.g., ETH, FLR, SGB)
-   `messageIntegrityCode`: MessageIntegrityCode derived from the expected response
-   `requestBody`: Data defining the request

### Response[​](#response "Direct link to Response")

Toplevel response structure.

#### Parameters[​](#parameters-1 "Direct link to Parameters")

-   `attestationType`: Extracted from the request
-   `sourceId`: Extracted from the request
-   `votingRound`: The ID of the FDC round in which the request was considered
-   `lowestUsedTimestamp`: The lowest timestamp used to generate the response
-   `requestBody`: Extracted from the request
-   `responseBody`: Data defining the response

### Proof[​](#proof "Direct link to Proof")

Toplevel proof structure for verification.

#### Parameters[​](#parameters-2 "Direct link to Parameters")

-   `merkleProof`: Merkle proof corresponding to the attestation response
-   `data`: Attestation response

### RequestBody[​](#requestbody "Direct link to RequestBody")

Request body specific to EVM transaction verification.

#### Parameters[​](#parameters-3 "Direct link to Parameters")

-   `transactionHash`: The hash of the transaction to relay
-   `requiredConfirmations`: Number of confirmations required for the block to be considered final
-   `provideInput`: If true, the transaction input data will be included in the response
-   `listEvents`: If true, events specified by logIndices will be included in the response
-   `logIndices`: Array of event indices to be relayed (max 50), if empty and listEvents is true, includes all events up to 50

### ResponseBody[​](#responsebody "Direct link to ResponseBody")

Response body containing transaction details.

#### Parameters[​](#parameters-4 "Direct link to Parameters")

-   `blockNumber`: Block number containing the transaction
-   `timestamp`: Timestamp of the block containing the transaction
-   `sourceAddress`: Address that signed the transaction (from)
-   `isDeployment`: True if the transaction created a contract
-   `receivingAddress`: Address receiving the transaction (to), zero address if isDeployment is true
-   `value`: Value transferred in wei
-   `input`: Transaction input data if provideInput is true, otherwise "0x00"
-   `status`: Transaction status (1 = success, 0 = failure)
-   `events`: Array of requested events if listEvents is true, otherwise empty

### Event[​](#event "Direct link to Event")

Structure representing a transaction event (log).

#### Parameters[​](#parameters-5 "Direct link to Parameters")

-   `logIndex`: Index of the event within the block
-   `emitterAddress`: Contract address that emitted the event
-   `topics`: Array of indexed event parameters (up to 4)
-   `data`: Non-indexed event parameters, concatenated as 32-byte strings
-   `removed`: True if the event was removed due to a chain reorganization

## Implementation Notes[​](#implementation-notes "Direct link to Implementation Notes")

-   Attestation ID: `0x06`
-   The `lowestUsedTimestamp` parameter uses the value of `timestamp`
-   The `lutlimit` (Lowest Used Timestamp limit) is `0x41eb00` (4,300,800 seconds = ~50 days) for all supported chains
-   Events are indexed at the block level, not at the transaction level
-   Maximum of 50 events can be included in a single attestation

## Event Handling[​](#event-handling "Direct link to Event Handling")

When working with events, it's important to remember:

1.  Events (logs) are indexed at the **block level**, not at the transaction level
2.  The order of events in `logIndices` should follow the requirements of the consuming contract
3.  If `listEvents` is set to false, `logIndices` must be an empty array
4.  If `listEvents` is true but `logIndices` is empty, all events up to a maximum of 50 will be included
5.  Events are returned in the same order as specified in `logIndices`

## Usage Example[​](#usage-example "Direct link to Usage Example")

EVMTransactionVerifier.sol

```
// SPDX-License-Identifier: MITpragma solidity ^0.8.25;import {ContractRegistry} from "@flarenetwork/flare-periphery-contracts/coston2/ContractRegistry.sol";import {IFdcVerification} from "@flarenetwork/flare-periphery-contracts/coston2/IFdcVerification.sol";import {IEVMTransaction} from "@flarenetwork/flare-periphery-contracts/coston2/IEVMTransaction.sol";contract EVMTransactionVerifier {    // A struct to hold the data from a verified ERC-20 transfer    struct VerifiedTransfer {        address tokenContract;        address from;        address to;        uint256 amount;        bytes32 transactionHash;    }    // An array to store all transfers verified by this contract    VerifiedTransfer[] public verifiedTransfers;    // The signature of the ERC-20 Transfer event    bytes32 private constant EVENT_TRANSFER_SIGNATURE =        keccak256(abi.encodePacked("Transfer(address,address,uint256)"));    event TransferVerified(        bytes32 indexed transactionHash,        address indexed tokenContract,        address from,        address to,        uint256 amount    );    function processTransactionProof(        IEVMTransaction.Proof calldata _proof,        address _tokenContract    ) external {        // 1. FDC Logic: Verify the proof's authenticity with the Flare network.        require(isProofValid(_proof), "Invalid EVM transaction proof");        require(            _proof.data.responseBody.status == 1,            "Transaction reverted or not found"        );        // 2. Business Logic: Iterate through events to find and record ERC-20 transfers.        IEVMTransaction.Event[] memory events = _proof.data.responseBody.events;        bytes32 txHash = _proof.data.requestBody.transactionHash;        for (uint i = 0; i < events.length; i++) {            IEVMTransaction.Event memory evt = events[i];            // Filter for the specific token contract if provided            if (                _tokenContract != address(0) &&                evt.emitterAddress != _tokenContract            ) {                continue;            }            // Check if the event is an ERC-20 Transfer: Transfer(address,address,uint256)            if (                evt.topics.length == 3 &&                evt.topics[0] == EVENT_TRANSFER_SIGNATURE            ) {                // Decode the event data                address from = address(uint160(uint256(evt.topics[1])));                address to = address(uint160(uint256(evt.topics[2])));                uint256 amount = abi.decode(evt.data, (uint256));                // Record the verified transfer                verifiedTransfers.push(                    VerifiedTransfer({                        tokenContract: evt.emitterAddress,                        from: from,                        to: to,                        amount: amount,                        transactionHash: txHash                    })                );                emit TransferVerified(                    txHash,                    evt.emitterAddress,                    from,                    to,                    amount                );            }        }    }    function isProofValid(        IEVMTransaction.Proof memory _proof    ) public view returns (bool) {        IFdcVerification fdcVerification = ContractRegistry            .getFdcVerification();        return fdcVerification.verifyEVMTransaction(_proof);    }}
```

[

Open example in Remix

](https://remix.ethereum.org/#url=https://github.com/flare-foundation/developer-hub/blob/main/examples/developer-hub-solidity/EVMTransactionVerifier.sol&version=builtin&evmVersion=cancun&optimize=true&runs=200)
