Smart contract development on the Ethereum blockchain continues to evolve, offering developers powerful tools to build decentralized applications (dApps) with advanced functionality. One such capability is the ability for smart contracts to create other contracts—enabling dynamic, on-chain logic that responds to user interactions or system states. This article explores two core methods for contract creation within existing contracts: CREATE and CREATE2. We’ll dive into how they work, their differences, and practical use cases in modern blockchain development.
Understanding these mechanisms is essential for developers working with factory patterns, proxy systems, or any architecture requiring predictable or conditional deployment of new contracts.
Understanding Contract Creation in Ethereum
In Ethereum, both externally owned accounts (EOAs) and smart contracts can deploy new contracts. While EOAs initiate deployments through transactions, smart contracts can programmatically spawn new contract instances using built-in opcodes: CREATE and CREATE2.
These two methods serve similar purposes but differ significantly in how they determine the address of the newly created contract. Choosing between them impacts security, predictability, and design flexibility.
The core keywords for this topic include: smart contract creation, CREATE vs CREATE2, Ethereum contract deployment, predictable contract address, Solidity contract factory, contract address calculation, nonce-based deployment, and salted contract deployment.
Using CREATE to Deploy Contracts
The CREATE opcode allows a contract to deploy another contract using a deterministic formula based on the creator’s address and its current nonce—the number of transactions the account has sent.
👉 Discover how developers use contract factories to streamline dApp deployment
How CREATE Works
When a contract uses CREATE, the resulting address is calculated as:
newAddress = hash(creatorAddress, nonce)This means each time the deploying contract sends a deployment transaction, the nonce increments, leading to a different address for each new contract.
Syntax in Solidity
In Solidity, deploying a contract via CREATE is straightforward:
Contract x = new Contract{value: _value}(params);Where:
Contractis the name of the contract being deployed.xis the reference to the newly created contract instance._value(optional) specifies the amount of ETH to send if the constructor is payable.paramsare arguments passed to the new contract’s constructor.
Note: To use CREATE, you must have access to the bytecode of the contract you're deploying. This is typically handled automatically by Solidity when referencing another contract type.Because the address depends on the nonce, it cannot be predicted far in advance—only after all prior transactions from the creator are known. This limits its usefulness in scenarios requiring precomputed addresses.
Leveraging CREATE2 for Predictable Deployments
While CREATE offers simplicity, CREATE2 introduces a major upgrade: predictable contract addresses independent of the creator’s nonce. This enables powerful patterns like pre-deploying logic, trustless proxies, and upgradeable systems.
Why Use CREATE2?
With CREATE2, you can compute the address of a future contract before it's deployed—regardless of what happens on-chain in the meantime. This is invaluable for:
- Delayed deployments
- Wallet recovery systems
- Minimal proxy factories
- Gas-efficient singleton patterns
Address Calculation Formula
The address generated by CREATE2 is derived from four components:
newAddress = hash(0xFF, creatorAddress, salt, bytecodeHash)Where:
0xFFis a constant prefix to avoid collision withCREATE.creatorAddressis the address of the deploying contract.saltis a user-defined value (e.g., a hash or random number).bytecodeHashis the Keccak-256 hash of the contract’s creation bytecode.
This allows developers to simulate deployments off-chain and verify that a contract will land at a specific address when conditions are met.
Implementation Example
In Solidity, using CREATE2 requires specifying a salt:
Contract x = new Contract{salt: _salt, value: _value}(params);Alternatively, using inline assembly gives more control:
assembly {
addr := create2(0, add(bytecode, 0x20), mload(bytecode), salt)
}Here:
0represents the value in wei sent.add(bytecode, 0x20)points to where bytecode starts in memory.mload(bytecode)loads the size of the bytecode.saltmust match the one used in pre-calculation.
👉 Learn how top-tier dApps leverage predictable addresses for seamless user experiences
This level of control makes CREATE2 ideal for advanced architectures like account abstraction (ERC-4337), where wallets are deployed deterministically upon first use.
Practical Use Cases and Developer Benefits
Both CREATE and CREATE2 play vital roles in real-world applications:
Factory Patterns
A common design pattern involves a "factory" contract that spawns multiple instances of a template contract (e.g., NFT collections, token pools). With CREATE, each new instance gets a unique address based on sequence. With CREATE2, factories can pre-calculate addresses for better UX and integration testing.
Upgradeable Systems
Using CREATE2, developers can deploy logic contracts at known addresses, making upgrades easier and more secure. This is especially useful in proxy-based upgrade patterns where the implementation address must remain consistent across versions.
Trustless Deployment
Since CREATE2 allows off-chain simulation, users can verify that a contract will deploy correctly before triggering the transaction—enhancing transparency and reducing risks.
Frequently Asked Questions (FAQ)
Q: What’s the main difference between CREATE and CREATE2?
A: The key difference lies in address determination. CREATE uses the creator’s address and nonce, making addresses sequential and non-repeatable. CREATE2 uses a salt and bytecode hash, enabling predictable and repeatable deployments regardless of nonce state.
Q: Can I change the salt in CREATE2 after calculating an address?
A: No. The salt is part of the hashing formula. Changing it results in a different address. To maintain predictability, the same salt must be used during both calculation and deployment.
Q: Is CREATE2 more expensive than CREATE in terms of gas?
A: Generally yes—CREATE2 consumes slightly more gas due to additional hashing operations. However, the added functionality often justifies the minimal cost increase.
Q: Can I use CREATE2 to redeploy a contract at the same address after self-destructing it?
A: Yes! Unlike CREATE, which relies on nonce progression, CREATE2 lets you redeploy at the same address as long as the bytecode and salt remain unchanged—even after the previous contract was destroyed.
Q: Do I need assembly to use CREATE2?
A: Not necessarily. Modern Solidity supports new Contract{salt: ...} syntax. Inline assembly is only needed for low-level optimizations or custom deployment logic.
👉 Explore secure deployment strategies used by leading blockchain projects
Summary: Choosing Between CREATE and CREATE2
Both CREATE and CREATE2 allow smart contracts to create other contracts, but their use cases differ:
- Use
CREATEwhen simplicity is key and address predictability isn’t required. - Use
CREATE2when you need deterministic addresses, support for redeployment, or integration with advanced patterns like account abstraction or minimal proxies.
As Ethereum evolves toward greater scalability and usability, tools like CREATE2 become increasingly critical for building robust, future-proof dApps.
By mastering these deployment techniques, developers gain fine-grained control over contract lifecycle management—unlocking innovative solutions in DeFi, gaming, identity systems, and beyond.