New to predeployed contracts? Start here:
- Predeployed Contracts Concept - Understanding predeployed contracts and how they differ from precompiles
- Predeployed Contracts Overview - Quick reference of available contracts
- Building Your Chain Guide - Quick start configuration examples
- Create2 Factory - Deterministic deployment patterns
- Multicall3 - Batch operations examples
- Permit2 - Signature-based approvals
- Safe Factory - Multisig wallet deployment
Getting Started
There are several methods to deploy preinstalled contracts on a Cosmos EVM chain:1. Genesis Configuration
The most straightforward method for new chains or testnets. Contracts are deployed when the chain is first initialized.- Default Configuration
- Custom Genesis Configuration
If using the reference
evmd
application, your chain automatically includes default preinstalls, however they will not be active by default.Local Development
Thelocal_node.sh
script automatically configures default preinstalls:
2. Governance Proposal
For chains already in production, use theMsgRegisterPreinstalls
governance proposal:
Proposal Structure
The
authority
field must be set to the governance module account address, which is typically derived from the gov module name. This is usually something like cosmos10d07y265gmmuvt4z0w9aw880jnsr700j6zn9kn
for the standard gov module.Submission Process
3. Chain Upgrade Handler
Include predeployed contracts as part of a coordinated chain upgrade:Implementation Details
Validation Process
All preinstall deployments undergo strict validation:-
Address Validation
- Must be valid Ethereum address format (40 hex characters)
- Cannot conflict with existing contracts
- Should not overlap with precompile reserved addresses (typically 0x1-0x9FF)
-
Code Validation
- Must be valid EVM bytecode (hex encoded)
- Cannot have empty code hash
- Must pass bytecode verification
-
Conflict Prevention
- Checks for existing contracts at target address
- Validates against account keeper for existing accounts
- Ensures no code hash conflicts with different bytecode
Storage and State
Predeployed contracts are stored in the chain state like regular contracts:Verification and Testing
Verify Deployment
After deployment, verify contracts are properly installed:Testing Strategy
- Local Testing: Deploy on local node first
- Testnet Validation: Test governance proposal process
- Integration Testing: Verify interactions with other contracts
- Gas Analysis: Monitor gas consumption patterns
- Security Audit: Review bytecode before mainnet deployment
Best Practices
Security Considerations
- Bytecode Verification: Always verify that bytecode matches official releases
- Address Selection: Ensure addresses don’t conflict with future plans
- Audit Requirements: Even well-known contracts should be reviewed
- Immutability: Remember that predeployed contracts cannot be upgraded
Deployment Recommendations
- Start with Defaults: Use
evmtypes.DefaultPreinstalls
unless you have specific requirements - Test Thoroughly: Validate on testnet before mainnet deployment
- Document Changes: Clearly communicate any non-standard deployments to developers
- Monitor Usage: Track contract interactions to understand adoption
Common Pitfalls to Avoid
- Don’t deploy to addresses that could conflict with precompiles (typically 0x1-0x9FF)
- Don’t assume contracts are deployed - always check first
- Don’t modify standard contract addresses without strong justification
- Don’t deploy untested or unaudited bytecode
Known Issues
Critical - Safe Factory Bytecode ErrorThe Safe Singleton Factory bytecode in Before deploying to production:
DefaultPreinstalls
(x/vm/types/preinstall.go:30-32
) is identical to the Create2 factory bytecode, which is incorrect and will not function for deploying Safe wallets.Verification:- Get the correct Safe Singleton Factory bytecode from the official repository
- Update your genesis
preinstalls
configuration with the correct bytecode - Test thoroughly on a testnet
- See the Safe Factory documentation for more details
Adding Custom Preinstalls
To add custom contracts beyond the defaults:Troubleshooting
Common Issues
Issue | Cause | Solution |
---|---|---|
”preinstall already has an account in account keeper” | Address collision | Choose different address |
”preinstall has empty code hash” | Invalid or empty bytecode | Verify bytecode hex string is valid |
”preinstall address is not a valid hex address” | Malformed address | Ensure 0x prefix and 40 hex chars |
”invalid authority” | Wrong governance address | Use correct gov module account address |
Contract not found after deployment | Wrong network | Verify chain ID and RPC endpoint |
Debugging Steps
- Check chain genesis configuration
- Verify proposal passed and executed
- Query contract code directly
- Test with simple contract interaction
- Review chain logs for errors
Quick Reference
Default Preinstalls
| Contract | Address | Bytecode Field | Status | |-|||—| | Create2 |0x4e59b44847b379578588920ca78fbf26c0b4956c
| preinstall.Code
| ✓ Verified |
| Multicall3 | 0xcA11bde05977b3631167028862bE2a173976CA11
| preinstall.Code
| ✓ Verified |
| Permit2 | 0x000000000022D473030F116dDEE9F6B43aC78BA3
| preinstall.Code
| ✓ Verified |
| Safe Factory | 0x914d7Fec6aaC8cd542e72Bca78B30650d45643d7
| preinstall.Code
| ⚠️ Bytecode Issue |
| EIP-2935 | 0x0b
| params.HistoryStorageCode
| ✓ System Contract |
Source: x/vm/types/preinstall.go:13-39
Genesis Configuration Paths
Further Resources
Official Specifications
- EIP-1014: CREATE2 Specification - Understanding deterministic deployment
- EIP-2935: Historical Block Hashes - Block hash storage specification
Contract Documentation
- Multicall3 Documentation - Official Multicall3 repository
- Permit2 Introduction - Uniswap’s Permit2 design
- Safe Contracts - Safe multisig implementation
Cosmos EVM Resources
- VM Module Reference - Complete VM module configuration