Author: @Norswap

Recipe

  1. Make sure your chain has the deterministic cross-chain deployer deployed at 0x4e59b44847b379578588920ca78fbf26c0b4956c

    If not, deploying it yourself by:

  2. Send the contract creation transaction initcode to the cross-chain deployer. It will be deployed at a deterministic address based on that code.

For further reference, see https://github.com/Arachnid/deterministic-deployment-proxy/

Explanation

CREATE

The CREATE opcode deployment address depends on the nonce, so it cannot be used for deterministic deployments (opcodes can only be executed by contracts). Using an EOA for deterministic deployment is possible, but only if the contract deployment is the first transaction on every chain (more generally, if the nonce is the same). It also requires custody of the EOA private key, excluding permissionless deployment scenarios.

CREATE2

The CREATE2 opcode enables deterministic deployment, depending this time on the contract init code and a salt. The problem is it needs to be sent from a contract, whose address must itself be consistent across chains for the final address to be deterministic across chains.

Deterministic Cross-Chain Deployer

A solution to this is using the CREATE2 deployer contract. This contract is itself deployed on every chain with the same legacy transaction. Legacy transactions do not include the chain ID and can be replayed on every chain.

This transaction itself uses an unknow private key: instead a transaction is generated with a random signature, and the public key is reversed engineered. Users can then send funds to that address and execute the transaction (the only one that can be sent, since the private key is unknown).

This is called “Nick’s method”. This method enables anyone to deploy the deployer, then anyone to use the deployer to solve the problems above (enabling deterministic deployments without owning the private key, or from a smart contract).

This method has two pitfalls:

  1. this only works for networks that support the legacy transaction.
  2. the signed tx hardcodes the gas limit, which makes it unusable if the gas pricing is different than Ethereum (at the time where the transaction was created)

Alternative Deployers (CREATE3, CreateX)

The Solady “CREATE3” deterministic deployment contract (not an opcode) takes things further by enabling deterministic deployment at an address regardless of the init code. The pitfall here is that this depends on the salt and can be frontrun, so using a private mempool is a must.

The method is that a proxy is deployed (so the initcode is always the same). Presumably (wasn’t able to verify), the proxy simply accepts a call with the contract initcode, deploys it, and then sets itself up to delegate to it. It’s potentially annoying when deploying another proxy contract (two layers of proxy/DELEGATECALL).