コンパイル:翻訳計画。 出典:soliditylang.orgSolidityコンパイラv0.8.22の最新バージョンがリリースされました。 0.8.22コンパイラには、ファイルレベルのイベント定義、未チェックループのインクリメンタル最適化、EVMアセンブリJSONのインポートのサポートなど、言語とコンパイラの多くの改善が含まれています。## 重要このリリースでは、保守がますます困難になっているコンスタンティノープル (コンスタンティノープル) より下の EVM のサポートが廃止されます。 これらの古めかしいバージョンは、イーサリアムのメインネットやテストネットでは長い間時代遅れであり、他のネットワークにももはや関係がないと思われます。 コード パスとソリューションが複雑なと、新しいバージョンの機能開発とテストが遅くなるため、将来のコンパイラ リリースでサポートを停止する予定です。 これらの EVM バージョンのサポートをご利用の場合は、TI までお問い合わせください[6] 。## 新機能のハイライト### 未チェックのループインクリメントループカウンタを増やすときに未チェックの演算を使用するのは、ガスの最適化のためです[7] 一般的な方法。 次のループとカウンター i の例で説明しましょう。for (uint i = 0; i < array.length; ++i) {acc += 配列[i] ;i はループ本体によって変更されません }多くの場合 (以下の正確な条件を参照)、比較演算によって i がその型の最大値に到達しないことが保証されるため、最大値に達する前にループが停止すると考えてよいでしょう。 この場合、カウンターの安全チェックは冗長であり、ガスの無駄になります。 これにより、ユーザーは長い未チェックのパターンを使用し、チェックをバイパスして、ループ内の未チェックの算術ブロックでカウンターをインクリメンタルにラップします。for (uint i = 0; i < array.length;){ acc += 配列[i] ;unchecked { i++; } // オーバーフローチェックなしでインクリメントされます -- ガス使用量が少なくなります}Solidity 0.8.22では、ループカウンターの未チェックの算術インクリメントを自動的に生成するオーバーフローチェックの最適化が導入されています。 この新しい最適化により、前の例のように、ループ本体で長い未チェックのデルタ パターンを使用する必要がなくなります。対照的に、新しい最適化により、ユーザーはガス効率を犠牲にすることなく、より読みやすい生のコードに戻ることができます。新たに最適化された流出回避チェックの正確な条件は次のとおりです。※サイクル条件はi<... ここで、i はローカル変数です (以降、"ループ カウンター" と呼びます)。* この比較は、ループカウンタと同じ型で実行する必要があります、つまり、比較の前にループカウンタが暗黙的に拡張されないように、右側の型をループカウンタの型に暗黙的に変換する必要があります。* ループカウンタは、組み込み整数型のローカル変数である必要があります。* ループ式は、ループカウンタ i++ または ++i の接頭辞または接尾辞のインクリメントでなければなりません。※サイクルカウンターは、サイクル条件やサイクルボディでは変更できません。2 番目の条件を明確にするために、次のコード スニペットについて考えてみます。for (uint8 i = 0; in < UINT16(1000); ++I) {ループ本体}この場合、i は比較の前に uint16 に変換され、条件が実際に false になることはないため、インクリメントされたオーバーフロー チェックは削除できません。また、< は最適化をトリガーする唯一の比較演算子であることに注意してください。 演算子 <= およびその他の演算子は意図的に除外されています。 また、演算子は組み込みである必要があり、ユーザー定義の<は対象外です。最適化は単純明快で常に有益なので、オプティマイザーの残りの部分が共通設定settings.optimizer.enabledを使用して無効になっている場合でも有効になります。 標準の JSON 入力で settings.optimizer.details.simpleCounterForLoopUncheckedIncrement を false に設定することで、明示的にオフにすることができます。 コマンドラインインターフェイスを使用して無効にすることはできません。### Yul オプティマイザを調整してゼロリテラルを再生成する新しいバージョンは、バージョン 0.8.20 で導入された PUSH0 オペコード サポートに基づいて構築され、Rematerialiser が追加されています[8] [9] 最適化ステップは、ゼロリテラルを変数参照として格納するのではなく、常に再生成するように拡張され、DUPの代わりにPUSH0を使用してガスコストを削減できます。 これを効果的に行うために、Rematerialiser と UnusedPruner が追加されています ステップは、Yul オプティマイザーのデフォルトのクリーンアップシーケンスに追加されます。### EVM アセンブリ JSON のインポートのサポートを追加 (実験的)この新しいリリースでは、EVMアセンブリのインポートを実験的にサポートし、バイトコード生成前に外部ツールが超最適化を実行する可能性を広げています。 この機能の主な目的は、低レベルの EVM アセンブリのシリアライゼーション・フォーマットを定義して、コンパイラが生成したアセンブリをエクスポート、変更、再インポートして、通常のコンパイル・プロセスを再開できるようにすることです。重要: これは試験運用版の機能であり、現在本番環境ではご利用いただけません。 この機能は、このリリースで提供されているため、試してみてフィードバックをお寄せください。### ファイルレベルでイベントを定義できますSolidity 0.8.22 では、ファイルレベルでイベントを定義できます。 イベント定義をコントラクトの範囲外に配置できるようになりました。 これにより、ライブラリ内のイベントを人為的にラップすることなく、コードを整理するための別のオプションが提供されます。さらに、このリリースでは、コードの外部コントラクトまたはインターフェイスで定義されたイベントを生成するときに NatSpec を生成するときにエラーを引き起こすバグが修正されています。 以前のリリース(0.8.21)では、Solidityコンパイラは、現在のコントラクトから継承されていないコントラクトとインターフェイスで定義されたイベントへの制限付きアクセスのサポートを追加しましたが、バグによりこの機能を完全に使用できませんでした。このバグ修正とファイルレベルのイベント定義の許可により、最新バージョンのSolidityでは、ユーザーはエラーなしで次の例をコンパイルできます。インターフェイス I {イベントForeignEvent();}契約C {イベントForeignEvent();}イベントE();契約D {関数f()パブリック{外部イベントを発行すると、0.8.21で内部エラーが発生しますI.ForeignEvent()を出力します。C.ForeignEvent()を出力します。ファイルレベルのイベントを発行します。新機能。 E()を放出します。}}## 完全な変更履歴### 言語機能* イベントをファイルレベルで定義できます。### コンパイラの機能* コードジェネレータ: count 変数がオーバーフローしない場合の for ループの冗長なオーバーフローチェックを削除* コマンドライン インターフェイス: CLIまたは標準のJSON入力で明示的に指定されていないソースファイルをコンパイラがロードしないようにするための--no-import-callbackオプションを追加。* コマンドライン インターフェイス: --asm-json で使用されるフォーマットで EVM アセンブリをインポートするための実験的な --import-asm-json オプションを追加。コマンドライン・インタフェース: コンパイルされたパイプラインの外部で生成されたエラー・メッセージには、適切な重大度と色分けを使用します。* EVM: "homestead", "tangerineWhistle", "spuriousDragon", "byzantium" の EVM バージョンのサポートを非推奨にしました。* Parser: 実験的なエラーリカバリモードを削除しました (--error-recovery/settings.parserErrorRecovery)。* SMTChecker:ユーザー定義演算子をサポートします。* Yul Optimizer: PUSH0 がサポートされている場合、変数にゼロ値を格納する代わりに、ゼロリテラルを使用することを優先します。* Yul Optimizer: デフォルトのクリーンアップシーケンスの最後に Rematerializer ステップと UnusedPruner ステップを実行します。### バグ修正* コードジェネレーター: via-IR コードジェネレーター経由の出力が、インポートコールバックで見つかったファイルに依存していた問題を修正。 場合によっては、異なる AST ID の割り当てによって、内部スケジューリングの関数の順序が変更され、その結果、明らかに異なっていても意味的には同等のバイトコードになることがあります。* NatSpec: 外部コントラクトまたはインターフェイスで定義されたイベントを発生させたコントラクトのユーザー ドキュメントまたは開発ドキュメントを要求する際の内部エラーを修正しました。* SMTChecker: 完了後にループが拡大する原因となっていたエンコード エラーを修正。* SMTChecker: 条件チェックの前に while ループや for ループをアンワインドすると、定数条件チェックの不整合を修正。* Yul Optimizer: CSE 中にコンパイラが生成した Yul 変数名が置換の決定に影響し、異なる (しかし同等の) バイトコードになる場合がある問題を修正しました。
イーサリアムで最も人気のあるスマートコントラクト開発言語であるSolidityの新バージョンがリリースされました
コンパイル:翻訳計画。 出典:soliditylang.org
Solidityコンパイラv0.8.22の最新バージョンがリリースされました。 0.8.22コンパイラには、ファイルレベルのイベント定義、未チェックループのインクリメンタル最適化、EVMアセンブリJSONのインポートのサポートなど、言語とコンパイラの多くの改善が含まれています。
重要
このリリースでは、保守がますます困難になっているコンスタンティノープル (コンスタンティノープル) より下の EVM のサポートが廃止されます。 これらの古めかしいバージョンは、イーサリアムのメインネットやテストネットでは長い間時代遅れであり、他のネットワークにももはや関係がないと思われます。 コード パスとソリューションが複雑なと、新しいバージョンの機能開発とテストが遅くなるため、将来のコンパイラ リリースでサポートを停止する予定です。 これらの EVM バージョンのサポートをご利用の場合は、TI までお問い合わせください[6] 。
新機能のハイライト
未チェックのループインクリメント
ループカウンタを増やすときに未チェックの演算を使用するのは、ガスの最適化のためです[7] 一般的な方法。 次のループとカウンター i の例で説明しましょう。
for (uint i = 0; i < array.length; ++i) { acc += 配列[i] ;i はループ本体によって変更されません }
多くの場合 (以下の正確な条件を参照)、比較演算によって i がその型の最大値に到達しないことが保証されるため、最大値に達する前にループが停止すると考えてよいでしょう。 この場合、カウンターの安全チェックは冗長であり、ガスの無駄になります。 これにより、ユーザーは長い未チェックのパターンを使用し、チェックをバイパスして、ループ内の未チェックの算術ブロックでカウンターをインクリメンタルにラップします。
for (uint i = 0; i < array.length;){ acc += 配列[i] ; unchecked { i++; } // オーバーフローチェックなしでインクリメントされます -- ガス使用量が少なくなります }
Solidity 0.8.22では、ループカウンターの未チェックの算術インクリメントを自動的に生成するオーバーフローチェックの最適化が導入されています。 この新しい最適化により、前の例のように、ループ本体で長い未チェックのデルタ パターンを使用する必要がなくなります。
対照的に、新しい最適化により、ユーザーはガス効率を犠牲にすることなく、より読みやすい生のコードに戻ることができます。
新たに最適化された流出回避チェックの正確な条件は次のとおりです。
※サイクル条件はi<... ここで、i はローカル変数です (以降、"ループ カウンター" と呼びます)。
2 番目の条件を明確にするために、次のコード スニペットについて考えてみます。
for (uint8 i = 0; in < UINT16(1000); ++I) { ループ本体 }
この場合、i は比較の前に uint16 に変換され、条件が実際に false になることはないため、インクリメントされたオーバーフロー チェックは削除できません。
また、< は最適化をトリガーする唯一の比較演算子であることに注意してください。 演算子 <= およびその他の演算子は意図的に除外されています。 また、演算子は組み込みである必要があり、ユーザー定義の<は対象外です。
最適化は単純明快で常に有益なので、オプティマイザーの残りの部分が共通設定settings.optimizer.enabledを使用して無効になっている場合でも有効になります。 標準の JSON 入力で settings.optimizer.details.simpleCounterForLoopUncheckedIncrement を false に設定することで、明示的にオフにすることができます。 コマンドラインインターフェイスを使用して無効にすることはできません。
Yul オプティマイザを調整してゼロリテラルを再生成する
新しいバージョンは、バージョン 0.8.20 で導入された PUSH0 オペコード サポートに基づいて構築され、Rematerialiser が追加されています[8] [9] 最適化ステップは、ゼロリテラルを変数参照として格納するのではなく、常に再生成するように拡張され、DUPの代わりにPUSH0を使用してガスコストを削減できます。 これを効果的に行うために、Rematerialiser と UnusedPruner が追加されています ステップは、Yul オプティマイザーのデフォルトのクリーンアップシーケンスに追加されます。
EVM アセンブリ JSON のインポートのサポートを追加 (実験的)
この新しいリリースでは、EVMアセンブリのインポートを実験的にサポートし、バイトコード生成前に外部ツールが超最適化を実行する可能性を広げています。 この機能の主な目的は、低レベルの EVM アセンブリのシリアライゼーション・フォーマットを定義して、コンパイラが生成したアセンブリをエクスポート、変更、再インポートして、通常のコンパイル・プロセスを再開できるようにすることです。
重要: これは試験運用版の機能であり、現在本番環境ではご利用いただけません。 この機能は、このリリースで提供されているため、試してみてフィードバックをお寄せください。
ファイルレベルでイベントを定義できます
Solidity 0.8.22 では、ファイルレベルでイベントを定義できます。 イベント定義をコントラクトの範囲外に配置できるようになりました。 これにより、ライブラリ内のイベントを人為的にラップすることなく、コードを整理するための別のオプションが提供されます。
さらに、このリリースでは、コードの外部コントラクトまたはインターフェイスで定義されたイベントを生成するときに NatSpec を生成するときにエラーを引き起こすバグが修正されています。 以前のリリース(0.8.21)では、Solidityコンパイラは、現在のコントラクトから継承されていないコントラクトとインターフェイスで定義されたイベントへの制限付きアクセスのサポートを追加しましたが、バグによりこの機能を完全に使用できませんでした。
このバグ修正とファイルレベルのイベント定義の許可により、最新バージョンのSolidityでは、ユーザーはエラーなしで次の例をコンパイルできます。
インターフェイス I { イベントForeignEvent(); } 契約C { イベントForeignEvent(); } イベントE(); 契約D { 関数f()パブリック{ 外部イベントを発行すると、0.8.21で内部エラーが発生します I.ForeignEvent()を出力します。 C.ForeignEvent()を出力します。 ファイルレベルのイベントを発行します。新機能。 E()を放出します。 } }
完全な変更履歴
言語機能
コンパイラの機能
バグ修正