Tutorial - Using create2 to predict the contract address before deploying
Tags: programming, solidity, blockchain, tutorial
Published: 2022-06-13 14:52:12

> _This tutorial is meant for those with a basic knowledge of Ethereum and smart contracts, who have some knowledge of Solidity._
> The purpose of building this blog is to write down the detailed operation history and my memo for learning the dApps and solidity programming.
> If you are also interested and want to get hands dirty, just follow these steps below and have fun!~

### Prerequisites
- [Remix](https://remix.ethereum.org/) for contract testing
- Basic knowledge of [Ethereum](https://ethereum.org/en/) and [Solidity](https://docs.soliditylang.org/en/v0.8.14/)

The create2 opcode gives us the ability to predict the contract address where a contract will be deployed. This opens up lots of possibilities to improve user onboarding and scalability.

### contract overview
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.14;
//Use Create2 to know contract address before it is deployed.
contract DeployWithCreate2 {
    address public owner;
    constructor(address _owner) {
        owner = _owner;
    }
}
contract Create2Factory {
    event Deploy(address addr);
    // to deploy another contract using owner address and salt specified
    function deploy(uint _salt) external {
        DeployWithCreate2 _contract = new DeployWithCreate2{
            salt: bytes32(_salt)    // the number of salt determines the address of the contract that will be deployed
        }(msg.sender);
        emit Deploy(address(_contract));
    }

    // get the computed address before the contract DeployWithCreate2 deployed using Bytecode of contract DeployWithCreate2 and salt specified by the sender
    function getAddress(bytes memory bytecode, uint _salt) public view returns (address) {
        bytes32 hash = keccak256(
            abi.encodePacked(
                bytes1(0xff), address(this), _salt, keccak256(bytecode)
            )
        );
        return address (uint160(uint(hash)));
    }
    // get the ByteCode of the contract DeployWithCreate2
    function getBytecode(address _owner) public pure returns (bytes memory) {
        bytes memory bytecode = type(DeployWithCreate2).creationCode;
        return abi.encodePacked(bytecode, abi.encode(_owner));
    }
}
```
> We use Create2Factory to deploy the contract DeployWithCreate2. First we get the byteCode of the contract DeployWithCreate2 using the function `getBytecode`, and then we use `byteCode` and owner-specified `salt` to compute the address of contract DeployWithCreate2. Finally we use function `deploy` to deploy the contract DeployWithCreate2 to see the actuall contract address.

### Contract testing steps
#### getBytecode

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/h2ikhc5nutc7eqqsy6x4.png)

#### getAddress

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6o2cbwdl5fggq9l9iu8d.png)

#### deploy with the same salt value
![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/2qkgzlsun97ont3gjgij.png)

#### check logs
```linux
logs	[
	{
		"from": "0xDA0bab807633f07f013f94DD0E6A4F96F8742B53",
		"topic": "0x55ea6c6b31543d8e2ec6a72f71a79c0f4b72ed0d4757172b043d8f4f4cd84848",
		"event": "Deploy",
		"args": {
			"0": "0x0B4f6a49C6a97B5dBB62F8A594cDefe5EabB4658",
			"addr": "0x0B4f6a49C6a97B5dBB62F8A594cDefe5EabB4658"
		}
	}
```

### Git repository
Welcome to visit the Git repo for source code (Create2.sol or Example-44), and feel free to reach me by leaving a message below or via email found in my profile. 

Thank you!

{% embed https://github.com/hyc0812/solidity-essentials %}

### References
https://docs.openzeppelin.com/cli/2.8/deploying-with-create2
https://www.youtube.com/watch?v=883-koWrsO4&list=PLO5VPQH6OWdVQwpQfw9rZ67O6Pjfo6q-p&index=58
https://blog.openzeppelin.com/getting-the-most-out-of-create2/