• 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)));
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    二、合约部署

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

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

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

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

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

  • 相关阅读:
    利用C++开发一个迷你的英文单词录入和测试小程序-源码
    这是什么代码帮我看看
    重读Java设计模式: 适配器模式解析
    【JS】JavaScript入门笔记第五弹之预解析、对象~
    免费GPU:九天•毕昇平台使用教程
    阅读JavaScript文档-闭包
    Java23种设计模式-创建型模式之工厂方法模式
    面试突击81:什么是跨域问题?如何解决?
    【Java】常用类和基础API
    C++ Reference: Standard C++ Library reference: Containers: array: array: fill
  • 原文地址:https://blog.csdn.net/zgsdzczh/article/details/126408014