How to use solidity CREATE and CREATE2
Published: 2023-07-27 04:55:33

## Overview

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

There are 2 major ways to deploy smart contract `CREATE` and `CREATE2`. They look quite similar, but there are still some differences.CREATE2 and CREATE are one of solidity opcode which give us the ability to predict the address where a contract will be deployed before we deploy a smart contract.You might be curious about what opcode is.Opcodes are the fundamental building blocks of EVM bytecode, and each opcode represents a specific operation that the EVM can perform. For example, there are opcodes for arithmetic operations, logical operations, storage access, memory manipulation, conditional branching, and more.

## What is CREATE
Smart contracts can be created both by other contracts and regular EOA.They both compute the new address the same way:

```shell
new_address = keccak256(sender, nonce)
```
So each created address is associated with a nonce value.Nonce increased on every transaction.It is related to the number of transactions we make and is unpredictable. That's why we need CREATE2.

## What is CREATE2 ?
The whole idea behind this opcode is to make the resulting address independent of future events. Regardless of what may happen on the blockchain, it will always be possible to deploy the contract at the precomputed address.There are four parameters in CREATE2 function:
* 0xFF
* the address of sender
* A salt (random value from sender)
* bytecode (the code of the new contract)

```shell
new_address = keccak256(0xFF, sender, salt, bytecode)
```

## Why we need CREATE2 ?

Imagine a scenario where you need to deploy a contract to multiple networks, and precisely at that moment, you need to store the addresses of the yet-to-be-deployed contracts as storage parameters within the currently deployed contract. In such cases, you would require knowing the future addresses of the contracts to be deployed in advance.

## How to use it 

### Use hash function to calculate address.

```solidity
    uint256 _salt = 1;
    bytes32 hash = keccak256(
        abi.encodePacked(
            bytes1(0xff),
            address(this),
            _salt,
            keccak256(type(TokenTemplate).creationCode)
        )
    );
```

### Use deploy to get the deployed address.

```solidity
    function deploy(
        bytes memory bytecode,
        uint _salt
    ) public payable returns (address) {
        address addr;

        assembly {
            addr := create2(
                callvalue(), // wei sent with current call
                // Actual code starts after skipping the first 32 bytes
                add(bytecode, 0x20),
                mload(bytecode), // Load the size of code contained in the first 32 bytes
                _salt // Salt from function arguments
            )

            if iszero(extcodesize(addr)) {
                revert(0, 0)
            }
        }

        return addr;
    }
```

you can find the whole code on github:
<https://gist.github.com/coffiasd/c2ff1a2d718d286b9064873be2fe079a>

Origin: <https://blog.coffiasd.cn/03-07-24.html>
Follow my twitter:<https://twitter.com/coffiasse>
TG:@coffiasd