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_denom
string "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_control
AccessControl Permissionless Permission policy for EVM operations history_serve_window
uint64 8192
Historical 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_block
0 Block DELEGATECALL byzantium_block
0 Block REVERT, RETURNDATASIZE, STATICCALL constantinople_block
0 Block CREATE2, EXTCODEHASH, SHL/SHR/SAR istanbul_block
0 Block CHAINID, SELFBALANCE berlin_block
0 Block Access lists (EIP-2929, 2930) london_block
0 Block BASEFEE, EIP-1559 shanghai_time
0 Timestamp PUSH0 cancun_time
0 Timestamp Transient storage, blob transactions prague_time
nil Timestamp TBD verkle_time
nil Timestamp Verkle trees
Static Precompiles
Precompiled contracts at fixed addresses (source ):
Address Contract Gas Cost Description 0x0000...0100
P256 3000 P256 curve verification 0x0000...0400
Bech32 5000 Bech32 address encoding 0x0000...0800
Staking Variable Delegation operations 0x0000...0801
Distribution Variable Reward claims 0x0000...0802
ICS20 Variable IBC transfers 0x0000...0803
Vesting Variable Vesting account ops 0x0000...0804
Bank Variable Token transfers 0x0000...0805
Gov Variable Governance voting 0x0000...0806
Slashing 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 0x01
Parameters Params
0x02
Contract code []byte
0x03
Contract storage [32]byte
Transient State
Key Prefix Description Value Type Lifetime 0x01
Transaction logs []Log
Per block 0x02
Block bloom [256]byte
Per block 0x03
Tx index uint64
Per block 0x04
Log size uint64
Per block 0x05
Gas used uint64
Per tx
Events
Transaction Events
Event Attributes When Emitted ethereum_tx
amount
, recipient
, contract
, txHash
, txIndex
, txGasUsed
Every EVM transaction tx_log
txLog
(JSON)When contracts emit events message
sender
, action="ethereum"
, module="evm"
Every message
Block Events
Event Attributes When Emitted block_bloom
bloom
(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_accounts
List accounts eth_blockNumber
Current block number eth_call
Execute call without tx eth_chainId
Get chain ID eth_createAccessList
Generate access list for tx optimization (v0.5.0+) eth_estimateGas
Estimate gas usage (optimized in v0.5.0+) eth_gasPrice
Current gas price eth_getBalance
Get account balance eth_getBlockByHash
Get block by hash eth_getBlockByNumber
Get block by number eth_getCode
Get contract code eth_getLogs
Get filtered logs eth_getStorageAt
Get storage value eth_getTransactionByHash
Get tx by hash eth_getTransactionCount
Get account nonce eth_getTransactionReceipt
Get tx receipt (enhanced with max_used_gas in v0.5.0+) eth_sendRawTransaction
Submit signed tx eth_syncing
Sync 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
}
}
References
Source Code