solidity使用create2预测合约地址|create2用法|智能合约create2

此篇文章教你如何在部署合约前就可以确定合约地址

一、合约源码

让我们创建一个工厂合约,它包含两个合约。

  • 第一个是Demo合约,其中一个函数可以读取全县所有者的钱包地址。
  • 第二个合约是工厂合约,它可以在部署Demo合约前获取其合约地址。

这个合约将使用Solidity文档中所说的CREATE2操作码:加“盐”的合约创建 / create2。

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract ContractDemo {
    address public owner;
    // Only owners can call transactions marked with this modifier
    modifier onlyOwner() {
        require(owner == msg.sender, "Caller is not the owner");
        _;
    }
    constructor(address _owner) payable {
        owner = _owner;
    }

    function getOwner() public view returns (address) {
        return owner;
    }
    
}
contract Factory {
    // Returns the address of the newly deployed contract
    function deploy(
        uint _salt
    ) public payable returns (address) {
        return address(new ContractDemo{salt: bytes32(_salt)}(msg.sender));
    }

    //  获取待部署合约字节码
    function getBytecode()
        public
        view
        returns (bytes memory)
    {
        bytes memory bytecode = type(ContractDemo).creationCode;
        return abi.encodePacked(bytecode, abi.encode(msg.sender));
    }
    /** 获取待部署合约地址
        params:
            _salt: 随机整数,用于预计算地址
    */ 
    function getAddress(uint256 _salt)
        public
        view
        returns (address)
    {
        // Get a hash concatenating args passed to encodePacked
        bytes32 hash = keccak256(
            abi.encodePacked(
                bytes1(0xff), // 0
                address(this), // address of factory contract
                _salt, // a random salt
                keccak256(getBytecode()) // the wallet contract bytecode
            )
        );
        // Cast last 20 bytes of hash to address
        return address(uint160(uint256(hash)));
    }
}

二、合约部署

在Remix中选择部署选项,并将要部署的合约切换到 Factory,点击部署:

部署被确认后,选择已部署的合约,我们就可以利用Factory合约获取Demo合约的合约地址了。
getAddress函数返回一个新的Demo实例的预计算的地址。传递一个salt参数,就可返回这个地址。为了简单,我们将使用111作为盐,但它可以是任何uint256值。
让我们把111作为参数传给getAddress函数,并在Remix中执行:
在这里插入图片描述
在这个特殊的例子中,预先计算的地址是0x9aBE429F1484622d7511aA9bc2C361EE6967b20b

接下来我们部署 Demo 合约,检查它是否正确部署到之前预先计算的地址上。在Remix中,在Factory合约实例中找到Deploy函数,并传递111作为盐。等待交易,并前往区块链浏览器确认它是否正确部署:

在交易细节部分(在区块链浏览器上)选择Internal Txns标签:
在这里插入图片描述
在页面上,我们看到CREATE2函数被我们的工厂合约调用,一个新的Demo合约被创建。点击创建的合约的地址,可以看到与之前预先计算的相同。

笔者整理了常见的一些智能合约并进行分类,如有需要请自取。
点击跳转

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zgsdzczh

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值