CREATE2 opcode helps us to predict the address of the smart contract before it is deployed on the Ethereum network, and Uniswap created Pair contract with CREATE2 instead of CREATE.
In this chapter, I will introduce the use of CREATE2.
How does CREATE calculate the address
Smart contracts can be created by other contracts and regular accounts using the CREATE opcode.
In both cases, the address of the new contract is calculated in the same way: the hash of the creator's address (usually the wallet address which will deploy or the contract address) and the nonce(the total number of transactions sent from this address or, for contract account, the total number of contracts created. Every time a contract is created, the nonce will plus one).
creator's address won't change, but the nonce may change over time, so it's difficult to predict the address of the contract created with CREATE.
How does CREATE2 calculate address
The purpose of CREATE2 is to make contract addresses independent of future events. No matter what happens on blockchain in the future, you can deploy the contract to a pre-calculated address.
The address of the contract created with CREATE2 is determined by four parts:
0xFF: a constant to avoid conflict withCREATE- creator's address
- salt: a value given by the creator
- The bytecode of the contract to be deployed
CREATE2 ensures that if the creator deploys a given contract bytecode with CREATE2 and is given salt, it will be stored at new address.
How to use CREATE2
CREATE2 is used in the same way as Create. It also creates a new contract and passes in parameters which are needed for the new contract constructor, except with an extra salt parameter.
Contract is the name of the contract to be created, x is the contract object (address), and _salt is the specified salt; If the constructor is payable, a number of(_value) ETH can be transferred to the contract at creation, and params is the parameter of new contract constructor.
Minimalist Uniswap2
Similar to the previous chapter, we use Create2 to implement a minimalist Uniswap.
Pair
Pair contract is simple and contains three state variables: factory, token0 and token1.
The constructor assigns the factory to the factory contract address at deployment time. initialize function is called once by the factory contract when the Pair contract is created, updating token0 and token1 to the addresses of two tokens in the token pair.
PairFactory2
Factory contract(PairFactory2) has two state variables. getPair is a map of two token addresses to the token pair address. It is convenient to find the token pair address according to tokens. allPairs is an array of token pair addresses, storing all token pair addresses.
PairFactory2 contract has only one createPair2 function, which uses CREATE2 to create a new Pair contract based on the two token addresses tokenA and tokenB entered. Inside
It's the above code that uses CREATE2 to create a contract, which is very simple, and salt is the hash of token1 and token2.
Calculate the Pair address beforehand
We write a calculateAddr function to precompute the address of Pair that tokenA and tokenB will generate. With it, we can verify whether the address we calculated in advance is the same as the actual address.
To verify whether the address of the token pair created matches the precomputed address, you can deploy the PairFactory2 contract and call createPair2 with the following two addresses as parameters. Then, observe the resulting address of the token pair created.
If there are parameters in the deployment contract constructor
For example, when create2 contract:
Pair pair = new Pair{salt: salt}(address(this));
When calculating, you need to package parameters and bytecode together:
keccak256(type(Pair).creationCode)=> keccak256(abi.encodePacked(type(Pair).creationCode, abi.encode(address(this))))
Verify on remix
- First, the address hash of
WBNBandPEOPLEis used assaltto calculate the address ofPaircontract - Calling
PairFactory2.createPair2and the address ofWBNBandPEOPLEare passed in as parameters to get the address ofpaircontract created. - Compare the contract address.

Application scenario of CREATE2
- The exchange reserves addresses for new users to create wallet contracts.
Factorycontract driven byCREATE2. The creation of trading pairs inUniswapV2is done by callingcreate2inFactory. The advantage is that it can get a certainpairaddress so that the Router can calculatepairaddress through(tokenA, tokenB), and no longer need to perform aFactory.getPair(tokenA, tokenB)cross-contract call.
Summary
In this chapter, we introduced the principle of CREATE2 opcode and how to use it. Besides, we used it to create a minimalist version of Uniswap and calculate the token pair contract address in advance. CREATE2 helps us to determine the contract address before deploying the contract, which is the basis for some layer2 projects.