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 ):
Parameter Type Default Description
evm_denomstring "atest"Token denomination for EVM transactions (18 decimals) extra_eips[]int64 []Additional EIPs to activate beyond hard fork defaults active_static_precompiles[]string []Activated static precompile addresses evm_channels[]string []IBC channel IDs for EVM-compatible chains access_controlAccessControl Permissionless Permission policy for EVM operations history_serve_windowuint64 8192Historical block hash depth for EIP-2935 (v0.5.0+)
Breaking Change in v0.5.0: The allow_unprotected_txs parameter has been removed from consensus parameters. Non-EIP155 transaction acceptance is now configured per-node in app.toml under [json-rpc].allow-unprotected-txs.
Parameter Details
Defines the token used for gas and value transfers in EVM:
Must be registered in bank module
Should have 18 decimal precision
Used for all EVM operations (gas, transfers, contracts)
Example: "atest", "aevmos", "wei"
Activates additional EIPs beyond fork defaults:
EIP Description Gas Impact
1344 ChainID opcode Minimal 1884 Repricing for trie-size-dependent opcodes Increases SLOAD 2200 Structured definitions for net gas metering Variable 2929 Gas cost for state access opcodes Increases cold access 3198 BASEFEE opcode Minimal 3529 Reduction in refunds Reduces max refund 3855 PUSH0 instruction New opcode
Show history_serve_window (v0.5.0+)
Controls EIP-2935 historical block hash storage depth: Purpose: Enables smart contracts to access historical block hashes via BLOCKHASH opcode
Range: Must be > 0, recommended ≤ 8192 for optimal performance
Storage Impact: Higher values increase node storage requirementsConfiguration Examples: {
"history_serve_window" : 8192 // Default: full EIP-2935 compatibility
}
{
"history_serve_window" : 1024 // Performance optimized: reduced storage
}
{
"history_serve_window" : 16384 // Extended history: maximum compatibility
}
Smart Contract Usage: contract HistoryExample {
function getRecentBlockHash ( uint256 blockNumber ) public view returns ( bytes32 ) {
// Works for blocks within history_serve_window range
return blockhash (blockNumber);
}
}
Granular control over contract operations: type AccessControl struct {
Create AccessControlType // Contract deployment
Call AccessControlType // Contract execution
}
Access Types:
PERMISSIONLESS: Open access, list = blacklist
RESTRICTED: No access, list ignored
PERMISSIONED: Limited access, list = whitelist
Configuration Profiles
Ethereum Compatible
Permissioned
High Security
{
"evm_denom" : "atest" ,
"extra_eips" : [ 3855 ],
"active_static_precompiles" : [
"0x0000000000000000000000000000000000000100" ,
"0x0000000000000000000000000000000000000400"
],
"evm_channels" : [],
"access_control" : {
"create" : { "access_type" : "PERMISSIONLESS" , "access_control_list" : []},
"call" : { "access_type" : "PERMISSIONLESS" , "access_control_list" : []}
},
"history_serve_window" : 8192
}
Chain Configuration
Hard fork activation schedule (source ):
Fork Default Type Opcodes/Features Added
homestead_block0 Block DELEGATECALL byzantium_block0 Block REVERT, RETURNDATASIZE, STATICCALL constantinople_block0 Block CREATE2, EXTCODEHASH, SHL/SHR/SAR istanbul_block0 Block CHAINID, SELFBALANCE berlin_block0 Block Access lists (EIP-2929, 2930) london_block0 Block BASEFEE, EIP-1559 shanghai_time0 Timestamp PUSH0 cancun_time0 Timestamp Transient storage, blob transactions prague_timenil Timestamp TBD verkle_timenil Timestamp Verkle trees
Static Precompiles
Precompiled contracts at fixed addresses (source ):
Address Contract Gas Cost Description
0x0000...0100P256 3000 P256 curve verification 0x0000...0400Bech32 5000 Bech32 address encoding 0x0000...0800Staking Variable Delegation operations 0x0000...0801Distribution Variable Reward claims 0x0000...0802ICS20 Variable IBC transfers 0x0000...0803Vesting Variable Vesting account ops 0x0000...0804Bank Variable Token transfers 0x0000...0805Gov Variable Governance voting 0x0000...0806Slashing Variable Validator 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 Prefix Description Value Type
0x01Parameters Params0x02Contract code []byte0x03Contract storage [32]byte
Transient State
Key Prefix Description Value Type Lifetime
0x01Transaction logs []LogPer block 0x02Block bloom [256]bytePer block 0x03Tx index uint64Per block 0x04Log size uint64Per block 0x05Gas used uint64Per tx
Events
Transaction Events
Event Attributes When 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
Event Attributes When Emitted
block_bloombloom (hex)End of each block with EVM txs
Queries
gRPC
Show View complete Query service interface
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-Account
Query-State
Query-Config
Debug
# Query EVM account
evmd query vm account 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0
# Query Cosmos address
evmd query vm cosmos-account 0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb0
JSON-RPC
Supported Methods
eth namespace
web3 namespace
net namespace
debug namespace
Method Description
eth_accountsList accounts eth_blockNumberCurrent block number eth_callExecute call without tx eth_chainIdGet chain ID eth_createAccessListGenerate access list for tx optimization (v0.5.0+) eth_estimateGasEstimate gas usage (optimized in v0.5.0+) 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 (enhanced with max_used_gas in v0.5.0+) 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
Operation EVM Gas Cosmos Gas Notes
Basic ops 3-5 3-5 1:1 mapping SLOAD 2100 2100 Cold access SSTORE 20000 20000 New value CREATE 32000 32000 Contract deploy Precompile Variable Variable Set per precompile
Gas Refunds
Maximum refund: 50% of gas used (after London)
refund = min ( gasUsed / 2 , gasRefund )
finalGasUsed = gasUsed - refund
Best Practices
Chain Integration
Precompile Selection
Only enable necessary precompiles
Test gas costs in development
Monitor usage patterns
Access Control
Start restrictive, open gradually
Use governance for changes
Monitor blacklist/whitelist events
Fork Planning
{
"shanghai_time" : "1681338455" , // Test first
"cancun_time" : "1710338455" // Delay for safety
}
Contract Development
Gas Optimization
// Cache storage reads
uint256 cached = storageVar;
// Use cached instead of storageVar
// Pack structs
struct Packed {
uint128 a;
uint128 b; // Single slot
}
Precompile Usage
IBank bank = IBank ( 0x0000000000000000000000000000000000000804 );
uint256 balance = bank. balances ( msg.sender , "atest" );
dApp Integration
Provider Setup
const provider = new ethers . JsonRpcProvider (
"http://localhost:8545" ,
{ chainId: 9000 , name: "evmos" }
);
Error Handling
try {
await contract . method ();
} catch ( error ) {
if ( error . code === 'CALL_EXCEPTION' ) {
// Handle revert
}
}
Troubleshooting
Common Issues
Issue Cause Solution
”out of gas” Insufficient gas limit Increase gas limit or optimize contract ”nonce too low” Stale nonce Query current nonce, retry ”insufficient funds” Low balance Ensure balance > value + (gasLimit × gasPrice) “contract creation failed” CREATE disabled or restricted Check access_control settings ”precompile not active” Precompile not in active list Enable 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