はじめに

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

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

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

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

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

変更点

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

  • コンパイラのデフォルトがcancunに変更。
  • mcopyオペコードのコードジェネレーター対応。
  • tstoreの警告回数の変更。

コンパイラのデフォルトがcancunに変更

EthereumのDencunアップグレードにより、新しいEVMバージョンであるCancunが導入されました。 これにより、Solidityコンパイラのデフォルトのバージョンが、新しいバージョンであるCancunをベースにコード生成するように変更されました。

mcopyオペコードのコードジェネレーター対応

Solidityのバージョン0.8.24にて、mcopyというオペコードが追加されました。 このオペコードはYulやインラインラインで使用できるオペコードです。

Yulやインラインアセンプリについては、以下の記事にを参考にしてください。

バージョン0.8.25では、コードジェネレーターがmloadとmstoreのループをmcopy置き換えるようになりました。 これにより、効率的なメモリーコピーが可能になります。

mload

メモリから32バイト(256ビット)のデータを読み込む命令です。 指定されたメモリアドレスからデータを取得します。

solidity
uint256 value = mload(add(memPtr, offset));

上記では、memPtrというメモリアドレスにoffsetを加えた位置から32バイトのデータを読み込んでvalueに格納しています。

mstore

メモリに32バイト(256ビット)のデータを書き込む命令です。 指定されたメモリアドレスにデータを格納します。

solidity
mstore(add(memPtr, offset), value);

上記では、memPtrというメモリアドレスにoffsetを加えた位置にvalueを32バイトのデータとして書き込みます。

mcopy

メモリの一部から別のメモリの一部にデータをコピーする命令です。 連続したメモリ領域に対して効率的にデータを移動させることができます。

solidity
mcopy(destPtr, srcPtr, length);

上記では、srcPtrからdestPtrへlengthバイト分のデータをコピーしています。

このように、mloadとmstoreの2つの命令を使用してコピーするよりも、mcopy命令を使用した方が、1つの命令で高速かつ低コストでコピーを実行できます。

活用される場面としては、abi.encode()やabi.decode()があげられます。 abi.encode()はデータ型をバイト配列に変換し、abi.decode()はバイト配列から元のデータ型に戻す処理を実行します。 この変換の時に大量のデータがメモリにコピーされるため、mcopyを使用することで効率よく実行できます。

一方、ガスコストを削減はしていますが、そこまでの効果はないようです。 理由としては、コンパイラ自体がメモリ内での不要なデータのコピーを避けるように設計されているためです。 また、メモリ以外のcalldataやストレージ、returndataなどには、このmcopyを使用することはできません。

tstoreの警告回数の変更

Transient Storageという一時的なデータ保存用ストレージがあります。 これはトランザクションが終了するまでデータを保持するストレージで、tstoreやtloadというオペコードを使用してアクセスします。 ただ、Transient Storageの誤った使用は予期しない動作やバグの原因になります。 そのため、Solidityバージョン0.8.24から、tstoreオペコードが使用されていると常に警告が表示されるようになっていました。 しかし、同じ警告が繰り返し表示されるのは煩わしいため、コンパイルごとに1回だけ表示されるように変更されました。

その他の変更

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

最後に

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

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