Using CREATE2 to deploy contracts at known addresses
A guide to using CREATE2 to predetermine the contract address before you deploy it.
Table of Contents for Using CREATE2 to deploy contracts at known addresses
When you deploy a smart contract, its address is generated based on a hash of the sender
and nonce
.
This means you can quite easily determine the deploy address - as long as you know the nonce and are sure it will definitely be that value (it increases with each transaction from an address).
If you need to know the address of a deployed contract regardless of the nonce you can use CREATE2
.
Using CREATE2
, the address is generated by a hash of the creator address (which never changes), a salt passed in as a param (which you control), and the contract creation code.
With those details you can always know the deploy address of a contract.
Here are a couple of examples of deploying solidity smart contracts using CREATE2
.
This gives you a function that lets you deploy a contract (you pass in the contract creation code) and a salt.
You could also calculate the deploy address in another language (like JS) so you know where a smart contract will be deployed.
Deploying a smart contract using CREATE2 in assembly code
Originally the only way to deploy with CREATE2
was via assembly language. (Scroll down to see an alternative/easier way)
contract YourContract {
function deployAContract(bytes memory contractCode, bytes32 salt) public returns (address addr) {
assembly {
addr := create2(0, add(contractCode, 0x20), mload(contractCode), salt)
if (iszero(extcodesize(addr))) {
revert(0, 0)
}
}
}
}
Deploying with CREATE2 by passing in salt
The easier way is to just pass in the {salt: yourSalt}
param when deploying a new contract.
The example below will return the deployed address.
contract YourContract {
function deploy(
bytes32 _salt
) public payable returns (address) {
return address(new ContractToDeploy{salt: _salt}());
}
}
Using the above, you can pass in the _salt
.
How to predict the address before deploying a smart contract (with CREATE2)
Here is the example Solidity code to predict where a smart contract will be deployed at, when using CREATE2
with the supplied salt.
You have to do some conversion (hash it, turn into uint256, then turn into 160 byte address.
// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;
contract SomeContractToDeploy {
//...
}
contract Factory {
function whereWillItDeploy(bytes32 salt, uint arg) public returns (address) {
address predictedAddress = address(uint160(uint(keccak256(abi.encodePacked(
bytes1(0xff),
address(this),
salt,
keccak256(abi.encodePacked(
type(SomeContractToDeploy).creationCode,
abi.encode(arg)
))
)))));
return predictedAddress;
}
}
Spotted a typo or have a suggestion to make this crypto dev article better? Please let me know!
Previous post
π Solidity Auditing online quiz
Learn how to audit smart contracts by looking at some example code and trying to find the bugs
β½ Solidity Gas Optimizations Guide
How to optimize and reduce gas usage in your smart contracts in Solidity
π§ͺ Guide to testing with Foundry
Guide to adding testing for your Solidity contracts, using the Foundry and Forge tools
π Guide to UTXO
UTXO and the UTXO set (used by blockchains such as Bitcoin) explained
π Solidity Assembly Guide
Introduction guide to using assembly in your Solidity smart contracts
π¦ Ethereum EOF format explained
Information explaining what the upcoming Ethereum EOF format is all about