You can look up existing EVM Chain IDs by referring to chainlist.org to ensure your chosen ID is not already in use.

Dual Chain ID System

Cosmos EVM requires two separate chain IDs to maintain full compatibility with both the Cosmos SDK and Ethereum ecosystems:

1. Cosmos Chain ID (String)

The Cosmos Chain ID is a string identifier used by:
  • CometBFT consensus engine
  • IBC (Inter-Blockchain Communication) protocol
  • Native Cosmos SDK transactions
  • Chain upgrades and governance
Format: String with flexible naming (e.g., "cosmosevm-1", "mychain-testnet-2") Example:
// In genesis.json
{
  "chain_id": "cosmosevm-1"
}

2. EVM Chain ID (Integer)

The EVM Chain ID is an integer used by:
  • Ethereum transactions (EIP-155 replay protection)
  • MetaMask and other Ethereum wallets
  • Smart contract deployments
  • EVM tooling (Hardhat, Foundry, etc.)
Format: Positive integer (e.g., 9000, 9001) Example:
// In app/app.go
const EVMChainID = 9000

Configuration

Both chain IDs must be configured when setting up your chain:

In Your Application Code

// app/app.go
const (
    CosmosChainID = "cosmosevm-1"  // String for Cosmos/IBC
    EVMChainID    = 9000           // Integer for EVM/Ethereum
)

In Genesis Configuration

The Cosmos Chain ID is set in genesis.json:
{
  "chain_id": "cosmosevm-1",
  // ... other genesis parameters
}
The EVM Chain ID is configured in the EVM module parameters:
// During chain initialization
evmtypes.DefaultChainConfig(9000)  // Your EVM Chain ID

Important Considerations

Chain ID Selection

The two chain IDs serve different purposes and must not be confused:
  • Use the Cosmos Chain ID (string) for IBC connections, governance proposals, and Cosmos SDK operations
  • Use the EVM Chain ID (integer) for MetaMask configuration, smart contract deployments, and EIP-155 transaction signing

EVM Chain ID Guidelines

When selecting your EVM Chain ID:
  1. Check availability: Verify your chosen ID is not already in use on chainlist.org
  2. Avoid conflicts: Don’t use well-known chain IDs (1 for Ethereum mainnet, 137 for Polygon, etc.)
  3. Consider ranges:
    • Production networks often use lower numbers
    • Testnets commonly use higher ranges (9000+)
    • Local development can use very high numbers (31337+)

Chain Upgrades

Unlike traditional Cosmos chains that change their chain ID during upgrades (e.g., cosmoshub-4 to cosmoshub-5), the EVM Chain ID must remain constant across upgrades to maintain compatibility with deployed smart contracts and existing wallets.
Only the Cosmos Chain ID may change during chain upgrades if needed for consensus-breaking changes. The EVM Chain ID should never change once set.

Examples

Here are some example configurations:
Network TypeCosmos Chain IDEVM Chain IDNotes
Mainnet"cosmosevm-1"9000Production network
Testnet"cosmosevm-testnet-1"9001Public testnet
Devnet"cosmosevm-dev-1"9002Development network
Local"cosmosevm-local-1"31337Local development

Troubleshooting

Common Issues

  1. “Chain ID mismatch” errors
    • Cause: Using Cosmos Chain ID where EVM Chain ID is expected (or vice versa)
    • Solution: Ensure you’re using the correct type of chain ID for each context
  2. MetaMask connection failures
    • Cause: Incorrect EVM Chain ID in wallet configuration
    • Solution: Use the integer EVM Chain ID, not the string Cosmos Chain ID
  3. IBC transfer failures
    • Cause: Using EVM Chain ID for IBC operations
    • Solution: IBC always uses the Cosmos Chain ID (string format)
  4. Smart contract deployment issues
    • Cause: EIP-155 replay protection using wrong chain ID
    • Solution: Ensure your EVM Chain ID matches what’s configured in the chain

Verification Commands

To verify your chain IDs are correctly configured:
# Check Cosmos Chain ID
curl -s http://localhost:26657/status | jq '.result.node_info.network'

# Check EVM Chain ID
curl -X POST -H "Content-Type: application/json" \
  --data '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}' \
  http://localhost:8545 | jq '.result'