CREATE a CONTRACT with 2 SAME addresses on 2 DIFFERENT chains

Alain | Web3hackingLabs
3 min readNov 6, 2022

Did you know that it was possible to create 2 smart contract on different blockchains with the same address?

In this article we will see how it’s possible and how to do that.

2 different ways of creating a smart contract.

To understand how it’s possible you need to know how addresses are calculated when you deploy a smart contract, they aren’t random.

The first way using CREATE opcode is not deterministic, this means that you can’t predict from the deployed smart contract which address the deployed smart contract will occupy.

To upgrade the EVM and bypass this limitation, in April 2018 the EIP 1014 was released, it introduced a new opcode, the CREATE2 opcode, which permit you to create the smart contract (like CREATE) and to compute the smart contract address BEFORE the smart contract creation, which wasn’t always possible with the CREATE opcode.

Note that CREATE or CREATE2 are the ONLY way to deploy a smart contract with another smart contract.

Deploying with CREATE.

When you deploy a smart contract with another smart contract on solidity.

The address of the smart contract is calculated using:

  • The address of msg.sender.
  • The “nonce”. (usually the number of transactions)

Here is the simple formula:

Address = bytes20(keccak256(senderAddress, nonce))

Here is a simple example from solidity:

pragma solidity ^0.8.0;contract testContract { //code }contract Deployer {
function Deploy() public returns(address) {
testContract test = new testContract();
return address(test);
}
}

For example let’s say:

  1. You go on the remix IDE website.
  2. You compile a simple smart contract. (The code of the smart contract doesn’t have any relevance.)
  3. You deploy it on the remix blockchain (inside the browser) with the default address: 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4

The first deployed smart contract address will always be 0xd9145CCE52D386f254917e481eB44e9943F39138 (Address 0x5b…, nonce 0)

And if you deploy another one, it will be: 0xd8b934580fcE35a11B58C6D73aDeE468a2833fa8 (Address 0x5b…, nonce 1)

And so on… (You can test by yourself)

Deploying with CREATE2

There is another way to deploy a smart contract with a different address, easier to predict this time.

There are 4 parameters (note that the nonce is not present anymore):

  • 0xFF
  • msg.sender
  • The salt (an arbitrarily value you can choose).
  • The byte code of the smart contract to deploy.

The address is computed as follows:

address = bytes20(keccak256(0xFF, senderAddress, salt, bytecode))

Since solidity 0.8 you can use CREATE2 in solidity by specifying the salt as follows:

pragma solidity ^0.8.0;contract testContract { //code }contract Deployer {
function Deploy(bytes32 salt) public returns(address) {
testContract test = new testContract{salt: bytes32(_salt)}();
return address(test);
}
}

Now the addresses should be very different.

How to deploy my contract on 2 different chains with the same address?

Now, let’s answer to the question: How to deploy a smart contract with the same addresses in 2 different chains?

  1. You can do it with the CREATE opcode by providing the same nonce. (which is not easy because, the nonce at every transaction increment by 1)
  2. You can do it with the CREATE2 opcode by providing the same salt on different chains. (easier than providing the nonce because you can’t fully control it)

So, the best method is obviously CREATE2.

Conclusion

I hope you’ve learnt something new and see you in the next article!

--

--

Alain | Web3hackingLabs

Smart contract Auditor & Cybersecurity engineer, follow me on Twitter to get more value: https://rebrand.ly/twitter_medium