The x/vm module from cosmos/evm provides a fully compatible Ethereum Virtual Machine execution environment as a Cosmos SDK module.
For conceptual understanding of EVM architecture and design, see EVM Architecture.

Parameters

The module parameters control EVM behavior and access policies (source):
ParameterTypeDefaultDescription
evm_denomstring"aatom"Token denomination for EVM transactions (18 decimals)
extra_eips[]int64[]Additional EIPs to activate beyond hard fork defaults
allow_unprotected_txsboolfalseAllow non-EIP155 replay-protected transactions
active_static_precompiles[]string[]Activated static precompile addresses
evm_channels[]string[]IBC channel IDs for EVM-compatible chains
access_controlAccessControlPermissionlessPermission policy for EVM operations

Parameter Details

Configuration Profiles

{
  "evm_denom": "aatom",
  "extra_eips": [3855],
  "allow_unprotected_txs": false,
  "active_static_precompiles": [
    "0x0000000000000000000000000000000000000100",
    "0x0000000000000000000000000000000000000400"
  ],
  "access_control": {
    "create": {"access_type": "PERMISSIONLESS", "list": []},
    "call": {"access_type": "PERMISSIONLESS", "list": []}
  }
}

Chain Configuration

Hard fork activation schedule (source):
ForkDefaultTypeOpcodes/Features Added
homestead_block0BlockDELEGATECALL
byzantium_block0BlockREVERT, RETURNDATASIZE, STATICCALL
constantinople_block0BlockCREATE2, EXTCODEHASH, SHL/SHR/SAR
istanbul_block0BlockCHAINID, SELFBALANCE
berlin_block0BlockAccess lists (EIP-2929, 2930)
london_block0BlockBASEFEE, EIP-1559
shanghai_time0TimestampPUSH0
cancun_time0TimestampTransient storage, blob transactions
prague_timenilTimestampTBD
verkle_timenilTimestampVerkle trees

Static Precompiles

Precompiled contracts at fixed addresses (source):
AddressContractGas CostDescription
0x0000...0100P2563000P256 curve verification
0x0000...0400Bech325000Bech32 address encoding
0x0000...0800StakingVariableDelegation operations
0x0000...0801DistributionVariableReward claims
0x0000...0802ICS20VariableIBC transfers
0x0000...0803VestingVariableVesting account ops
0x0000...0804BankVariableToken transfers
0x0000...0805GovVariableGovernance voting
0x0000...0806SlashingVariableValidator slashing info

Activation

# Via genesis
{
  "active_static_precompiles": [
    "0x0000000000000000000000000000000000000804",
    "0x0000000000000000000000000000000000000800"
  ]
}

# Via governance proposal
evmd tx gov submit-proposal update-params-proposal.json

Messages

MsgEthereumTx

Primary message for EVM transactions (source):
message MsgEthereumTx {
  google.protobuf.Any data = 1;  // Transaction data (Legacy/AccessList/DynamicFee)
  string hash = 3;                // Transaction hash
  string from = 4;                // Sender address (derived from signature)
}
Validation Requirements:
  • Valid signature matching from address
  • Sufficient balance for gas + value
  • Correct nonce (account sequence)
  • Gas limit ≥ intrinsic gas

MsgUpdateParams

Governance message for parameter updates:
message MsgUpdateParams {
  string authority = 1;  // Must be governance module
  Params params = 2;     // New parameters
}

State

Persistent State

Key PrefixDescriptionValue Type
0x01ParametersParams
0x02Contract code[]byte
0x03Contract storage[32]byte

Transient State

Key PrefixDescriptionValue TypeLifetime
0x01Transaction logs[]LogPer block
0x02Block bloom[256]bytePer block
0x03Tx indexuint64Per block
0x04Log sizeuint64Per block
0x05Gas useduint64Per tx

Events

Transaction Events

EventAttributesWhen Emitted
ethereum_txamount, recipient, contract, txHash, txIndex, txGasUsedEvery EVM transaction
tx_logtxLog (JSON)When contracts emit events
messagesender, action="ethereum", module="evm"Every message

Block Events

EventAttributesWhen Emitted
block_bloombloom (hex)End of each block with EVM txs

Queries

gRPC

service Query {
  // Account queries
  rpc Account(QueryAccountRequest) returns (QueryAccountResponse);
  rpc CosmosAccount(QueryCosmosAccountRequest) returns (QueryCosmosAccountResponse);
  rpc ValidatorAccount(QueryValidatorAccountRequest) returns (QueryValidatorAccountResponse);
  
  // State queries
  rpc Balance(QueryBalanceRequest) returns (QueryBalanceResponse);
  rpc Storage(QueryStorageRequest) returns (QueryStorageResponse);
  rpc Code(QueryCodeRequest) returns (QueryCodeResponse);
  
  // Module queries
  rpc Params(QueryParamsRequest) returns (QueryParamsResponse);
  rpc Config(QueryConfigRequest) returns (QueryConfigResponse);
  
  // EVM operations
  rpc EthCall(EthCallRequest) returns (MsgEthereumTxResponse);
  rpc EstimateGas(EthCallRequest) returns (EstimateGasResponse);
  
  // Debugging
  rpc TraceTx(QueryTraceTxRequest) returns (QueryTraceTxResponse);
  rpc TraceBlock(QueryTraceBlockRequest) returns (QueryTraceBlockResponse);
  
  // Fee queries
  rpc BaseFee(QueryBaseFeeRequest) returns (QueryBaseFeeResponse);
  rpc GlobalMinGasPrice(QueryGlobalMinGasPriceRequest) returns (QueryGlobalMinGasPriceResponse);
}

CLI

# Query EVM account
evmd query vm account 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0

# Query Cosmos address
evmd query vm cosmos-account 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0

JSON-RPC

Supported Methods

MethodDescription
eth_accountsList accounts
eth_blockNumberCurrent block number
eth_callExecute call without tx
eth_chainIdGet chain ID
eth_estimateGasEstimate gas usage
eth_gasPriceCurrent gas price
eth_getBalanceGet account balance
eth_getBlockByHashGet block by hash
eth_getBlockByNumberGet block by number
eth_getCodeGet contract code
eth_getLogsGet filtered logs
eth_getStorageAtGet storage value
eth_getTransactionByHashGet tx by hash
eth_getTransactionCountGet account nonce
eth_getTransactionReceiptGet tx receipt
eth_sendRawTransactionSubmit signed tx
eth_syncingSync status

Hooks

Post-transaction processing interface (source):
type EvmHooks interface {
    PostTxProcessing(
        ctx sdk.Context,
        msg core.Message,
        receipt *ethtypes.Receipt,
    ) error
}

Registration

// In app.go
app.EvmKeeper = app.EvmKeeper.SetHooks(
    vmkeeper.NewMultiEvmHooks(
        app.Erc20Keeper.Hooks(),
        app.CustomKeeper.Hooks(),
    ),
)

Use Cases

  • Process EVM events in Cosmos modules
  • Bridge EVM logs to Cosmos events
  • Trigger native module actions from contracts
  • Custom indexing and monitoring

Gas Configuration

Gas Consumption Mapping

OperationEVM GasCosmos GasNotes
Basic ops3-53-51:1 mapping
SLOAD21002100Cold access
SSTORE2000020000New value
CREATE3200032000Contract deploy
PrecompileVariableVariableSet per precompile

Gas Refunds

Maximum refund: 50% of gas used (after London)
refund = min(gasUsed/2, gasRefund)
finalGasUsed = gasUsed - refund

Best Practices

Chain Integration

  1. Precompile Selection
    • Only enable necessary precompiles
    • Test gas costs in development
    • Monitor usage patterns
  2. Access Control
    • Start restrictive, open gradually
    • Use governance for changes
    • Monitor blacklist/whitelist events
  3. Fork Planning
    {
      "shanghai_time": "1681338455",  // Test first
      "cancun_time": "1710338455"     // Delay for safety
    }
    

Contract Development

  1. Gas Optimization
    // Cache storage reads
    uint256 cached = storageVar;
    // Use cached instead of storageVar
    
    // Pack structs
    struct Packed {
        uint128 a;
        uint128 b;  // Single slot
    }
    
  2. Precompile Usage
    IBank bank = IBank(0x0000000000000000000000000000000000000804);
    uint256 balance = bank.balances(msg.sender, "aatom");
    

dApp Integration

  1. Provider Setup
    const provider = new ethers.JsonRpcProvider(
        "http://localhost:8545",
        { chainId: 9000, name: "evmos" }
    );
    
  2. Error Handling
    try {
        await contract.method();
    } catch (error) {
        if (error.code === 'CALL_EXCEPTION') {
            // Handle revert
        }
    }
    

Troubleshooting

Common Issues

IssueCauseSolution
”out of gas”Insufficient gas limitIncrease gas limit or optimize contract
”nonce too low”Stale nonceQuery current nonce, retry
”insufficient funds”Low balanceEnsure balance > value + (gasLimit × gasPrice)
“contract creation failed”CREATE disabled or restrictedCheck access_control settings
”precompile not active”Precompile not in active listEnable via governance

Debug Commands

# Check EVM parameters
evmd query vm params

# Trace failed transaction
evmd query vm trace-tx 0xFailedTxHash

# Check account state
evmd query vm account 0xAddress

References

Source Code