🛠️

Solidity 0.8.28での変更点まとめ

2024/10/10に公開

はじめに

初めまして。
CryptoGamesというブロックチェーンゲーム企業でエンジニアをしている cardene(かるでね) です!
スマートコントラクトを書いたり、フロントエンド・バックエンド・インフラと幅広く触れています。

https://cryptogames.co.jp/

代表的なゲームはクリプトスペルズというブロックチェーンゲームです。

https://cryptospells.jp/

以下でも情報発信しているので、興味ある記事があればぜひ読んでみてください!

https://twitter.com/cardene777

https://chaldene.net/

https://qiita.com/cardene

https://cardene.substack.com/

https://mirror.xyz/0xcE77b9fCd390847627c84359fC1Bc02fC78f0e58

https://cardene.notion.site/ERC-EIP-2a03fa3ea33d43baa9ed82288f98d4a9?pvs=4

今回はSolidityのバージョン0.8.28での変更点をまとめていきます。

以下の公式のリリース記事をもとにまとめていきます。

https://soliditylang.org/blog/2024/10/09/solidity-0.8.28-release-announcement/

変更点

Solidityのバージョン0.8.28では以下の項目が変更されました。

  • Transientストレージ変数の完全サポート
  • Yul ASTのJSON生成をオンデマンド化
  • コントラクトごとのパイプラインの設定
  • バグ修正とその他の改善

Transientストレージ変数の完全サポート

Solidity 0.8.28では、「Transientストレージ変数」と呼ばれる一時的なストレージ変数が正式にサポートされました。
Version 0.8.27では、Transient変数の構文自体は解析されていましたが、バイトコードを生成することはできなかったです。
今回のリリースにより、Transientストレージ変数を完全にサポートしてバイトコード生成が可能になりました。

https://zenn.dev/cryptogames/articles/1d9850df4148ab

Yul ASTのJSON生成をオンデマンド化

https://zenn.dev/heku/books/c28469224e315f/viewer/0799d1

Yul ASTは、Yulコードをツリー形式で表現したもので、コードの各部分(関数、変数、条件式など)をノードとして階層的に整理したものです。
これにより、コンパイラーがコードの構造を効率的に解析し、最適化やバイトコード生成が可能になります。

https://zenn.dev/heku/books/c28469224e315f/viewer/378a1d#正式な仕様

Solidityコンパイラーは、出力データ(ABIやメタデータなど)を内部的にキャッシュします。
これにより、ABIとメタデータの両方を同時にリクエストした場合、同じデータが重複して生成されることを防いで効率的なコンパイルが可能になります。

しかし、Yul ASTのような新しく導入された大きなデータも、明示的にリクエストされなくてもキャッシュされてしまう問題がありました。
大規模プロジェクトでは、この問題により大量のメモリを消費するにもかかわらず、パフォーマンスの向上に結びつかず効率が良くない状態でした。

バージョン0.8.28では、この問題を解決して以下の改善が行われました。

  • キャッシュの削減
    • 必要ない場合はYul ASTを生成せずメモリ使用量を大幅に削減。
    • これにより、メモリの消費が最大で80%削減。
  • コンパイル時間の短縮
    • Yul ASTの不要な生成を防ぎコンパイル時間を最大で25%短縮。
File Time (v0.8.27) Time (v0.8.28) Change
openzeppelin 40 s 35 s -13%
uniswap-v4 157 s 128 s -18%
eigenlayer 716 s 545 s -24%
File Memory (0.8.27) Memory (0.8.28) Change
openzeppelin 1220 MiB 506 MiB -59%
uniswap-v4 4805 MiB 1496 MiB -69%
eigenlayer 20346 MiB 4455 MiB -78%

コントラクトごとのパイプラインの設定

Solidityコンパイラーは「遅延評価」という仕組みを持っており、必要な部分だけを実行して出力を生成します。
必須の処理は「解析」と「分析」段階でエラーを検出し、ABI(アプリケーションバイナリインターフェース)、メタデータ、Solidity AST(抽象構文木)、ストレージレイアウトなどの情報が得られます。
もしバイトコードやIR(中間表現)が不要であれば、コード生成や最適化のステージはスキップされます。

これまでの仕組みでは、コンパイルの時に全てのコントラクトに対して同じパイプラインが適用されていました。
そのため、例えば1つのコントラクトに対してバイトコードをリクエストしたとしても、他の全てのコントラクトに対してもバイトコードが生成されていました。
これにより、不要な作業が増え、コンパイル時間が長くなってしまう問題がありました。

バージョン0.8.28では、この制限が解除されてr特定のコントラクトに対してのみ必要なステージを実行できるようになりました。
あるコントラクトでバイトコードが必要な場合でも、他のコントラクトでは必要ない場合はそれらのコントラクトのバイトコード生成はスキップされます。
これにより、無駄な処理が減り、コンパイル全体の効率が向上します。

この変更は、全てのコントラクトに同じ出力を求めるようなシンプルなコンパイル作業にはあまり影響を与えません。
しかし、フレームワークなどを使ってより高度なワークフローを実装する場合など、コードの一部だけが変更される場合に再コンパイル作業がより迅速になります。

この変更はStandard JSONインターフェース(Solidityコンパイラーの標準的なJSON形式のインターフェース)にのみ適用され、CLIではコントラクトごとの出力選択はまだサポートされていません。

その他の変更

その他の細かい修正については以下の記事を参考にしてください。

https://soliditylang.org/blog/2024/09/04/solidity-0.8.27-release-announcement/

最後に

今回はSolidityのバージョン0.8.28の変更点をまとめました。

以下でも情報発信しているので、興味ある記事があればぜひ読んでみてください!

https://twitter.com/cardene777

https://chaldene.net/

https://qiita.com/cardene

https://cardene.substack.com/

https://mirror.xyz/0xcE77b9fCd390847627c84359fC1Bc02fC78f0e58

https://cardene.notion.site/ERC-EIP-2a03fa3ea33d43baa9ed82288f98d4a9?pvs=4

CryptoGames

Discussion