Default Contracts
Cosmos EVM includes five default preinstalls (x/vm/types/preinstall.go):
| Contract | Address | Purpose | Docs |
|---|---|---|---|
| Create2 | 0x4e59b44847b379578588920ca78fbf26c0b4956c | Deterministic contract deployment using CREATE2 | EIP-1014 |
| Multicall3 | 0xcA11bde05977b3631167028862bE2a173976CA11 | Batch multiple contract calls in one transaction | Repo · Site |
| Permit2 | 0x000000000022D473030F116dDEE9F6B43aC78BA3 | Signature-based token approvals for any ERC20 | Repo · Docs |
| Safe Singleton Factory | 0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7 | Deploy Safe multisig wallets at deterministic addresses | Repo · Docs |
| EIP-2935 | 0x0000F90827F1C53a10cb7A02335B175320002935 | Historical block hash storage | EIP-2935 |
Enabling at Genesis
Preinstalls are deployed when the chain first starts, based on thepreinstalls array in genesis.json. If the array is empty, no contracts are deployed.
App-level configuration
In your chain’s application code, define which preinstalls to include inNewEVMGenesisState. The evmd reference chain includes all five defaults:
evmd/genesis.go
DefaultGenesis(), which is used when generating genesis state programmatically (e.g. evmd testnet).
Populating genesis.json
To enable preinstalls on a chain started from a genesis file (includinglocal_node.sh), populate the preinstalls array in genesis.json before starting the node. Each entry requires the contract name, address, and compiled bytecode:
genesis.json
x/vm/types/preinstall.go.
Adding Contracts After Launch
Governance Proposal
UseMsgRegisterPreinstalls to deploy contracts on a running chain via governance:
proposal.json
Chain Upgrade Handler
Include preinstalls in a coordinated chain upgrade:app/upgrades/v2/upgrades.go
Adding Custom Contracts
To deploy a contract beyond the defaults, add it to your preinstalls list:evmd/genesis.go
- 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)
Verification
After the chain starts with preinstalls in genesis.json, confirm the contracts are installed:code returns null, the preinstall was not included in genesis.json when the chain was initialized.
Troubleshooting
| Error | Cause | Fix |
|---|---|---|
preinstall already has an account in account keeper | Address already has a contract | Choose a different address |
preinstall has empty code hash | Invalid or empty bytecode | Verify bytecode hex string is valid and non-empty |
preinstall address is not a valid hex address | Malformed address | Ensure 0x prefix and 40 hex characters |
invalid authority | Wrong governance address | Use the correct gov module account address |