# SDK Reference: EVM Client
Source: https://docs.chain.link/cre/reference/sdk/evm-client-go
Last Updated: 2026-02-16

> For the complete documentation index, see [llms.txt](/llms.txt).

This page provides a reference for the `evm.Client`, the low-level tool for all interactions with EVM-compatible blockchains. The client includes a comprehensive set of read, write, and utility methods for building chain-aware workflows.

> **NOTE: EVM Client and bindings**
>
> The `evm.Client` provides the foundational methods for all onchain interactions. It is highly recommended to wrap its
> usage in a type-safe "binding" for your specific smart contracts. Your binding will use this generic client internally
> to handle ABI encoding and decoding, making your workflow code cleaner and safer. See the [Generating
> Bindings](/cre/guides/workflow/using-evm-client/generating-bindings) guide for more details.

## Client instantiation

To use the client, you must instantiate it with the `ChainSelector` ID for the blockchain you intend to interact with.

```go
import "github.com/smartcontractkit/cre-sdk-go/capabilities/blockchain/evm"

// Instantiate a client for Ethereum Sepolia
sepoliaClient := &evm.Client{
    ChainSelector: 16015286601757825753, // ethereum-testnet-sepolia
}
```

> **NOTE: What is a Chain Selector?**
>
> A Chain Selector is a unique identifier for a blockchain network. It is used to select the correct blockchain client
> for the workflow. See the [Chain Selectors](#chain-selectors) section below for a complete list of supported networks
> and usage examples.

For chains that have a constant defined in the SDK, you can also use the `ChainSelectorFromName` helper for improved readability. See the [Chain Selectors](#chain-selectors) section for a full list of available constants.

```go
// Alternatively, use the ChainSelectorFromName helper for better readability
sepoliaSelector, err := evm.ChainSelectorFromName("ethereum-testnet-sepolia")

sepoliaClient := &evm.Client{
    ChainSelector: sepoliaSelector,
}
```

## Read & query methods

These methods are used to read data from the blockchain without creating a transaction.

### `CallContract`

Executes a `view` or `pure` function on a smart contract. To use this function, you construct an `evm.CallContractRequest` object, which holds the details of your call. The function returns a promise that resolves to an `evm.CallContractReply` containing the data returned by the contract.

**Signature:**

```go
func (c *Client) CallContract(runtime cre.Runtime, input *CallContractRequest) cre.Promise[*CallContractReply]
```

#### `evm.CallContractRequest`

This is the main input object for the `CallContract` function. It acts as a wrapper for the call message and an optional block number.

| Field         | Type           | Description                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| ------------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Call`        | `*evm.CallMsg` | Contains the actual details of the function call you want to make.                                                                                                                                                                                                                                                                                                                                                                             |
| `BlockNumber` | `*pb.BigInt`   | Optional. The block number to query. Accepts:<br />• `nil` or `-2` (default): `latest` — the most recent block<br />• `-3`: `finalized` — an immutable block<br />• **Any positive integer**: an explicit block height (see [Custom Block Depths](/cre/guides/workflow/using-evm-client/onchain-read-go#custom-block-depths) for examples)<br /><br />See [Finality and Confidence Levels](/cre/concepts/finality-go) for finality strategies. |

#### `evm.CallMsg`

This struct contains the core details of your onchain call.

| Field  | Type     | Description                                                                                       |
| ------ | -------- | ------------------------------------------------------------------------------------------------- |
| `From` | `[]byte` | Optional. The 20-byte address of the sender.                                                      |
| `To`   | `[]byte` | The 20-byte address of the target contract.                                                       |
| `Data` | `[]byte` | The ABI-encoded byte string for the function call, including the function selector and arguments. |

#### `evm.CallContractReply`

This is the object returned by the promise when the `CallContract` function successfully completes.

| Field  | Type     | Description                                         |
| ------ | -------- | --------------------------------------------------- |
| `Data` | `[]byte` | The ABI-encoded data returned by the contract call. |

### `BalanceAt`

Retrieves the native token balance for a specific account. You provide the account address in an `evm.BalanceAtRequest`, and the function returns a promise that resolves to an `evm.BalanceAtReply` containing the balance.

**Signature:**

```go
func (c *Client) BalanceAt(runtime cre.Runtime, input *BalanceAtRequest) cre.Promise[*BalanceAtReply]
```

#### `evm.BalanceAtRequest`

| Field         | Type         | Description                                                                                                                                                                                                                                                                                                                            |
| ------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `Account`     | `[]byte`     | The 20-byte address of the account to query.                                                                                                                                                                                                                                                                                           |
| `BlockNumber` | `*pb.BigInt` | Optional. The block number to query. Accepts `nil` or `-2` for `latest` (default), `-3` for `finalized`, or any positive integer for an explicit block height (see [Custom Block Depths](/cre/guides/workflow/using-evm-client/onchain-read-go#custom-block-depths)). See [Finality and Confidence Levels](/cre/concepts/finality-go). |

#### `evm.BalanceAtReply`

| Field     | Type         | Description                        |
| --------- | ------------ | ---------------------------------- |
| `Balance` | `*pb.BigInt` | The balance of the account in Wei. |

### `FilterLogs`

Queries historical event logs that match a specific set of filter criteria defined in an `evm.FilterLogsRequest`. The function returns a promise that resolves to an `evm.FilterLogsReply` containing an array of matching logs.

**Signature:**

```go
func (c *Client) FilterLogs(runtime cre.Runtime, input *FilterLogsRequest) cre.Promise[*FilterLogsReply]
```

#### `evm.FilterLogsRequest`

| Field         | Type               | Description                                                                                  |
| ------------- | ------------------ | -------------------------------------------------------------------------------------------- |
| `FilterQuery` | `*evm.FilterQuery` | A struct defining the filters for the log query, such as block range, addresses, and topics. |

#### `evm.FilterLogsReply`

| Field  | Type         | Description                                          |
| ------ | ------------ | ---------------------------------------------------- |
| `Logs` | `[]*evm.Log` | An array of log objects that match the filter query. |

### `GetTransactionByHash`

Retrieves a transaction by its hash. You provide the hash in an `evm.GetTransactionByHashRequest`, and the function returns a promise that resolves to an `evm.GetTransactionByHashReply` containing the transaction object.

**Signature:**

```go
func (c *Client) GetTransactionByHash(runtime cre.Runtime, input *GetTransactionByHashRequest) cre.Promise[*GetTransactionByHashReply]
```

#### `evm.GetTransactionByHashRequest`

| Field  | Type     | Description                                     |
| ------ | -------- | ----------------------------------------------- |
| `Hash` | `[]byte` | The 32-byte hash of the transaction to look up. |

#### `evm.GetTransactionByHashReply`

| Field         | Type               | Description                       |
| ------------- | ------------------ | --------------------------------- |
| `Transaction` | `*evm.Transaction` | The transaction object, if found. |

### `GetTransactionReceipt`

Fetches the receipt for a transaction given its hash. You provide the hash in an `evm.GetTransactionReceiptRequest`, and the function returns a promise that resolves to an `evm.GetTransactionReceiptReply` containing the receipt.

**Signature:**

```go
func (c *Client) GetTransactionReceipt(runtime cre.Runtime, input *GetTransactionReceiptRequest) cre.Promise[*GetTransactionReceiptReply]
```

#### `evm.GetTransactionReceiptRequest`

| Field  | Type     | Description                          |
| ------ | -------- | ------------------------------------ |
| `Hash` | `[]byte` | The 32-byte hash of the transaction. |

#### `evm.GetTransactionReceiptReply`

| Field     | Type           | Description                               |
| --------- | -------------- | ----------------------------------------- |
| `Receipt` | `*evm.Receipt` | The transaction receipt object, if found. |

### `HeaderByNumber`

Retrieves a block header by its number. You provide the block number in an `evm.HeaderByNumberRequest`, and the function returns a promise that resolves to an `evm.HeaderByNumberReply` containing the header object.

**Signature:**

```go
func (c *Client) HeaderByNumber(runtime cre.Runtime, input *HeaderByNumberRequest) cre.Promise[*HeaderByNumberReply]
```

#### `evm.HeaderByNumberRequest`

| Field         | Type         | Description                                                                                                                                                                                                                                                                                                                                       |
| ------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `BlockNumber` | `*pb.BigInt` | The number of the block to retrieve. Accepts `nil` for `latest` (default), `-2` for `latest`, `-3` for `finalized`, or any positive integer for an explicit block height (see [Custom Block Depths](/cre/guides/workflow/using-evm-client/onchain-read-go#custom-block-depths)). See [Finality and Confidence Levels](/cre/concepts/finality-go). |

#### `evm.HeaderByNumberReply`

| Field    | Type          | Description                        |
| -------- | ------------- | ---------------------------------- |
| `Header` | `*evm.Header` | The block header object, if found. |

### `EstimateGas`

Estimates the gas required to execute a specific transaction. You provide the transaction details in an `evm.EstimateGasRequest`, and the function returns a promise that resolves to an `evm.EstimateGasReply` with the gas estimate.

**Signature:**

```go
func (c *Client) EstimateGas(runtime cre.Runtime, input *EstimateGasRequest) cre.Promise[*EstimateGasReply]
```

#### `evm.EstimateGasRequest`

| Field | Type           | Description                                             |
| ----- | -------------- | ------------------------------------------------------- |
| `Msg` | `*evm.CallMsg` | The transaction message to simulate for gas estimation. |

#### `evm.EstimateGasReply`

| Field | Type     | Description                               |
| ----- | -------- | ----------------------------------------- |
| `Gas` | `uint64` | The estimated amount of gas in gas units. |

## Write methods

### `WriteReport`

Executes a state-changing transaction by submitting a report to a designated receiver contract. You provide the transaction details in an `evm.WriteCreReportRequest`, and the function returns a promise that resolves to an `evm.WriteReportReply` with the transaction status.

**Signature:**

```go
func (c *Client) WriteReport(runtime cre.Runtime, input *WriteCreReportRequest) cre.Promise[*WriteReportReply]
```

#### `evm.WriteCreReportRequest`

| Field       | Type             | Description                                            |
| ----------- | ---------------- | ------------------------------------------------------ |
| `Receiver`  | `[]byte`         | The 20-byte address of the receiver contract to call.  |
| `Report`    | `*cre.Report`    | The report data generated by the DON to be submitted.  |
| `GasConfig` | `*evm.GasConfig` | Optional. Gas limit configuration for the transaction. |

#### `evm.WriteReportReply`

| Field                             | Type                               | Description                                                                         |
| --------------------------------- | ---------------------------------- | ----------------------------------------------------------------------------------- |
| `TxStatus`                        | `TxStatus`                         | The final status of the transaction: `SUCCESS`, `REVERTED`, or `FATAL`.             |
| `ReceiverContractExecutionStatus` | `*ReceiverContractExecutionStatus` | Optional. The status of the receiver contract's execution: `SUCCESS` or `REVERTED`. |
| `TxHash`                          | `[]byte`                           | Optional. The 32-byte transaction hash of the onchain submission.                   |
| `TransactionFee`                  | `*pb.BigInt`                       | Optional. The total fee paid for the transaction in Wei.                            |
| `ErrorMessage`                    | `*string`                          | Optional. An error message if the transaction failed.                               |

## Chain Selectors

A **chain selector** is a unique identifier for a blockchain network used throughout the CRE platform. The same chain can be referenced in three different ways depending on the context. All three formats are equivalent and refer to the same blockchain.

> **NOTE: Related resources**
>
> - **Forwarder addresses**: For network-specific forwarder contract addresses, see [Forwarder Directory](/cre/guides/workflow/using-evm-client/forwarder-directory)

- **RPC configuration**: For configuring RPC endpoints in `project.yaml`, see [Project Configuration](/cre/reference/project-configuration)

### Understanding the three formats

| Format                       | Example                      | Used In                                                                                            |
| ---------------------------- | ---------------------------- | -------------------------------------------------------------------------------------------------- |
| **String Name** (kebab-case) | `"ethereum-testnet-sepolia"` | `project.yaml` configuration files, workflow `config.json` files, `ChainSelectorFromName()` helper |
| **Go Constant** (PascalCase) | `evm.EthereumTestnetSepolia` | Directly in your workflow Go code when you need the numeric ID                                     |
| **Numeric ID** (uint64)      | `16015286601757825753`       | `evm.Client` instantiation in Go code                                                              |

> **NOTE: Which format should I use?**
>
> - **In configuration files** (`project.yaml`, `config.staging.json`, `config.production.json`, etc.): Use the **string name** format (e.g., `chain-name: ethereum-testnet-sepolia` in YAML, `"chainName": "ethereum-testnet-sepolia"` in JSON)

- **In Go code**: Use either the **Go constant** (e.g., `evm.EthereumTestnetSepolia`) or the **helper function** with the string name (e.g., `evm.ChainSelectorFromName("ethereum-testnet-sepolia")`)

### Complete chain selector reference

This table shows all three equivalent formats for each supported chain:

| Chain               | String Name                           | Go Constant                           | Numeric ID           |
| ------------------- | ------------------------------------- | ------------------------------------- | -------------------- |
| Apechain Curtis     | apechain-testnet-curtis               | evm.ApechainTestnetCurtis             | 9900119385908781505  |
| Arc Testnet         | arc-testnet                           | evm.ArcTestnet                        | 3034092155422581607  |
| Arbitrum One        | ethereum-mainnet-arbitrum-1           | evm.EthereumMainnetArbitrum1          | 4949039107694359620  |
| Arbitrum Sepolia    | ethereum-testnet-sepolia-arbitrum-1   | evm.EthereumTestnetSepoliaArbitrum1   | 3478487238524512106  |
| Avalanche Mainnet   | avalanche-mainnet                     | evm.AvalancheMainnet                  | 6433500567565415381  |
| Avalanche Fuji      | avalanche-testnet-fuji                | evm.AvalancheTestnetFuji              | 14767482510784806043 |
| Base Mainnet        | ethereum-mainnet-base-1               | evm.EthereumMainnetBase1              | 15971525489660198786 |
| Base Sepolia        | ethereum-testnet-sepolia-base-1       | evm.EthereumTestnetSepoliaBase1       | 10344971235874465080 |
| BNB Chain Mainnet   | binance\_smart\_chain-mainnet         | evm.BinanceSmartChainMainnet          | 11344663589394136015 |
| BNB Chain Testnet   | binance\_smart\_chain-testnet         | evm.BinanceSmartChainTestnet          | 13264668187771770619 |
| Ethereum Mainnet    | ethereum-mainnet                      | evm.EthereumMainnet                   | 5009297550715157269  |
| Ethereum Sepolia    | ethereum-testnet-sepolia              | evm.EthereumTestnetSepolia            | 16015286601757825753 |
| Hyperliquid Testnet | hyperliquid-testnet                   | evm.HyperliquidTestnet                | 4286062357653186312  |
| Ink Sepolia         | ink-testnet-sepolia                   | evm.InkTestnetSepolia                 | 9763904284804119144  |
| Jovay Testnet       | jovay-testnet                         | evm.JovayTestnet                      | 945045181441419236   |
| Linea Sepolia       | ethereum-testnet-sepolia-linea-1      | evm.EthereumTestnetSepoliaLinea1      | 5719461335882077547  |
| OP Mainnet          | ethereum-mainnet-optimism-1           | evm.EthereumMainnetOptimism1          | 3734403246176062136  |
| OP Sepolia          | ethereum-testnet-sepolia-optimism-1   | evm.EthereumTestnetSepoliaOptimism1   | 5224473277236331295  |
| Plasma Testnet      | plasma-testnet                        | evm.PlasmaTestnet                     | 3967220077692964309  |
| Polygon Mainnet     | polygon-mainnet                       | evm.PolygonMainnet                    | 4051577828743386545  |
| Polygon Amoy        | polygon-testnet-amoy                  | evm.PolygonTestnetAmoy                | 16281711391670634445 |
| World Chain Mainnet | ethereum-mainnet-worldchain-1         | evm.EthereumMainnetWorldchain1        | 2049429975587534727  |
| World Chain Sepolia | ethereum-testnet-sepolia-worldchain-1 | evm.EthereumTestnetSepoliaWorldchain1 | 5299555114858065850  |
| ZKSync Era          | ethereum-mainnet-zksync-1             | evm.EthereumMainnetZksync1            | 1562403441176082196  |
| ZKSync Era Sepolia  | ethereum-testnet-sepolia-zksync-1     | evm.EthereumTestnetSepoliaZksync1     | 6898391096552792247  |

### Usage examples

**In your `project.yaml` file (RPC configuration):**

```yaml
local-simulation:
  rpcs:
    - chain-name: ethereum-testnet-sepolia # String name for RPC endpoint
      url: https://your-rpc-url.com
```

**In your workflow's `config.json` file (workflow-specific settings):**

Your workflow configuration can include chain selector names as part of your custom config structure. For example:

```json
{
  "schedule": "*/30 * * * * *",
  "evms": [
    {
      "storageAddress": "0x1234...",
      "chainName": "ethereum-testnet-sepolia" // Use string name in your config
    }
  ]
}
```

**In your workflow Go code (Option 1 - Using the constant):**

```go
evmClient := &evm.Client{
    ChainSelector: evm.EthereumTestnetSepolia,  // Direct constant
}
```

**In your workflow Go code (Option 2 - Using the helper function with config):**

```go
// Read chain name from your config and convert to numeric selector
sepoliaSelector, err := evm.ChainSelectorFromName(config.Evms[0].ChainName)
if err != nil {
    return err
}
evmClient := &evm.Client{
    ChainSelector: sepoliaSelector,
}
```

### `ChainSelectorFromName`

A helper function to convert a string name to its numeric chain selector ID.

**Signature:**

```go
func ChainSelectorFromName(name string) (uint64, error)
```

**Parameters:**

- `name`: The kebab-case string identifier for the chain (e.g., `"ethereum-testnet-sepolia"`)

**Returns:**

- The numeric chain selector ID
- An error if the chain name is not recognized

**Example:**

```go
selector, err := evm.ChainSelectorFromName("ethereum-testnet-sepolia")
if err != nil {
    return fmt.Errorf("invalid chain name: %w", err)
}
// selector now holds 16015286601757825753
```