Skip to main content
The Internet Computer provides native integration with the Ethereum network, enabling canisters to interact with Ethereum smart contracts, query blockchain state, and manage ETH and ERC-20 tokens through chain-key ECDSA signatures.

Architecture Overview

The Ethereum integration leverages the IC’s HTTP outcalls feature to communicate with Ethereum JSON-RPC providers:
  • EVM RPC Canister: Provides reliable Ethereum JSON-RPC access via multiple providers
  • Chain-Key ECDSA: Enables canisters to sign Ethereum transactions
  • ckETH Minter: Converts ETH to ckETH and vice versa
  • Ledger Suite Orchestrator: Manages ckERC20 token ledgers

EVM RPC Integration

The Ethereum integration uses HTTPS outcalls to query multiple JSON-RPC providers, achieving decentralization without running full Ethereum nodes.

Key Capabilities

Smart Contract Calls

Query and call Ethereum smart contracts

Block Data

Fetch blocks, transactions, and receipts

Event Logs

Scrape and process Ethereum event logs

Transaction Submission

Submit signed transactions to the network

RPC Provider Configuration

The EVM RPC canister aggregates responses from multiple providers:
// From rs/ethereum/cketh/minter/src/lib.rs
pub const EVM_RPC_ID_PRODUCTION: Principal =
    Principal::from_slice(&[0, 0, 0, 0, 2, 48, 0, 204, 1, 1]);
pub const EVM_RPC_ID_STAGING: Principal = 
    Principal::from_slice(&[0, 0, 0, 0, 2, 48, 0, 161, 1, 1]);
The minter uses the EVM RPC canister to:
  • Query Ethereum block heights
  • Fetch event logs from helper contracts
  • Estimate gas fees for transactions
  • Submit signed withdrawal transactions

Chain-Key ECDSA for Ethereum

Canisters can control Ethereum addresses through chain-key ECDSA signatures.

ECDSA Key Management

1

Key Derivation

Each canister derives unique Ethereum addresses from a subnet ECDSA key:
pub const MAIN_DERIVATION_PATH: Vec<ByteBuf> = vec![];
2

Address Generation

The public key is converted to an Ethereum address using Keccak-256 hashing.
3

Transaction Signing

Canisters request threshold ECDSA signatures for Ethereum transactions.

Signing Ethereum Transactions

Canisters can sign EIP-1559 transactions:
// Transaction structure for Ethereum
struct Eip1559Transaction {
    chain_id: u64,
    nonce: u64,
    max_priority_fee_per_gas: u128,
    max_fee_per_gas: u128,
    gas_limit: u64,
    to: [u8; 20],
    value: u128,
    data: Vec<u8>,
}
  • chain_id: Ethereum network identifier (1 for mainnet, 11155111 for Sepolia)
  • nonce: Transaction sequence number for the sender
  • max_priority_fee_per_gas: Tip paid to miners (priority fee)
  • max_fee_per_gas: Maximum total fee willing to pay per gas
  • gas_limit: Maximum gas units the transaction can consume
  • to: Destination Ethereum address
  • value: Amount of ETH to transfer (in wei)
  • data: Contract call data or empty for simple transfers

Ethereum Network Support

Supported Networks

// From rs/ethereum/cketh/minter/cketh_minter.did
type EthereumNetwork = variant {
    Mainnet;   // Ethereum mainnet
    Sepolia;   // Sepolia testnet
};
NetworkChain IDPurpose
Mainnet1Production Ethereum transactions
Sepolia11155111Testing with Sepolia testnet ETH
Sepolia replaced Goerli as the primary Ethereum testnet. Use Sepolia for testing ckETH integration.

Helper Smart Contracts

The Ethereum integration uses helper smart contracts to facilitate deposits and event tracking.

ETH Helper Contract

The helper contract emits events when users deposit ETH:
// Deposit ETH with IC principal and subaccount
function depositEth(
    uint256 amount,
    bytes32 principal,
    bytes32 subaccount
) external payable;

Contract Addresses

ETH Helper Contract: 0x18901044688D3756C35Ed2b36D93e6a5B8e00E68View on Etherscan

Event Log Scraping

The ckETH minter continuously scrapes Ethereum event logs to detect deposits.

Scraping Configuration

// From rs/ethereum/cketh/minter/src/lib.rs
pub const SCRAPING_ETH_LOGS_INTERVAL: Duration = Duration::from_secs(3 * 60);
pub const PROCESS_ETH_RETRIEVE_TRANSACTIONS_INTERVAL: Duration = 
    Duration::from_secs(6 * 60);

Log Processing Flow

Event Log Structure

The helper contract emits structured events:
// Parsed from Ethereum logs
struct ReceivedEthEvent {
    from: [u8; 20],           // Ethereum sender address
    value: u128,              // Amount in wei
    principal: [u8; 29],      // IC principal
    subaccount: [u8; 32],     // IC subaccount
}

Gas Fee Estimation

The minter estimates gas fees for Ethereum transactions using EIP-1559 pricing.

Fee Structure

// From rs/ethereum/cketh/minter/cketh_minter.did
type Eip1559TransactionPrice = record {
    gas_limit : nat;
    max_fee_per_gas : nat;
    max_priority_fee_per_gas : nat;
    max_transaction_fee : nat;
    timestamp : opt nat64;
};
The minter queries multiple RPC providers to get reliable gas fee estimates and uses conservative values to ensure transaction inclusion.

Gas Limit by Operation

OperationTypical Gas Limit
ETH Transfer21,000
ERC-20 Transfer~65,000
Contract InteractionVariable
Helper Contract Deposit~33,000

Transaction Management

The minter manages Ethereum transaction lifecycle:

Transaction States

1

Pending

Withdrawal request received, awaiting transaction creation
2

TxCreated

Transaction created but not yet signed
3

Signing

Requesting threshold ECDSA signature
4

TxSent

Transaction broadcast to Ethereum network
5

TxFinalized

Transaction confirmed on Ethereum blockchain

Nonce Management

// From rs/ethereum/cketh/minter/cketh_minter.did
type InitArg = record {
    // ... other fields
    next_transaction_nonce : nat;
};
The minter tracks transaction nonces to ensure proper ordering:
  • Maintains sequential nonce for all outgoing transactions
  • Handles nonce gaps through transaction resubmission
  • Supports manual nonce override via upgrade args

Block Height Tracking

Block Tags

type BlockTag = variant {
    Latest;     // Latest mined block
    Safe;       // Latest safe head block  
    Finalized;  // Latest finalized block
};
  • Latest: Most recent block, may be reorganized
  • Safe: Safe from short-term reorganizations (recommended)
  • Finalized: Fully finalized, safest but may lag behind
The minter uses the configured block tag to determine which blocks to scrape for events.

Security Considerations

The Ethereum integration implements multiple security measures:

Event Validation

  • Verify event source (helper contract address)
  • Validate principal and subaccount format
  • Check minimum deposit amounts
  • Confirm transaction finality before minting

Transaction Security

  • All transactions signed via threshold ECDSA
  • Gas price limits to prevent overpaying
  • Transaction replay protection via nonces
  • Failed transaction reimbursement

RPC Provider Security

  • Query multiple providers for consensus
  • Detect and handle inconsistent responses
  • Automatic fallback to alternative providers
  • Rate limiting and retry logic

Performance Optimizations

Parallel Processing

The minter processes deposits and withdrawals in parallel:
// Concurrent timers
pub const SCRAPING_ETH_LOGS_INTERVAL: Duration = Duration::from_secs(3 * 60);
pub const PROCESS_ETH_RETRIEVE_TRANSACTIONS_INTERVAL: Duration = 
    Duration::from_secs(6 * 60);
pub const PROCESS_REIMBURSEMENT: Duration = Duration::from_secs(3 * 60);

Caching Strategy

  • Cache recent block data to reduce RPC calls
  • Store processed event logs to avoid reprocessing
  • Maintain gas fee estimates between updates

ckETH Minter

Chain-key Ethereum token implementation

ckBTC Minter

Chain-key Bitcoin token implementation

Source Code Reference

Key files in the Ethereum integration:
  • rs/ethereum/cketh/minter/src/lib.rs - Main minter constants and modules
  • rs/ethereum/cketh/minter/src/eth_rpc.rs - Ethereum RPC abstractions
  • rs/ethereum/cketh/minter/src/eth_rpc_client.rs - RPC client implementation
  • rs/ethereum/cketh/minter/src/eth_logs/ - Event log parsing
  • rs/ethereum/cketh/minter/src/deposit.rs - Deposit processing
  • rs/ethereum/cketh/minter/src/withdraw.rs - Withdrawal handling
  • rs/ethereum/cketh/minter/src/tx.rs - Transaction management

Build docs developers (and LLMs) love