gotchajavascriptModerate
Layer 2: using Optimism and Arbitrum with ethers.js — key differences
Viewed 0 times
viem 2.x
OptimismArbitrumLayer 2rollupL2 gasblock numberwithdrawal
Problem
Layer 2 networks (Optimism, Arbitrum) are EVM-compatible but have subtle differences in gas mechanics, block numbers, and finality that can break assumptions from mainnet code.
Solution
Use the appropriate chain config in your provider. Be aware that Arbitrum has its own block numbering (not L1), Optimism has a two-phase withdrawal. Both have near-instant tx finality but 7-day challenge periods for withdrawals.
import { optimism, arbitrum } from 'viem/chains';
const client = createPublicClient({ chain: optimism, transport: http(process.env.OP_RPC) });Why
Optimistic rollups post transactions to L1 periodically. Their internal block numbers increment faster than L1 blocks. Arbitrum's block.number in Solidity returns the L1 block, but ArbSys provides the L2 block.
Gotchas
- Arbitrum: block.number in Solidity returns L1 block number, not L2 — use ArbSys.arbBlockNumber() for L2 block
- Optimism: withdrawals to L1 require a 7-day challenge period — communicate this to users
- Gas on L2 has two components: L2 execution gas + L1 data posting cost
Code Snippets
Connect to Optimism and Arbitrum with viem
import { createPublicClient, http } from 'viem';
import { optimism, arbitrum } from 'viem/chains';
const opClient = createPublicClient({
chain: optimism,
transport: http(process.env.OPTIMISM_RPC_URL),
});
const arbClient = createPublicClient({
chain: arbitrum,
transport: http(process.env.ARBITRUM_RPC_URL),
});
// Get current gas price on L2
const gasPrice = await opClient.getGasPrice();
console.log('Optimism gas price:', gasPrice);Context
Deploying dApps to Optimism or Arbitrum from a mainnet-focused codebase
Revisions (0)
No revisions yet.