DEV Community

Cover image for Tutorial - Using create2 to predict the contract address before deploying
Yongchang He
Yongchang He

Posted on

Tutorial - Using create2 to predict the contract address before deploying

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

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

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

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

getAddress

Image description

deploy with the same salt value

Image description

check logs

logs    [
    {
        "from": "0xDA0bab807633f07f013f94DD0E6A4F96F8742B53",
        "topic": "0x55ea6c6b31543d8e2ec6a72f71a79c0f4b72ed0d4757172b043d8f4f4cd84848",
        "event": "Deploy",
        "args": {
            "0": "0x0B4f6a49C6a97B5dBB62F8A594cDefe5EabB4658",
            "addr": "0x0B4f6a49C6a97B5dBB62F8A594cDefe5EabB4658"
        }
    }
Enter fullscreen mode Exit fullscreen mode

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!

GitHub logo hyc0812 / solidity-essentials

Solidity programming baby examples...

Solidity-Baby Steps...

The best path for earning Solidity is to approach examples.

Here are baby examples. Typing one-by-one is recommended.

References:

MyBlog explanation for using EnglishAuction and testing.

examples

videoResource

Example-1

updateBalance & getBalance

// SPDX-License-Identifier: GPL-3.0

pragma solidity >=0.7.0 <0.9.0;

contract MyLedger {
    mapping(address => uint) public balances;
    function updateBalance(uint newBal) public {
        balances[msg.sender] = newBal;
    }
    function getBalance() public view returns(uint) {
        return balances[msg.sender];
    }
}
Enter fullscreen mode Exit fullscreen mode

Example-2

Inherited from Square

// SPDX-License-Identifier: GPL-3.0
pragma solidity >=0.7.0 <0.9.0;

import "@openzeppelin/contracts/utils/Strings.sol";

contract Shape {
    uint height;
    uint width;

    constructor(uint _height, uint _width) {
        height = _height;
        width = _width;
    }
}

contract Square is Shape {
    constructor(uint h, uint w) Shape(h, w) {}

    function getHeight() 
Enter fullscreen mode Exit fullscreen mode

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/

Top comments (0)