Solidity 0.8.27 发布公告

  • Solidity
  • 更新于 2024-10-10 10:36
  • 阅读 599

为遗留处理流程带来了对 require 中自定义错误的支持,优化器改进,例如优化 IR 的缓存,这将通过 IR 加速编译,多个 bug 修复,以及更多功能!

我们很高兴地宣布发布 Solidity 编译器 v0.8.27

此版本的编译器为遗留处理流程带来了对 require 中自定义错误的支持,优化器改进,例如优化 IR 的缓存,这将通过 IR 加速编译,多个 bug 修复,以及更多功能!

突出特性

require 的自定义错误的遗留支持

Solidity 中的自定义错误为用户解释操作失败的原因提供了一种方便且节省 gas 的方式。支持在 require 函数中使用错误是一个备受期待的功能,并在编译器的上一个版本中最终实现。该版本引入了一个新的重载 — require(bool, <error>),它会以错误的签名进行回退,而不是其他变体使用的 Error(string)

然而,使用自定义错误与 require 仅在 IR 处理流程中得到支持,即通过 Yul 编译。随着 0.8.27 的发布,你也可以在遗留处理流程中使用此功能。

要了解有关该功能及其使用方法的更多信息,请查看 我们之前的发布公告 中的示例。

优化 IR 的缓存

在调查 IR 处理流程的性能瓶颈时,我们意识到设计的一个方面对实际项目的性能影响远比我们在引入处理流程时设想的要大。

作为背景,当合约使用需要在编译时了解另一个合约字节码的特性时,访问的字节码必须作为依赖嵌入到访问合约中。例如,当合约需要使用 new 部署或访问其 .runtimeCode.creationCode 时,就会发生这种情况。

在 IR 处理流程中,这种嵌入发生得非常早,已经在 Yul 代码生成期间。被访问合约的源代码作为 Yul 子对象包含,这意味着可以使用语言原语简单地访问其字节码。这确保了代码生成器的输出是自包含的,并使处理流程非常简单。没有必须链接的外部工件,并且关于源的所有信息在每个阶段都可以知道。

然而,这种设计的缺点是,每次包含依赖项时,整个处理流程必须再次运行该依赖项。特别是,整个优化过程会重复,即使合约已经在隔离中进行了优化。

新功能通过在 Yul 对象级别引入缓存来保持 IR 处理流程的简单性。由于每个 Yul 对象都是独立优化的,因此在编译字节码依赖项时可以重用结果。下面是我们在一些流行项目上的基准测试:

项目 0.8.26 0.8.27 加速
openzeppelin 37 s 37 s 0%
uniswap-v4 225 s 147 s 42%
eigenlayer 1211 s 674 s 44%

请注意,一些项目未受影响,而其他项目的差异则相当显著。我们观察到,在每种情况下,实际部署的生产代码实际上具有非常少的字节码依赖,并且编译相对较快,这证实了我们的初步假设。然而,在某些项目中,测试套件大量使用 new,导致大型测试合约多次经历相同的优化。在这种用例中,new 的成本是无关紧要的,而使用它使得可以保持整个测试用 Solidity 编写,因此在 Foundry 等框架中已成为一种常见模式。得益于缓存,编译器现在可以高效地处理这种模式。

附加说明

瞬态存储

此版本引入了对瞬态存储变量的解析器支持。澄清一下,整个功能尚未完成。

编译器现在将接受将某些变量标记为 transient 的语法,并允许用户生成瞬态存储布局。然而,仍然无法为使用此类变量的合约生成字节码。

我们计划在接下来的几个版本中逐步引入对瞬态存储的高级语言支持。特别是,下一个版本将提供对值类型的瞬态状态变量的完全支持。支持将从那里扩展,以涵盖更复杂的用例。

--strict-assembly--yul

此版本删除了已弃用的类型化 Yul 方言,该方言仅可通过 CLI 中的 --yul 选项访问。用户不应将此误认为是对 Yul 支持的弃用。

请注意,此更改不会以任何方式影响 Yul 编译。始终用于选择 Yul 唯一常用方言的是 --strict-assembly 选项,而不是 --yul。后者仅用于现在已弃用的实验性类型化方言。

完整变更日志

语言特性

  • 接受带有 transient 数据位置的状态变量声明(仅解析器支持,尚无代码生成)。
  • 在使用遗留处理流程时,使 require(bool, Error) 可用。
  • Yul:源位置注释的解析规则已放宽:位置组件之间的空格以及单引号代码片段现在被允许。

编译器特性

  • 命令行接口:添加 --transient-storage-layout 输出。
  • 命令行接口:允许在汇编器模式下使用 --asm-json 输出选项以 JSON 格式导出合约的 EVM 汇编。
  • 命令行接口:仅在请求未优化的 IR 时不执行 IR 优化。
  • 常量优化器:如果所选 EVM 版本支持,则使用 PUSH0
  • 错误报告:未实现的功能现在被正确报告为错误,而不是被处理为 bug。
  • EVM:支持 EVM 版本 "Prague"。
  • 观察优化器:当支持时,PUSH0 被显式复制,而不是使用 DUP1
  • 观察优化器:删除相同的代码片段,如果它们一个接一个地出现,则终止控制流。
  • SMTChecker:为一元减法操作添加 CHC 引擎检查以检测下溢和上溢。
  • SMTChecker:用 cvc5 替换 CVC4 作为可能的 BMC 后端。
  • 标准 JSON 接口:添加 transientStorageLayout 输出。
  • 标准 JSON 接口:仅在请求未优化的 IR 时不执行 IR 优化。
  • Yul:删除仅可通过 CLI 中的 --yul 访问的已弃用的类型化 Yul 方言。
  • Yul:未类型化 Yul 方言中类型的存在现在是解析器错误。
  • Yul 优化器:缓存优化的 IR 以加速具有字节码依赖的合约的优化。
  • Yul 优化器:优化器现在将一些以前未识别的相同字面量视为相同。

Bug 修复

  • 汇编器:修复由于字节码中标签所需大小的不精确计算而导致的 ICE,当代码大小超过 255 时。
  • 解析器:修复在某些情况下将一元加法操作用作二元操作时错误地发出的解析器错误。
  • SMTChecker:修复报告 BMC 和 CHC 引擎验证检查的无效数量的错误。
  • SMTChecker:修复不变量中一元减法表达式的格式。
  • SMTChecker:修复在报告 BMC 引擎的证明目标时的内部编译器错误。
  • SMTChecker:修复在分配给合约或函数数组时的 SMT 逻辑错误。
  • 标准 JSON 接口:对于 Yul 输入,在出现警告的情况下正确生成输出构建产物。
  • 类型检查器:修复在将嵌套元组分配给元组时的段错误。
  • Yul IR 代码生成:Yul 子对象的确定性顺序。
  • Yul 优化器:修复 Yul 源位置始终引用未优化源,即使在优化输出中。
  • Yul 优化器:修复在没有错误时生成警告两次的问题。
  • Yul 优化器:名称简化可能导致以点开头和/或结尾的禁止标识符,例如,x._ 将被简化为 x.
  • Yul 解析器:修复解析非常长的位置注释时的段错误。

构建系统

  • 更改构建系统以使用 git 子模块来处理某些依赖项(nlohmann-json、fmtlib 和 range-v3)。

如何安装/升级?

要升级到最新版本的 Solidity 编译器,请按照我们文档中提供的安装说明 。你可以在此处下载 Solidity 的新版本:v0.8.27

如果你想从源代码构建,请不要使用 GitHub 自动生成的源代码档案。

最后但同样重要的是,我们要感谢所有帮助使此次发布成为可能的贡献者!

我是 AI 翻译官,为大家转译优秀英文文章,如有翻译不通的地方,在这里修改,还请包涵~

点赞 1
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
Solidity
Solidity
江湖只有他的大名,没有他的介绍。