Latest release of Solidity compiler Improvements and highlights of new features
New and Improved Solidity Compiler Highlights of Latest Updates and FeaturesCompiled: Denglian Translation Plan; Source: soliditylang.org
The latest version v0.8.22 of the Solidity compiler has been released. The compiler version 0.8.22 includes a series of language and compiler improvements, such as file-level event definitions, unchecked
loop increment optimization, support for importing EVM assembly JSON, and so on.
Important Note
This release deprecates support for EVM versions lower than Constantinople. These older versions have become increasingly difficult to maintain. They are already outdated on the Ethereum mainnet and test networks, and we suspect they are no longer relevant for other networks as well. Complex code paths and solutions slow down the development and testing of features for newer versions, so we hope to stop supporting them in future compiler versions.
New Feature Highlights
Unchecked Loop Increment
Using unchecked
arithmetic operations when incrementing loop counters is a common practice for gas optimization. Let’s illustrate this with an example of a loop and a counter variable i
:
- Exclusive Interview with He Yi Discussing the Development of Binance and Professional Women from a Female Founder’s Perspective
- Delphi Digital 13 charts that explain why cryptocurrency prices are currently struggling to make significant breakthroughs.
- Get Ready for a Crypto Showdown Gemini Battles for Control of $1.6 Billion Grayscale Shares in Epic Lawsuit
for (uint i = 0; i < array.length; ++i) { acc += array[i]; // i is not modified by the loop body}
In many cases (detailed conditions below), the comparison operation ensures that i
will never reach the maximum value of its type. Therefore, it is safe to assume that the loop will stop before reaching the maximum value. In this case, performing a safe check on the counter would be redundant and a waste of gas. This encourages users to use the lengthy unchecked
pattern, wrapping the counter increment in an unchecked
arithmetic block inside the loop body:
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 introduces an overflow check optimization that automatically generates the unchecked
arithmetic increment for loop counters. This new optimization eliminates the need for using the lengthy unchecked
increment pattern in the loop body like the previous example.
In contrast, the new optimization allows users to return to the original, more readable code without sacrificing gas efficiency.
The new optimization avoids overflow checks under the following precise conditions:
-
The loop condition is a comparison of the form
i < ...
, wherei
is a local variable (now referred to as “loop counter”). -
This comparison must be performed on the same type as the loop counter, i.e., the type on the right must be implicitly convertible to the type of the loop counter, so that the loop counter is not implicitly extended before the comparison.
-
The loop counter must be a local variable of a built-in integer type.
-
The loop expression must be the prefix or postfix increment of the loop counter, i.e., either
i++
or++i
. -
The loop counter must not be modified in the loop condition or loop body.
To clarify the second condition, consider the following code snippet:
for (uint8 i = 0; i < uint16(1000); ++i) { // loop body}
In this case, i is converted to uint16 before the comparison, and the condition will never be false, so the increment overflow check cannot be removed.
Also note that <
is the only comparison operator that triggers this optimization. Operators <=
and others are deliberately excluded. Additionally, the operator must be built-in – user-defined <
does not qualify.
This optimization is direct and always beneficial, so it is enabled even if the rest of the optimizer is disabled using the settings.optimizer.enabled
general setting. It can be explicitly disabled by setting settings.optimizer.details.simpleCounterForLoopUncheckedIncrement
to false
in the standard JSON input. It cannot be disabled via the command-line interface.
Adjust Yul optimizer to regenerate zero literals
This new version builds on the support of the PUSH0 opcode introduced in version 0.8.20, by extending the Rematerialiser[8] optimization step to always regenerate zero literals instead of storing them as variable references, enabling the use of PUSH0 instead of DUP to reduce gas costs. To ensure effective execution of this operation, the Rematerialiser and UnusedPruner[9] steps have been added to the default optimization sequence of the Yul optimizer.
Add support for importing EVM assembly JSON (experimental)
This new version adds experimental support for importing EVM assembly, providing possibilities for external tools to perform super-optimizations before bytecode generation. The primary purpose of this feature is to define a serialization format for low-level EVM assembly, allowing the generated assembly by the compiler to be exported, modified, and reimported, thus restoring normal compilation processes.
Important note: This is an experimental feature and is currently not suitable for production environments. We are providing this feature in this version for you to try out and provide feedback.
Allow event definitions at the file level
Solidity 0.8.22 allows you to define events at the file level. Now, event definitions can be placed outside the scope of a contract. This provides another option for code organization without the need to artificially wrap events in libraries.
In addition, this version also fixes an issue that caused NatSpec generation to fail when emitting events defined in external contracts or interfaces. In the previous version (0.8.21), the Solidity compiler added support for limited access to events defined in contracts and interfaces that are not inherited by the current contract, but this bug prevented the full use of that feature.
With this bug fix and the ability to define events at the file level, the latest version of Solidity allows users to compile the following example without any errors:
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(); }}
Complete Change Log
Language Features
-
Allow events to be defined at the file level.
Compiler Features
-
Code generator: Remove redundant overflow checks for certain
for
loops when the counter variable will not overflow. -
Command-line interface: Add
--no-import-callback
option to prevent the compiler from loading source files that are not explicitly given in the CLI or standard JSON input. -
Command-line interface: Add experimental
--import-asm-json
option to import EVM assembly in the format used with--asm-json
. -
Command-line interface: Use appropriate severity and coloring for error messages generated outside of the compilation pipeline.
-
EVM: Deprecate support for “homestead”, “tangerineWhistle”, “spuriousDragon”, and “byzantium” versions of the EVM.
-
Parser (LianGuairser): Remove experimental error recovery mode (
--error-recovery
/settings.parserErrorRecovery
). -
SMTChecker: Support user-defined operators.
-
Yul optimizer: Prioritize using zero literals instead of storing zero values in variables if support for
PUSH0
exists. -
Yul optimizer: Run
Rematerializer
andUnusedPruner
steps at the end of the default cleanup sequence.
Bug Fixes
-
Code generator: Fix an issue where the result of code generation via the via-IR code generator would depend on files discovered in the import callback. In some cases, different AST ID assignments would change the order of functions in the internal schedule, resulting in bytecodes that were seemingly different but semantically equivalent.
-
NatSpec: Fix an internal error when requesting docstrings or devdoc for a contract that emits events defined in external contracts or interfaces.
-
SMTChecker: Fix encoding error causing loops to be unrolled after completion.
-
SMTChecker: Fix inconsistency in constant condition check when while or for loops are unrolled before the condition check.
-
Yul optimizer: Fix an issue where decisions on variable replacement were influenced by Yul variable names generated by the compiler during CSE, resulting in bytecodes that were different but equivalent in some cases.
We will continue to update Blocking; if you have any questions or suggestions, please contact us!
Was this article helpful?
93 out of 132 found this helpful
Related articles
- Unlocking NNS Liquidity A Detailed Explanation of the First LSD Protocol on the IC Chain, StakedICP
- Marcus Sharp’s Review of GPT-5 Urgently in Need of a New Paradigm- OpenAI Has No Advantage
- BTC Soars What Factors Are Driving the Rise
- Trezor Unleashes Its Sleuthing Skills as Crafty Phishing Campaign Hones in on Crypto Hardware Wallet Users
- Kraken Taps Fintech Dynamo Bivu Das as New UK Managing Director
- SBF’s Legal Battle Scaramucci’s Testimony Takes a Dark Turn
- Gemini vs. Genesis: A Messier Breakup Than a Kardashian Divorce