EIP-3171 was an EIP that introduced a new native opcode (CREATE3
) that enabled deterministic contract creation similar to that of CREATE2
but with the initcode
removed from the address derivation formula. Unfortunately, the EIP was rejected, in part due to the emergence of a popular application-layer approximation bearing the same name. However, this approximation leveraged a combination of the CREATE
and CREATE2
opcodes to achieve its functionality, and in doing so increased the compute cost of mining efficient addresses by severalfold while also breaking compatibility with existing salt mining tooling.
CREATE4
is a different approach to approximating the functionality lost in the rejection of EIP-3171. Despite the name, the address derivation formula for CREATE4
is significantly closer to what a native CREATE3
opcode would have possessed than the original CREATE3
app-layer implementation was. Because CREATE4
uses a single CREATE2
call with a fixed initCode
under the hood, create2crunch can be used to mine CREATE4
salts for efficient addresses at no additional compute cost over CREATE2
mining.
- Store the
deployedCode
of the desired contract somewhere on-chain (in order of gas cost) - Expose the
deployedCode
via a getter function with support for returning from both transient storage and from a contract address based on previously set flags in storage. This ensures that the method of code storage does not affect the address derivation formula. CREATE2
with a user's salt and "bootstrap"initCode
containing their address somewhere (for front-running protection) that queries thedeployedCode
from the getter function and returns it.- We now have a process that can be used to deploy any bytecode with a deterministic address based on the
msg.sender
and a salt.
For Create4Factory
, the initCode
is constructed as follows:
- Executable constructor:
3636363636335af13d36363e3d36f3
- Deployer address (user calling
create4
):ffffffffffffffffffffffffffffffffffffffff
(20-byte salt)
Result: 0x3636363636335af13d36363e3d36f3<deployer address>
If we have
Create4Factory
address:0xe358511cd9bf45c8a4d4aaf96ad5f6234ad20282
(note: not the real-world address!)- Deployer address:
0xab5801a7d398351b8be11c439e05c5b3259aec9b
(Vb)
Our initCode
would be:
0x3636363636335af13d36363e3d36f3ab5801a7d398351b8be11c439e05c5b3259aec9b
- Deterministic contract address based on
msg.sender
+ salt - Simple,
CREATE2
-compatible address derivation formula with ideal compute cost - Front-running protection
- Cheaper than CREATE3 for smaller contracts on chains with EIP-1153 support
- Same contract addresses on different EVM networks (even those without support for EIP-1153)
- Supports any EVM compatible chain with support for CREATE2 (& PUSH0)
- ~1.93-1.95x deployment cost increase for chains without EIP-1153 (transient storage) support
- ~7-10% deployment cost increase for chains with EIP-1153 support
- No constructor support (deployed bytecode must be precomputed)
None yet :)
Call the create4
method on the Create4Factory
, provide the contract creationCode
(on EIP-1153 networks) or the address of a deployed contract containing the code you want to deploy (on non-EIP-1153 networks) and a salt. Different contract codes will result on the same address as long as the same salt is provided.
We compare the approximate cost of deploying a contract consisting of N FF
bytes from an EOA via CREATE2
and CREATE4
- Transient storage:
create4(bytes, bytes32)
vsCREATE2
- Deployed code:
create4(address, bytes32)
vsCREATE2
Note: deployed code benchmarks also consider the cost of deploying the code from an EOA before calling create4(address, bytes32)
The code for the benchmarks can be found in test/Gasbench.t.sol and the results may be reproduced locally by running:
forge test --use bin/solc --match-contract C4GasBench -vv
-
Transient storage: 1.072x more expensive than CREATE2
-
Deployed code: 1.931x more expensive than CREATE2
- Transient storage: 1.080x more expensive than CREATE2
- Deployed code: 1.935x more expensive than CREATE2
- Transient storage: 1.095x more expensive than CREATE2
- Deployed code: 1.943x more expensive than CREATE2
- Transient storage: 3.075x more expensive than CREATE2
- Deployed code: 2.902x more expensive than CREATE2
forge install dyedm1/create4
forge build --use bin/solc
forge test --use bin/solc
forge fmt
//SPDX-License-Identifier: GPL-2.0-or-later
pragma solidity ^0.8.20;
import {Create4} from "lib/create4/src/Create4Factory.sol";
contract CreateMe {
function test() external view returns (uint256) {
return 0x1337;
}
}
contract Deployer {
function deployChild() external {
Create4Factory(0x0000000000000000000000000000000000000000).create4(type(CreateMe).deploymentCode, bytes32(0x1337));
}
}
Code in this repository is licensed under GPLv3 unless otherwise indicated (see LICENSE file).