Create2 & create3

Both CREATE2 and CREATE3 have been around for some time. They allow us to know the address of a contract before it's deployed, which can be very useful. They also make it possible to deploy a contract to the same address on multiple blockchains.

CREATE2 no longer requires the nonce, whereas CREATE3 also no longer requires the bytecode.

CREATE3 seems to be the most convenient solution for multi-blockchain apps. But there doesn't seem to be much information about it.

So should we be using CREATE3 over CREATE2?
Are there any issues with either?

1 Like

CREATE2 factory with contract deployed on many blockchains (at 0x98b2920d53612483f91f12ed7754e51b4a77919e): https://docs.axelar.dev/dev/general-message-passing/solidity-utilities#constant-address-deployer

CREATE3 factory with contract deployed on many blockchains (at 0x93FEC2C00BfE902F733B57c5a6CeeD7CD1384AE1): https://github.com/lifinance/create3-factory

A widely used deterministic CREATE2 deployer: https://github.com/Arachnid/deterministic-deployment-proxy

It has been deployed on 31 blockchains (at 0x4e59b44847b379578588920cA78FbF26c0B4956C) for anyone to use to deploy their own contracts.

I think this one's the best future-proof option, e.g when a new blockchain comes along and you want to deploy your own contract at the same address as on the other blockchains. With the other options, you'd have to ask whoever had deployed the CREATE2 deployer contract to also deploy on the new blockchain so that you can then use it, as they're the ones who can make a transaction that would get the deployer contract to the same address.

With Arachnid/deterministic-deployment-proxy you can just send a raw transaction of the original contract creation transaction bytecode to the new blockchain, and it'll get created at the same address. Then you can use that to deploy your own contract, which would end up having the same address as on other blockchains.

The reusable deployment transaction bytecode is at https://etherscan.io/getRawTx?tx=0xeddf9e61fb9d8f5111840daef55e5fde0041f5702856532cdbb5a02998033d26

You can see that it has already been deployed onto other blockchains e.g.:

https://testnet.bobascan.com/getRawTx?tx=0xeddf9e61fb9d8f5111840daef55e5fde0041f5702856532cdbb5a02998033d26
https://optimistic.etherscan.io/getRawTx?tx=0xeddf9e61fb9d8f5111840daef55e5fde0041f5702856532cdbb5a02998033d26

To deploy the same deployer contract using ethers you'd just run this on a blockchain that doesn't have the contract at 0x4e59b44847b379578588920ca78fbf26c0b4956c yet:

txHash = await ethers.provider.send("eth_sendRawTransaction", [ "0xf8a58085174876e800830186a08080b853604580600e600039806000f350fe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe03601600081602082378035828234f58015156039578182fd5b8082525050506014600cf31ba02222222222222222222222222222222222222222222222222222222222222222a02222222222222222222222222222222222222222222222222222222222222222" ])

CREATE2 is more easily available, because it's just an opcode. I would stick to it unless you specifically need to use CREATE3 to create deterministic addresses that don't depend on the code.

1 Like

When even blank spaces and commented text affects bytecode and thus deployment address, it helps to have less factors that affect address when trying to deploy contracts to the same addresses across many blockchains.

New blockchains have been appearing which means there will be more dapps that support multiple blockchains. The same contracts need to be deployed to each of them, and that may not happen all at one time, as there could be future blockchains to add support for. Same addresses help to keep code simple and elegant.

The best way to deploy contracts to the same addresses on multiple blockchains is to use a keylessly-deployed CREATE3 factory contract to deploy your contracts.

If a keylessly-deployed CREATE3 factory contract doesn't exist yet on a blockchain, then deploy it yourself, and it will get the same address as the same factory contract on other blockchains (as long as the deployment creation code remains unchanged) because of the keyless deployment method - nobody owns (or knows the private keys of) the signer whose address is in the from field in the transaction, as that address is derived from a manually-entered signature.

The pros and cons of various ways to deploy contracts in order to achieve the goal of same addresses on multiple blockchains is covered in SKYBIT Keyless Deployment.

There you'll also find scripts to:

  • deploy CREATE3 factories using the keyless deployment method;
  • deploy your contracts keylessly if you don't want to use a factory;
  • deploy your contracts (including upgradeable contracts) via CREATE3.

Don't use that one, because it doesn't hash deploying account's address with the salt, so others could deploy your contract to the same address on a different blockchain, which you may not have wanted.