CREATE3: Deploying Contracts to the Same Address Across Multiple EVM Chains

·

In today’s multi-chain ecosystem, Ethereum Virtual Machine (EVM)-compatible blockchains are flourishing. As decentralized applications (dApps) expand across networks like Ethereum, Polygon, Arbitrum, and Optimism, developers face a growing need: deploying smart contracts to identical addresses on multiple chains. This uniformity simplifies frontend integrations, contract interconnectivity, and cross-chain management.

One innovative solution to this challenge is CREATE3, a pattern that leverages existing EVM opcodes to achieve deterministic contract deployment addresses—regardless of constructor parameters or chain-specific states. While there was once a proposal for a native CREATE3 opcode (EIP-3173), it was ultimately deemed unnecessary since the same outcome can be achieved through clever contract design.

Let’s explore how CREATE, CREATE2, and finally CREATE3 evolve this capability—and how you can implement it effectively in your dApp architecture.


Understanding Contract Creation: From CREATE to CREATE2

Before diving into CREATE3, it's essential to understand its predecessors and their limitations.

CREATE: The Original Deployment Mechanism

Purpose: Allows a contract or externally owned account (EOA) to deploy a new contract during execution.

How It Works:
The address of the newly created contract is derived from the creator’s address and nonce:

address = keccak256(rlp([sender_address, sender_nonce]))[12:]

Limitation:
Since a contract’s nonce increments only when it creates another contract, achieving the same address across chains requires perfectly synchronized nonces—something nearly impossible in practice. This makes cross-chain address consistency impractical with CREATE alone.

👉 Discover how top developers streamline multi-chain deployments today.


CREATE2: Predictable Addresses Based on Init Code

Purpose: Enables deployment to a predictable address determined at compile time, not runtime.

How It Works:
The new contract’s address depends on four factors:

address = keccak256(0xff + sender_address + salt + keccak256(init_code)))[12:]

Advantage:
Developers can pre-calculate where a contract will live before deployment—ideal for upgradeable patterns and meta-transactions.

Catch:
The init_code includes constructor arguments. So if different chains require different initialization data (e.g., chain-specific config), the resulting hash—and thus the address—will differ.

This limitation leads us directly to CREATE3.


Introducing CREATE3: Same Address, Any Chain

What Is CREATE3?

CREATE3 is not a new opcode but a design pattern that combines CREATE2 and CREATE to ensure contracts are deployed to the same address across all EVM chains, even with varying constructor arguments.

Core Objective

Ensure that:

How Does CREATE3 Work?

Here’s the step-by-step process:

  1. Assume a shared CREATE3 Factory exists across all target chains at the same address.
  2. Developer sends a transaction to the factory with:

    • A chosen salt
    • The target contract’s init_code (including constructor args)
  3. The factory uses CREATE2 to deploy a temporary CREATE2 Proxy contract using a fixed, hardcoded init_code.
  4. Because both the factory address and the proxy’s init_code are identical across chains, the proxy lands at the same address everywhere.
  5. The proxy then uses CREATE to deploy the final contract.
  6. Since the proxy’s address and initial nonce (1) are consistent, so is the final contract’s address.
✅ Final Contract Address Formula:
new_address = keccak256(rlp([create2_proxy_address, 1]))[12:]

This elegant workaround removes dependency on dynamic variables like init_code hashes while preserving full flexibility in deployment logic.


Inside the Fixed Init Code: Bytecode Magic

A fascinating aspect of CREATE3 is the hardcoded init code used by the CREATE2 Proxy:

67 **363d3d37363d34f0** 3d5260086018f3

The bold section (363d3d37363d34f0) represents the actual runtime bytecode stored on-chain—the logic of the proxy itself. It performs a simple but crucial task:

Notable gas optimizations:

This minimal footprint ensures efficiency without sacrificing functionality.


Setting Up the CREATE3 Factory

For the system to work, one prerequisite must be met: the CREATE3 Factory must exist at the same address on all chains.

Two common approaches:

Option 1: Self-Deploy Using a New EOA

Option 2: Use a Public Factory

Projects like ZeframLou/create3-factory offer pre-deployed factories.

👉 See how leading teams manage multi-chain deployments securely and efficiently.


Frequently Asked Questions (FAQ)

Q: Is CREATE3 an EVM opcode?

No. CREATE3 is a contract design pattern, not a new opcode. It builds upon existing EVM mechanics (CREATE and CREATE2) to achieve deterministic addressing.

Q: Can I use OpenZeppelin’s Ownable with CREATE3?

Yes—but with caution. In the constructor, msg.sender will be the CREATE2 Proxy, not your wallet. To fix this, call transferOwnership(msg.sender) at the end of construction or use alternative ownership patterns.

Q: Does CREATE3 increase gas costs?

Yes, slightly. You pay extra for deploying both the factory (one-time) and the ephemeral proxy per deployment. However, this cost is often justified by improved cross-chain interoperability.

Q: Can I predict the final contract address before deployment?

Absolutely. As long as you know:

Q: What happens if I reuse a salt?

Reusing a salt results in redeploying the proxy—but since it already exists, CREATE2 reverts. Each salt should be unique per intended deployment.

Q: Are there security risks with CREATE3?

Main risks include:


Key Considerations When Using CREATE3

While powerful, CREATE3 introduces complexity:


Final Thoughts

CREATE3 exemplifies how developers innovate within constraints. By combining CREATE and CREATE2, it reduces address-determining variables down to just two: deployer address and salt. This enables seamless multi-chain deployments with predictable outcomes.

As interoperability becomes central to Web3 architecture, patterns like CREATE3 will play a vital role in building scalable, maintainable dApps across ecosystems.

Whether you're launching a cross-chain DEX or managing complex protocol upgrades, understanding CREATE3 gives you greater control over your deployment strategy—and prepares you for the future of modular blockchain development.

👉 Start building smarter multi-chain applications with advanced deployment tools.