DEV Community

Ayden
Ayden

Posted on

How to use solidity CREATE and CREATE2

Overview

Image description

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:

new_address = keccak256(sender, nonce)
Enter fullscreen mode Exit fullscreen mode

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)
new_address = keccak256(0xFF, sender, salt, bytecode)
Enter fullscreen mode Exit fullscreen mode

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.

    uint256 _salt = 1;
    bytes32 hash = keccak256(
        abi.encodePacked(
            bytes1(0xff),
            address(this),
            _salt,
            keccak256(type(TokenTemplate).creationCode)
        )
    );
Enter fullscreen mode Exit fullscreen mode

Use deploy to get the deployed address.

    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;
    }
Enter fullscreen mode Exit fullscreen mode

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

Top comments (0)