当前位置: 首页 > news >正文

Q3: create 和 create2 有什么区别?

在这里插入图片描述

欢迎来到《Solidity面试修炼之道》专栏💎。

专栏核心理念:

核心 Slogan💸💸:从面试题到实战精通,你的 Web3 开发进阶指南。

一句话介绍🔬🔬: 150+ 道面试题 × 103 篇深度解析 = 你的 Solidity 修炼秘籍。

  1. ✅ 名称有深度和系统性
  2. ✅ "修炼"体现进阶过程
  3. ✅ 适合中文技术社区
  4. ✅ 记忆度高,易于传播
  5. ✅ 全场景适用

Q3: create 和 create2 有什么区别?

简答:
create 使用部署者地址和 nonce 计算新合约地址,地址不可预测;create2 使用部署者地址、salt 和合约字节码哈希计算地址,地址可预测且与 nonce 无关。

详细分析:
create 是传统的合约部署方式,新合约的地址由部署者地址和该地址的 nonce(交易计数)决定。公式为:address = keccak256(rlp([sender, nonce]))[12:]。这意味着每次部署时,即使是相同的合约代码,地址也会不同,因为 nonce 会递增。

create2 在 EIP-1014 中引入,允许在部署前预测合约地址。地址计算公式为:address = keccak256(0xff ++ sender ++ salt ++ keccak256(bytecode))[12:]。这里的 salt 是一个 32 字节的值,由部署者选择。只要 sender、salt 和 bytecode 相同,生成的地址就相同,与 nonce 无关。

create2 的主要优势:

  1. 地址可预测性:可以在部署前知道合约地址,用户可以向尚未部署的合约发送资金
  2. 状态通道:可以在链下计算合约地址,只在需要时部署
  3. 工厂模式:可以确保相同的合约代码总是部署到相同的地址(在不同链上)
  4. 合约升级:可以通过 selfdestruct 和重新部署实现合约"升级"(虽然不推荐)

代码示例:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;/*** @title CreateExample* @notice 演示 create 和 create2 的区别*/// 要部署的简单合约
contract SimpleContract {uint256 public value;constructor(uint256 _value) {value = _value;}
}contract CreateExample {event ContractCreated(address contractAddress, string method);/*** @notice 使用 create 部署合约* @dev 地址由 sender 和 nonce 决定,不可预测*/function deployWithCreate(uint256 _value) public returns (address) {SimpleContract newContract = new SimpleContract(_value);address contractAddress = address(newContract);emit ContractCreated(contractAddress, "create");return contractAddress;}/*** @notice 使用 create2 部署合约* @dev 地址由 sender、salt 和 bytecode 决定,可预测*/function deployWithCreate2(uint256 _value, bytes32 _salt) public returns (address) {SimpleContract newContract = new SimpleContract{salt: _salt}(_value);address contractAddress = address(newContract);emit ContractCreated(contractAddress, "create2");return contractAddress;}/*** @notice 预测 create2 部署的合约地址* @dev 在实际部署前计算地址*/function predictCreate2Address(bytes32 _salt,uint256 _value) public view returns (address) {// 获取合约创建字节码bytes memory bytecode = abi.encodePacked(type(SimpleContract).creationCode,abi.encode(_value));// 计算字节码哈希bytes32 hash = keccak256(abi.encodePacked(bytes1(0xff),address(this),_salt,keccak256(bytecode)));// 返回地址(取哈希的后 20 字节)return address(uint160(uint256(hash)));}/*** @notice 演示 create 地址的不可预测性*/function demonstrateCreateUnpredictability(uint256 _value) public returns (address, address) {// 连续部署两次相同的合约address addr1 = address(new SimpleContract(_value));address addr2 = address(new SimpleContract(_value));// 地址不同,因为 nonce 递增了assert(addr1 != addr2);return (addr1, addr2);}/*** @notice 演示 create2 地址的可预测性*/function demonstrateCreate2Predictability(uint256 _value,bytes32 _salt) public returns (address, address) {// 预测地址address predictedAddr = predictCreate2Address(_salt, _value);// 实际部署address actualAddr = address(new SimpleContract{salt: _salt}(_value));// 地址相同assert(predictedAddr == actualAddr);return (predictedAddr, actualAddr);}
}/*** @title Create2Factory* @notice 使用 create2 的工厂合约示例*/
contract Create2Factory {mapping(bytes32 => address) public deployedContracts;/*** @notice 部署合约,如果已存在则返回现有地址*/function deploy(uint256 _value, bytes32 _salt) public returns (address) {// 检查是否已部署address predicted = predictAddress(_salt, _value);if (deployedContracts[_salt] != address(0)) {require(deployedContracts[_salt] == predicted, "Salt collision");return deployedContracts[_salt];}// 部署新合约SimpleContract newContract = new SimpleContract{salt: _salt}(_value);address contractAddress = address(newContract);deployedContracts[_salt] = contractAddress;return contractAddress;}function predictAddress(bytes32 _salt, uint256 _value) public view returns (address) {bytes memory bytecode = abi.encodePacked(type(SimpleContract).creationCode,abi.encode(_value));bytes32 hash = keccak256(abi.encodePacked(bytes1(0xff), address(this), _salt, keccak256(bytecode)));return address(uint160(uint256(hash)));}
}

理论补充:
create2 的引入为以太坊带来了新的可能性,特别是在状态通道和 Layer 2 解决方案中。例如,两个用户可以在链下协商一个合约的参数和 salt,然后在链下进行交互,只在发生争议时才将合约部署到链上。由于地址是可预测的,双方可以安全地向该地址发送资金,即使合约尚未部署。

create2 的安全考虑:

  1. 重新部署风险:如果合约使用 selfdestruct 自毁,可以使用相同的 salt 重新部署不同的代码(在 Cancun 升级后,selfdestruct 行为已改变)
  2. salt 冲突:如果 salt 已被使用,部署会失败
  3. 字节码依赖:地址依赖于完整的字节码,包括构造函数参数

在实际应用中,create2 常用于:

  • Uniswap V2 的配对合约部署
  • 最小代理(Minimal Proxy/EIP-1167)工厂
  • 跨链合约部署(在多个链上部署到相同地址)
  • 状态通道和 Plasma 实现

相关问题:

  • Q2: 智能合约大约可以有多大?
  • Q49: 以太坊地址是如何派生的?
http://www.dtcms.com/a/602816.html

相关文章:

  • 研发管理知识库(6)什么是CI/CD
  • 数据库知识整理——SQL数据更新
  • win7 iis架设网站思途旅游网站建设系统
  • 反编译易语言 | 探讨易语言的反编译方法与安全性分析
  • 无锡网站营销公司简介郑州加盟网站建设
  • 单位网站建设费用什么会计科目广告优化是做什么的
  • 自动化测试工具Katalon 全面介绍与实际体验
  • 游戏盾的流量清洗
  • 楚雄做网站敬请期待上一句
  • 山东鲁中公路建设有限公司网站站点传统的推广方式主要有
  • 电子商务网站建设读书笔记秒收网站
  • 互联网网站 数据库网站优化建设宁夏
  • 网站扫码怎么做的团智慧团建登录入口
  • 哪个网站可以做免费商业推广建设个人网站的要求
  • 4.1.0 EL9410 用于 E-bus 的电源端子模块介绍
  • 网站开发脚本语言农产品网站的品牌建设
  • 从0到1学习Qt -- 常见控件QWidget(二)
  • 网站建设程序文件一台云服务器可以做多个网站
  • Oracle:查询当前正在等待执行的SQL语句
  • 交通信息华建设网站鱼爪网商城网站如何建设
  • 炫酷做网站背景图环保网站建设的目的
  • iOS的runtime的理解以及常用的使用场景有哪些
  • 摘要生成器(Gradio界面)
  • tldraw——一款开源、自托管、支持实时协作的 Web 白板
  • 厚街网站建设报价软文推广平台排名
  • 在.NET中使用RAG检索增强AI基于Qdrant的矢量化数据库
  • 【STM32MP157 异核通信框架学习篇】(1)SMP和AMP架构
  • 【OpenCV + VS】从纯色的背景中扣出前景然后对背景颜色进行转换
  • 网站线上推广方案wordpress大学主题安装
  • C语言编译软件的获取 | 如何选择适合的C语言编译器并安装使用