Default contracts
Cosmos EVM includes five default preinstalls (x/vm/types/preinstall.go):
Enabling at genesis
Preinstalls are set in theapp_state.evm.preinstalls array of genesis.json. How you populate that array depends on how you generate genesis for your chain.
-
Using
local_node.sh:evmd initdoes not populate preinstalls automatically. you will need to updatelocal_node.shto write the default preinstalls intogenesis.jsonbefore the node starts. Each entry requires the contract name, address, and compiled bytecode:Bytecodes are defined inlocal_node.shx/vm/types/preinstall.go. -
Using programmatic genesis (e.g.,
evmd testnet): Preinstalls are set inNewEVMGenesisState()inevmd/genesis.go. The reference chain already setsevmGenState.Preinstalls = evmtypes.DefaultPreinstallsthere, so all five defaults are included automatically. -
Custom genesis generation: Include the
preinstallsarray directly in yourgenesis.jsonunderapp_state.evm, with each entry specifyingname,address, and hex-encodedcode. Example:genesis.json
Add custom contracts
- To deploy a contract beyond the defaults, open
evmd/genesis.goand updateNewEVMGenesisState. The example below uses a minimal 10-byte contract (0x600160005260206000f3) that returns1on any call — replace the name, address, and code with your own:
evmd/genesis.go
- Add a
jqpatch tolocal_node.shafter the last genesis customization line (.consensus.params.block.max_gas), before the# Change proposal periodscomment. Use+=to append without overwriting any previously set preinstalls:
local_node.sh
- Valid Ethereum address (0x prefix, 40 hex characters)
- Must not conflict with existing contracts or precompile addresses (0x1–0x9FF)
- Non-empty, valid EVM bytecode (hex encoded)
- Rebuild the binary and start the chain:
-y flag wipes any existing chain data and reinitializes from genesis, which is required for the preinstall to take effect.
- Once the chain is running, open a new terminal and confirm the contract is installed by running the following commands:
code:
0x600160005260206000f3, which is the bytecode set in genesis.go and local_node.sh. A non-empty value confirms the code was written to state.
Expected output for account:
code_hash: a non-empty hash confirms the contract exists at this addressbalance: "0": preinstalls are deployed with no native token balance, which is expectednonce: "0": preinstalls are not deployed via a transaction, so the nonce starts at 0
Add contracts after launch
The following methods are examples of ways to deploy predeployed contracts after the chain is running.Deploy via governance proposal
UseMsgRegisterPreinstalls to deploy contracts on a running chain via governance:
proposal.json
Deploy via chain upgrade handler
Include preinstalls in a coordinated chain upgrade:app/upgrades/v2/upgrades.go