Solidity——create和create2部署合约

这篇具有很好参考价值的文章主要介绍了Solidity——create和create2部署合约。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

部署智能合约是开发中必不可少的一个环节,常规的方式是借助像Hardhat这样的工具,通过编写ts部署脚本来实现。但在实际业务中,经常会遇到通过在合约中部署子合约的情况。比如添加Token流动池。这类需求在设计在上需要通过工厂合约来创建部署子合约来实现,它看起来就像是从一个模具厂生产的模具一样,只是每个模具的编号(子合约地址)不同。子合约的业务逻辑不是本次介绍的重点,我们主要关注在合约中部署合约的两种方式:

一、create部署

先确认子合约的内容,一个构造函数和简单的函数:

contract Son {
    
    address token1;
    address token2;

    constructor(address _token1,address _token2) {
        token1 = _token1;
        token2 = _token2;
    }

    function addLiquidity() external pure returns(uint256){
        return 1;
    }
}

create的部署方式是通过new关键字来实现,所部署合约的地址是通过哈希计算得来: 

  1. 部署地址 —msg.sender
  2. 之前在该地址部署的交易数  — nonce

keccak256(rlp.encode(deployingAddress, nonce))

nonce每次获取的不一样,因此每次部署的合约地址不同。在solidity最新的版本中,只需通过内置的关键字new即可:

X x = new X()

//新版本的create部署方式
    //0x4D1435CA4761C96ea6156AFf63A9F0D8D00D10c1
    //0xFF8C88bA69cbfba47BfC1ff84aB2cfA6a64B8429
    function create(address token1,address token2) external returns(address){
        Son son = new Son(token1,token2);
        return address(son);
    }

remix运行结果:

Solidity——create和create2部署合约,Solidity基础,区块链,web3.0

合约地址:0x5C9eb5D6a6C2c1B3EFc52255C0b356f116f6f66D,我们用相同的参数token1、token2,再次部署的结果: 

Solidity——create和create2部署合约,Solidity基础,区块链,web3.0

合约地址: 0xb8f43EC36718ecCb339B75B727736ba14F174d77,可以看到与第一次的地址不同,create部署的好处是每次的部署地址不同,不用担心合约地址被占用导致部署失败的问题,缺点是无法通过计算得到合约地址,不适合一些需要提前知道合约地址的场景。

二、create2部署

合约地址计算的方式:

  1. 部署地址(msg.sender)
  2. 部署合约代码字节码的哈希(bytecode)
  3. 创建者提供的随机的salt (32 字节字符串).

keccak256(0xff ++ deployingAddr ++ salt ++ keccak256(bytecode))

相较于create,多了参数salt。

//新版本的create2部署方式
    function create2(address token1,address token2) external returns(address){
        bytes32 salt = keccak256(abi.encodePacked(token1, token2));//盐值,可以是一个数字、一个字符串等,一般是随机数
        Son son = new Son{salt: salt}(token1,token2);
        return address(son);
    }

salt的获取规则是计算token1和token2的hash,也可以根据实际的业务进行调整。部署代码:

X x = new X{salt: salt}()

token1和token2仍然使用create中的参数值,remix运行结果: 

Solidity——create和create2部署合约,Solidity基础,区块链,web3.0

合约地址为:0x8D0Cd60156182DF2263a41960c250Bd921047Bc3 ,与create部署的合约地址不同,因为底层的计算方式不同。现在我们用相同的参数再次部署:

Solidity——create和create2部署合约,Solidity基础,区块链,web3.0

已经报错,因为相同的salt计算的合约地址是相同的,而合约地址必须未被使用过。

我们用旧版本的create2来试试看

//老版本的create2部署方式,通过solidity汇编语法实现
    function deployAssembly(address token1,address token2) external returns(address addr){
        bytes memory bytecode = getBytecode(token1, token2);
        bytes32 salt = keccak256(abi.encodePacked(token1, token2));//盐值,可以是一个数字、一个字符串等,一般是随机数

        assembly {
            //param1:发送给新合约的wei数(msg.value)
            //param2:存储位置(从32开始)和需要的长度(bytecode)
            //param3:存储在memory中
            //param4:随机值
            addr := create2(0,add(bytecode, 32),mload(bytecode),salt)

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


    function getBytecode(address token1,address token2) internal pure returns(bytes memory bytecode){
        bytecode = type(Son).creationCode;//获取合约字节码,也可通过编译合约获取
        bytecode = abi.encodePacked(bytecode, abi.encode(token1, token2));
    }

需要提前通过creationCode()函数获取部署子合约的bytecode。部署结果:

Solidity——create和create2部署合约,Solidity基础,区块链,web3.0

可以看到结果仍然是失败,因为与上述计算的合约地址相同,只是实现方式不同。我们通过计算合约地址的函数来验证是否与部署成功的地址一致:

Solidity——create和create2部署合约,Solidity基础,区块链,web3.0

可以看到计算结果是:0x8D0Cd60156182DF2263a41960c250Bd921047Bc3,与create2函数返回的合约地址相同。

相较于create,create2提供了更多的灵活性,使得开发者可以预先计算合约地址,从而更好地管理合约地址的分配。同时,create2还可以用于实现一些更高级的功能,例如合约工厂、二级合约等。

需要注意的是,使用create2创建合约时,由于需要提供一个预计地址,因此需要确保该地址没有被使用过,否则可能会导致创建失败。此外,使用create2创建合约时,需要确保预计地址的计算规则是确定的,这样可以确保预计地址与实际地址的一致性。文章来源地址https://www.toymoban.com/news/detail-842143.html

到了这里,关于Solidity——create和create2部署合约的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • solidity进阶第五课——Create2

    Create2操作码使我们在智能合约部署在以太坊网络之前就能预测合约的地址。Uniswap创建Pair合约用的就是Create2而不是Create。 Create是如何计算地址 智能合约可以由其他合约和普通账户利用Create操作码创建。 在这两种情况下,新合约的地址都以相同的方式计算:创建者的地址(通

    2023年04月08日
    浏览(28)
  • 使用Ganache,web3js和remix在个人区块链上部署并调用合约

    Ganache是一个运行在本地的个人区块链,适用于以太坊的开发者。 首先我们需要下载Ganache web3js的中文文档 remix英文版的网址 有以上的准备之后我们就可以开始了 首先启动Ganache 这就是Ganache的主页面,下面有10个供我们使用的账号,上面有他们的地址以及余额,我们暂时需要

    2024年01月19日
    浏览(74)
  • 欢迎来到Web3.0的世界:Solidity智能合约安全漏洞分析

    智能合约是运行在区块链网络中的一段程序,经由多方机构自动执行预先设定的逻辑,程序执行后,网络上的最终状态将不可改变。智能合约本质上是传统合约的数字版本,由去中心化的计算机网络执行,而不是由政府或银行等中央集权机构执行。智能合约程序可以用Solidi

    2024年02月03日
    浏览(44)
  • 区块链合约交互 web3

    遵循ERC20规则, 钱包里可以有很多种类型的token:USDT,DFI,DFA 1.合约交互之前需要先判断是否仍允许purchasePool合约从账户(钱包里的账户) 中提取的ERC20dfaContract 这本合约里(DFA)的金额 await this.contract.ERC20dfaContract.methods.allowance(this.address,this.addressMap.AcceleratePool).call(); ERC20df

    2024年02月07日
    浏览(62)
  • 区块链-java对接web3合约

    本文章讲述了如何在合约已经部署并且能拿到合约abi文件的情况下,用java代码去进行调用合约 已经部署好的合约地址 编译合约后生成的abi文件  通过hardhat-build去编译 通过remix网站去编译获取(教程可自行百度查询) 引入web3的jar包 版本用最新的就行了 引入web3j-maven-plugin 将编

    2024年01月16日
    浏览(65)
  • 【区块链 | Solidity】Solidity开发教程:用Web3.js构建第一个Dapp

    Web3.js 使用的实用介绍 原文 作者:wissal haji 欢迎订阅《Solidity智能合约零基础开发教程专栏》系列文章。 如果你一直在跟着这个系列学习,那么你已经掌握了编写自己的智能合约。 因此,今天给大家介绍一下构建去中心化应用的全貌,并向大家介绍一下web3.js,这是构建da

    2024年01月24日
    浏览(50)
  • 【区块链学习最全教程】学习 Solidity,全栈 Web3,Javascript 和区块链开发

    Chainlink 开发者社区发布了一个关于全栈 web3,solidity 和区块链开发的完整视频教程。本视频教程由 Chainlink 开发者大使 Patrick Collins 讲解。教程由浅入深讲解了区块链的基础知识,智能合约基础以及流行的开发工具。视频内容覆盖广泛,不论是初学者还是资深工程师,都会从中

    2023年04月09日
    浏览(54)
  • 某60区块链安全之Create2实战一学习记录

    学会使用python3的web3模块 学会分析以太坊智能合约Create2引发的漏洞及其利用 找到合约漏洞进行分析并形成利用 Ubuntu18.04操作机 python3 君士坦丁堡硬升级中引入了一个新操作码 CREATE2 ,它使用新的方式来计算常见的合约地址,让生成的合约地址更具有可控性 在 CREATE2 以前,

    2024年02月05日
    浏览(38)
  • 某60区块链安全之Create2实战二学习记录

    学会使用python3的web3模块 学会分析以太坊智能合约中的伪随机数问题 学会利用Create2可在同一地址部署不同合约特性解决伪随机数问题 找到合约漏洞进行分析并形成利用 Ubuntu18.04操作机 python3 君士坦丁堡硬升级中引入了一个新操作码 CREATE2 ,它使用新的方式来计算常见的合约

    2024年02月03日
    浏览(40)
  • Web3 solidity编写交易所合约 编写ETH和自定义代币存入逻辑 并带着大家手动测试

    上文 Web3 叙述交易所授权置换概念 编写transferFrom与approve函数我们写完一个简单授权交易所的逻辑 但是并没有测试 其实也不是我不想 主要是 交易所也没实例化 现在也测试不了 我们先运行 ganache 启动一个虚拟的区块链环境 先发布 在终端执行 如果你跟着我一步一步来的 那编

    2024年02月13日
    浏览(39)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包