编译:登链翻译方案;来源:soliditylang.org

Solidity编译器的最新版别v0.8.22的发布。0.8.22版别的编译器包含了一系列的言语和编译器改善,例如文件级事情界说、unchecked 循环增量优化、支撑导入EVM汇编JSON 等等。

重要提示

本次发布抛弃了对低于 Constantinople(君士坦丁堡) 版别的 EVM 的支撑,这些版别越来越难以保护。这些陈旧的版别在以太坊主网和测验网络上早已过时,咱们怀疑它们对其他网络也不再相关。杂乱的代码路径和解决方案会减慢针对新版别的功用开发和测验的速度,因而咱们希望在未来的编译器版别中停止支撑它们。

新功用亮点

unchecked 循环增量

在增加循环计数器时运用 unchecked 算术运算是为了 gas 优化[7]的常见做法。让咱们以以下循环和计数器 i 的示例来阐明:

for (uint i = 0; i < array.length; ++i) {
   acc += array[i]; // i is not modified by the loop body
}

在许多情况下(详见下文的准确条件),比较操作将保证 i 永久不会到达其类型的最大值,因而能够安全地假设在到达最大值之前循环将停止。在这种情况下,对计数器进行安全查看将是多余的,也是一种 gas 的浪费。这就会鼓励用户运用冗长的 unchecked 形式,将计数器增量包装在循环体内的unchecked算术块中,绕过查看:

for (uint i = 0; i < array.length;) {
   acc += array[i];
   unchecked { i++; } // i gets incremented without overflow checks -- less gas used
}

Solidity 0.8.22 引进了一种溢出查看优化,自动生成了关于循环计数器的 unchecked 算术增量。这个新的优化消除了在循环体中运用相似前面示例中的冗长 unchecked 增量形式的需要。

相比之下,新的优化运用户能够在不献身gas效率的情况下返回到原始的、更易读的代码。

新优化避免溢出查看的准确条件如下:

  • 循环条件是形如 i < ... 的比较,其间 i 是一个局部变量(从现在开始称为“循环计数器”)。

  • 此比较有必要在与循环计数器相同的类型上履行,即右侧的类型有必要能够隐式转换为循环计数器的类型,以使循环计数器在比较之前不会被隐式扩展。

  • 循环计数器有必要是内置整数类型的局部变量。

  • 循环表达式有必要是循环计数器的前缀或后缀递加,即 i++ 或 ++i。

  • 循环计数器不能在循环条件或循环体中被修正。

为了澄清第二个条件,考虑以下代码片段:

for (uint8 i = 0; i < uint16(1000); ++i) {
   // loop body
}

在这种情况下, i 在比较之前被转换为 uint16,并且条件实际上永久不会为假,因而无法删去递加的溢出查看。

别的,请注意, < 是唯一会触发该优化的比较运算符。故意排除了运算符 <= 和其他运算符。此外,该运算符有必要是内置的 - 用户界说的 < 不符合条件。

该优化是直接的且总是有利的,因而即便运用通用设置 settings.optimizer.enabled 禁用了优化器的其余部分,它也会被启用。能够经过在标准 JSON 输入中将 settings.optimizer.details.simpleCounterForLoopUncheckedIncrement 设置为 false 来明确关闭它。无法运用命令行界面禁用它。

调整Yul优化器以从头生成零字面量

新版别在 0.8.20 版别引进的 PUSH0 操作码的支撑基础上进行了构建,经过将 Rematerialiser[8] 优化步骤扩展为始终从头生成零字面量而不是将其存储为变量引证,从而答应运用 PUSH0 而不是 DUP 来下降gas本钱。为保证有效履行此操作,将 Rematerialiser 和 UnusedPruner[9] 步骤增加到了Yul优化器的默认清理序列中。

增加对导入 EVM 汇编 JSON 的支撑(实验性)

这个新版别增加了对导入 EVM 汇编的实验性支撑,为外部东西在字节码生成之前履行超级优化供给了可能性。此功用的首要意图是界说一种初级 EVM 汇编的序列化格局,使编译器生成的汇编能够被导出、修正和从头导入,从而康复正常的编译进程。

重要提示:这是一个实验性功用,目前不适用于生产环境。咱们在此版别中供给此功用,以便你测验并供给反馈。

答应在文件等级界说事情

Solidity 0.8.22 答应你在文件等级界说事情。现在,事情界说能够放在合约规模之外。这为代码组织供给了另一种选择,无需人为地将事情包装在库中。

此外,此版别还修正了一个过错,该过错导致在为代码发出在外部合约或接口中界说的事情时生成 NatSpec 时出错。在上一个版别(0.8.21)中,Solidity编译器增加了对在当前合约未继承的合约和接口中界说的事情的限制拜访的支撑,但该过错阻挠了该功用的彻底运用。

经过此过错修正和答应文件等级事情界说,Solidity的最新版别运用户能够编译以下示例而不会呈现任何过错:

interface I {
   event ForeignEvent();
}
contract C {
   event ForeignEvent();
}
event E();
contract D {
   function f() public {
       // Emitting a foreign event would trigger an internal error on 0.8.21
       emit I.ForeignEvent();
       emit C.ForeignEvent();
       // Emitting a file-level event. New feature.
       emit E();
   }
}

完好的更改日志

言语特性

  • 答应在文件等级界说事情。

编译器特性

  • 代码生成器:当计数变量不会溢出时,删去某些for循环的冗余溢出查看。

  • 命令行界面:增加--no-import-callback选项,防止编译器加载未在 CLI 或标准 JSON 输入中明确给出的源文件。

  • 命令行界面:增加实验性的--import-asm-json选项,能够导入以--asm-json运用的格局的 EVM 汇编。

  • 命令行界面:关于在编译 pipeline 之外发生的过错消息,运用恰当的严重性和着色。

  • EVM:弃用对“homestead”、“tangerineWhistle”、“spuriousDragon”和“byzantium” EVM 版别的支撑。

  • 解析器(Parser):删去实验性的过错康复形式(--error-recovery / settings.parserErrorRecovery)。

  • SMTChecker:支撑用户界说的运算符。

  • Yul 优化器:假如支撑PUSH0,优先运用零字面量而不是将零值存储在变量中。

  • Yul 优化器:在默认的清理序列的结尾运转RematerializerUnusedPruner步骤。

Bug 修正

  • 代码生成器:修正经过 via-IR 代码生成器输出的成果依赖于导入回调中发现的文件的问题。在某些情况下,不同的 AST ID 分配会改变内部调度中函数的顺序,导致表面上不同但在语义上等效的字节码。

  • NatSpec:修正在请求合约的用户文档或开发文档时呈现内部过错的问题,该合约发出了在外部合约或接口中界说的事情。

  • SMTChecker:修正编码过错,导致循环在完成后打开。

  • SMTChecker:修正常量条件查看的不一致性,当 while 或 for 循环在条件查看之前打开时。

  • Yul 优化器:修正在 CSE 期间受编译器生成的Yul变量名影响替换决策的问题,在某些情况下导致不同(但等效)的字节码。

此时快讯

【金色晚报 | 10月29日晚间重要动态一览】12:00-21:00关键词:Uniswap基金会、Floki、Chiliz、经济日报
1.Linea主网桥接转入突破10万ETH
2.数据:过去5天比特币巨鲸已累积超3万枚BTC
3.Uniswap基金会在过去6天内总共转出980万UNI
4.Peter Schiff:SEC最终批准比特币现货ETF将结束涨势
5.Floki:超12%的FLOKI代币供应量将在可预见时间内退出流通
6.Chiliz推出Chiliz Chain生态系统,CHZ持有者通过质押可获得奖励
7.经济日报:持之以恒防范化解金融风险,打击虚拟货币交易炒作等工作取得重要阶段性成果

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注