Skip to main content
The VM module (x/vm) is the core EVM implementation that enables Ethereum compatibility on Cosmos chains. It provides the EVM runtime, state management, precompiled contracts, and transaction processing.

Module Overview

Purpose: Execute Ethereum smart contracts and process EVM transactions within the Cosmos SDK framework Key Functionality:
  • EVM state transitions and transaction execution
  • Ethereum fork activation management (Homestead, Berlin, London, Shanghai, Cancun, Prague, etc.)
  • Native precompiled contracts for Cosmos module access
  • EVM-to-Cosmos and Cosmos-to-EVM account bridging
  • Gas metering and fee handling
  • Historical state queries with configurable retention
Source Code: x/vm Parameter Defaults: x/vm/types/params.go

Configuration Methods

The VM module can be configured through genesis.json before chain launch. Here are the three primary methods:

Method 1: Direct JSON Editing

Edit ~/.evmd/config/genesis.json directly:

Method 2: Using jq Command-Line Tool

Programmatically modify genesis using jq (as seen in local_node.sh):

Method 3: Using genesis CLI Commands

Some parameters can be set through CLI commands (though most VM params require genesis.json editing):

Parameters

evm_denom

What It Does: Specifies which bank module denomination to use as the native EVM token (gas token). Type: string Valid Values: Must match a base denomination from bank metadata configuration Default: "uatom" (params.go:21) Configuration:
Critical Requirements:
  • MUST match bank.denom_metadata[0].base
  • MUST match staking.params.bond_denom
  • MUST match mint.params.mint_denom
Impact: This is the token users pay for EVM gas, displayed in MetaMask balances, and used for all EVM operations. Examples:
  • "atest" - For 18 decimal token (atto prefix: 10^18)
  • "ustake" - For 6 decimal token (micro prefix: 10^6)
Common Errors:
  • Mismatch with bank metadata causes EVM transactions to fail
  • Wrong decimal places leads to incorrect balance displays

extra_eips

What It Does: Enables additional Ethereum Improvement Proposals beyond the default fork activations. Type: []int64 (array of EIP numbers) Valid Values: Any activatable EIP number Default: [] (empty - all EIPs come from chain_config fork configuration) (params.go:22) Configuration:
Common EIPs: Validation: Checked against list of activatable EIPs (params.go:182-200) Impact:
  • Enables opcodes/features not in your default fork configuration
  • Useful for testing upcoming Ethereum features
  • Can break compatibility if not carefully managed
Recommendation: Leave empty unless you need specific EIPs for custom contracts or testing

active_static_precompiles

What It Does: List of precompiled contract addresses to enable for Cosmos module access from EVM. Type: []string (array of hex addresses) Valid Values: Addresses from the available precompiles list (precompiles.go:4-15) Default: [] (empty - no precompiles enabled) (params.go:23) Configuration:
Available Precompiles: Production Recommendations:
  • Enable only needed precompiles for security and gas efficiency
  • Commonly enabled: 0x0100 (P256), 0x0400 (Bech32), 0x0800 (Staking), 0x0804 (Bank)
  • IBC chains: Also enable 0x0802 (ICS20)
  • Governance participation: Enable 0x0805 (Gov)
Security Note: Each enabled precompile increases attack surface. Only enable precompiles your applications will actually use. Default evmd Example: Enables ALL precompiles for development convenience (local_node.sh:243)

evm_channels

What It Does: Whitelisted IBC channel IDs that the ICS20 precompile can use for token transfers. Type: []string (array of channel IDs) Valid Values: Channel IDs matching format channel-{N} where N is a non-negative integer Default: [] (empty - no channels whitelisted) (params.go:24) Configuration:
Validation: Each channel must match regex pattern (params.go:80-96) Impact:
  • Restricts which IBC channels the ICS20 precompile (0x0802) can transfer tokens through
  • Empty list means ICS20 precompile cannot perform any IBC transfers
  • Provides security control over cross-chain token movements
When to Configure:
  • Only needed if you enable ICS20 precompile (0x0802)
  • Set after establishing IBC connections with other chains
  • Update via governance when adding new IBC routes
Example Use Case: Enable IBC transfers only to trusted chains via specific channels

access_control

What It Does: Defines permission model for contract deployment (CREATE/CREATE2) and contract calls. Type: Object with create and call fields, each containing access_type and optional access_control_list Valid Values:
  • access_type: 0 (Permissionless), 1 (Restricted), 2 (Permissioned)
  • access_control_list: Array of addresses (only used with Restricted or Permissioned)
Default: Permissionless for both (params.go:30-48) Configuration:
Access Types: Type 0 - Permissionless (Default):
  • Anyone can perform the operation
  • Standard Ethereum behavior
  • Recommended for public chains
Type 1 - Restricted:
  • Everyone EXCEPT addresses in access_control_list can perform operation
  • Blacklist model
  • Useful for blocking specific malicious actors
Type 2 - Permissioned:
  • ONLY addresses in access_control_list can perform operation
  • Whitelist model
  • Useful for private/consortium chains or phased launches
Common Configurations: Public Chain (Default):
Permissioned Deployment, Public Usage:
Validation: Enforced in (params.go:140-180) Impact:
  • Controls who can deploy contracts (important for chain security)
  • Controls who can call existing contracts (rarely restricted)
  • Can be updated via governance proposals after launch
Recommendation: Use Type 0 (Permissionless) for public EVM chains to maintain Ethereum compatibility

history_serve_window

What It Does: Number of recent blocks to keep for historical EVM queries (eth_getBlockByNumber, eth_getLogs, etc.). Type: uint64 Valid Values: Any non-negative integer Default: 8192 blocks (params.go:50) Configuration:
Impact: Storage:
  • Larger window = more disk space required
  • Smaller window = less disk space usage
  • Each block stores EVM state diffs and receipts
Query Capability:
  • Queries beyond history_serve_window will fail
  • Block explorers need sufficient history for user queries
  • DeFi analytics may require longer history
Performance:
  • Very large windows can slow down state pruning
  • Affects database size and sync time
Common Values:
  • 8192 - Default (roughly 11 hours at 5s blocks)
  • 100000 - Extended history (roughly 5.8 days at 5s blocks)
  • 1000000 - Full history (roughly 58 days at 5s blocks)
  • 0 - No history retention (not recommended for RPC nodes)
Recommendations:
  • Archive Nodes: Set to very large number or 0 (unlimited)
  • RPC Nodes: 100,000 - 1,000,000 blocks
  • Validator Nodes: Can use default 8192 (validators don’t serve RPC)
Related: Works with EIP-2935 for historical block hash access

extended_denom_options

What It Does: Enables 18-decimal EVM representation for non-18-decimal Cosmos tokens. Required for 6-decimal tokens like ustake. Type: []ExtendedDenomOption - Array of objects mapping Cosmos denoms to EVM extended denoms Valid Values: Each entry must have a valid denom pair following the extended denom pattern Default: [] (empty - no extended denoms) (params.go:25) Configuration:
When Required:
  • 18 decimals: NOT required - standard bank module works
  • 6 decimals: REQUIRED - must add extended_denom_options
  • Other decimals: REQUIRED - must add extended_denom_options
Extended Denom Patterns:
  • u prefix (micro, 10^6) → a prefix (atto, 10^18): ustakeastake
  • n prefix (nano, 10^9) → a prefix (atto, 10^18): ntokenatoken
  • Any other → add evm prefix: stakeevmstake
How It Works:
  1. Native 6-decimal token: ustake (smallest unit)
  2. Extended 18-decimal representation: astake (for EVM)
  3. 1 ustake = 10^12 astake
  4. PreciseBank module handles fractional conversions
Example: 6 Decimal Token:
Related Configuration: Requires PreciseBank Module to be included in app.go

Complete Configuration Example

Based on local_node.sh:
Or in genesis.json directly:


Source Code References