EVMスマートコントラクトGas費最適化ガイド - 13の実用的なヒント

EVM ガス代最適化 - イーサリアムスマートコントラクト開発ガイド

イーサリアムのメインネットのGas費用は常に注目されている問題であり、特にネットワークが混雑している時はさらに深刻です。ピーク時にはユーザーは高額な取引手数料を支払う必要があります。したがって、スマートコントラクトの開発段階でGas費用の最適化を行うことが非常に重要です。Gas消費の最適化は取引コストを効果的に削減するだけでなく、取引効率を向上させ、ユーザーにより経済的で効率的なブロックチェーンの使用体験を提供します。

本記事では、イーサリアム仮想マシン(EVM)のGas費メカニズム、Gas費最適化に関する主要な概念、及びスマートコントラクト開発時のGas費最適化のベストプラクティスについて概説します。これらの内容が開発者にインスピレーションと実用的な助けを提供し、一般ユーザーがEVMのGas費用の運用方式をよりよく理解し、共にブロックチェーンエコシステムの課題に取り組む助けになることを願っています。

! イーサリアムスマートコントラクトのガス最適化のためのトップ10のベストプラクティス

EVMのGas費メカニズムの紹介

EVM互換ネットワークでは、「ガス」は特定の操作を実行するために必要な計算能力を測定する単位です。

EVMの構造レイアウトにおいて、Gas消費は3つの部分に分かれています: 操作実行、外部メッセージ呼び出し、およびメモリとストレージの読み書き。

取引の実行には計算リソースが必要なため、無限ループやサービス拒否(DoS)攻撃を防ぐために一定の手数料が課されます。取引を完了するために必要な手数料は「ガス代」と呼ばれます。

EIP-1559が発効して以来、Gas料金は以下の公式で計算されます:

ガス料金 = 使用したガスの単位 * (ベース料金 + プライオリティ料金)

基本料金は消失し、優先料金はインセンティブとして機能し、バリデーターにトランザクションをブロックチェーンに追加するよう促します。トランザクションを送信する際に、より高い優先料金を設定することで、トランザクションが次のブロックに含まれる可能性を高めることができます。これは、ユーザーがバリデーターに支払う「チップ」のようなものです。

イーサリアムスマートコントラクトのGas最適化トップ10ベストプラクティス

EVMにおけるGasの最適化について理解する

Solidityでスマートコントラクトをコンパイルすると、コントラクトは一連の「オペコード」、すなわちopcodesに変換されます。

任意の操作コード(、例えば契約の作成、メッセージ呼び出しの実行、アカウントストレージへのアクセス、および仮想マシン上での操作の実行)には、認識されたGas消費コストがあります。これらのコストはイーサリアムのホワイトペーパーに記録されています。

複数回のEIPの修正を経て、一部のオペコードのGasコストが調整されており、黄皮書にあるものと異なる可能性があります。

ガス最適化の基本概念

Gas最適化の核心理念は、EVMブロックチェーン上でコスト効率の高い操作を優先し、Gasコストが高い操作を避けることです。

EVMにおいて、以下の操作はコストが低い:

  • メモリ変数の読み書き
  • 定数と不変変数の読み取り
  • ローカル変数の読み書き
  • calldata 配列や構造体などの calldata 変数を読み取る
  • 内部関数呼び出し

コストが高い操作には次のものが含まれます:

  • コントラクトストレージに保存された状態変数の読み書き
  • 外部関数呼び出し
  • ループ操作

! [イーサリアムスマートコントラクトのガス最適化のためのトップ10のベストプラクティス](https://img-cdn.gateio.im/webp-social/moments-b237228ebe933741fb60f2e8bcb38405.webp0192837465674839201

EVMガス費用最適化ベストプラクティス

) 1. ストレージの使用を可能な限り減らす

Solidityでは、Storage###のストレージ(は限られたリソースであり、そのGas消費はMemory)のメモリ(よりもはるかに高くなります。スマートコントラクトがストレージからデータを読み取ったり書き込んだりするたびに、高額なGasコストが発生します。

イーサリアムのホワイトペーパーの定義によれば、ストレージ操作のコストはメモリ操作の100倍以上です。例えば、OPcodesmloadとmstore命令はわずか3ガス単位を消費しますが、ストレージ操作であるsloadとsstoreは最も理想的な状況でも、コストは少なくとも100単位が必要です。

ストレージ使用の制限方法には、次のものがあります:

  • 一時的なデータをメモリに保存する
  • ストレージの変更回数を減らす: 中間結果をメモリに保存し、すべての計算が完了してから結果をストレージ変数に割り当てます。

! [イーサリアムスマートコントラクトのガス最適化のためのトップ10のベストプラクティス])https://img-cdn.gateio.im/webp-social/moments-30f0bc370a7b9ca65f3d623c31262b76.webp(

) 2. 変数パッケージ

スマートコントラクト中に使用されるStorage slot###ストレージスロット(の数および開発者がデータを示す方法は、Gas費の消費に大きな影響を与えます。

Solidityコンパイラは、コンパイル中に連続したストレージ変数をパッケージ化し、32バイトのストレージスロットを変数ストレージの基本単位とします。変数のパッケージ化とは、変数を適切に配置することで、複数の変数が単一のストレージスロットに収まるようにすることを指します。

変数をパッケージ化することで、開発者は大量のGas単位を節約できます。各ストレージスロットがGasを消費するため、変数のパッケージ化は必要なストレージスロットの数を減らすことでGasの使用を最適化します。

! [イーサリアムスマートコントラクトのガス最適化のためのトップ10のベストプラクティス])https://img-cdn.gateio.im/webp-social/moments-995905cb414526d4d991899d0c2e6443.webp0192837465674839201

( 3. データタイプの最適化

適切なデータ型を選択することは、Gasの使用を最適化するのに役立ちます。たとえば、Solidityでは、整数を異なるサイズに細分化できます:uint8、uint16、uint32など。EVMは256ビット単位で操作を実行するため、uint8を使用すると、EVMは最初にそれをuint256に変換しなければならず、この変換は追加のGasを消費します。

しかし、変数をパッキング最適化する場合、4つのuint8変数を1つのストレージスロットにパッキングすると、それらを反復する総コストは4つのuint256変数よりも低くなります。これにより、スマートコントラクトはストレージスロットを1回読み書きし、1回の操作で4つのuint8変数をメモリ/ストレージに配置できます。

! [イーサリアムスマートコントラクトのガス最適化のためのトップ10のベストプラクティス])https://img-cdn.gateio.im/webp-social/moments-55fcdb765912ef9cd238c46b1d248cff.webp###

( 4. 固定サイズの変数を動的変数の代わりに使用する

データが32バイト以内に制御できる場合、bytesまたはstringsの代わりにbytes32データ型を使用することをお勧めします。一般的に、固定サイズの変数は可変サイズの変数よりもガスの消費が少なくなります。バイトの長さを制限できる場合は、できるだけbytes1からbytes32の最小長を選択してください。

) 5. マッピングと配列

Solidityのデータリストは、2つのデータ型で表すことができます: 配列###Arrays###とマッピング(Mappings)ですが、それらの構文と構造はまったく異なります。

マッピングはほとんどの場合、効率が高くコストが低いですが、配列は反復可能でデータ型のパッキングをサポートしています。したがって、データリストを管理する際には、反復が必要ない限り、またはデータ型のパッキングによってGas消費を最適化できる場合を除いて、マッピングを優先して使用することをお勧めします。

! イーサリアムスマートコントラクトのガス最適化のためのトップ10ベストプラクティス

( 6. メモリの代わりに calldata を使用する

関数の引数で宣言された変数は、calldataまたはmemoryに格納できます。両者の主な違いは、memoryは関数によって変更可能であるのに対し、calldataは不変であることです。

この原則を覚えておいてください:関数の引数が読み取り専用である場合は、memoryの代わりにcalldataを優先して使用するべきです。これにより、関数のcalldataからmemoryへの不必要なコピー操作を避けることができます。

![イーサリアムスマートコントラクトのGas最適化トップ10ベストプラクティス])https://img-cdn.gateio.im/webp-social/moments-9c566626ab499ef65d6f5089a2876ad3.webp###

( 7. できるだけConstant/Immutableキーワードを使用してください

Constant/Immutable変数は契約のストレージに保存されません。これらの変数はコンパイル時に計算され、契約のバイトコードに保存されます。したがって、ストレージと比較して、それらのアクセスコストははるかに低く、可能な限りConstantまたはImmutableキーワードを使用することをお勧めします。

! [イーサリアムスマートコントラクトのガス最適化のためのトップ10のベストプラクティス])https://img-cdn.gateio.im/webp-social/moments-c0701f9e09280a1667495d54e262dd2f.webp###

( 8. オーバーフロー/アンダーフローが発生しないことを確認した上でUncheckedを使用する

開発者が算術演算がオーバーフローやアンダーフローを引き起こさないことを確認できる場合、Solidity v0.8.0で導入されたuncheckedキーワードを使用して、余分なオーバーフローやアンダーフローのチェックを回避し、Gasコストを節約できます。

さらに、0.8.0以上のバージョンのコンパイラでは、SafeMathライブラリを使用する必要がなくなりました。なぜなら、コンパイラ自体にオーバーフローおよびアンダーフロー保護機能が組み込まれているからです。

! [イーサリアムスマートコントラクトのガス最適化のためのトップ10のベストプラクティス])https://img-cdn.gateio.im/webp-social/moments-a823fb7761aafa6529a6c45304e0314b.webp###

( 9. 最適化モディファイア

モディファイアのコードは変更された関数に埋め込まれ、モディファイアを使用するたびにそのコードがコピーされます。これによりバイトコードのサイズが増加し、Gas消費が増加します。内部関数にロジックを再構築し、モディファイア内でその内部関数を再利用することで、バイトコードのサイズを減少させ、Gasコストを削減できます。

![イーサリアムスマートコントラクトのGas最適化トップ10ベストプラクティス])https://img-cdn.gateio.im/webp-social/moments-839b91e2f02389949aa698d460a497d8.webp###

( 10. ショートサーキット最適化

||および&&演算子に対して、論理演算はショートサーキット評価が発生します。つまり、最初の条件が論理式の結果を決定できる場合、2番目の条件は評価されません。

Gas消費を最適化するために、計算コストが低い条件を前に置くべきです。そうすることで、高コストの計算をスキップできる可能性があります。

! [イーサリアムスマートコントラクトのガス最適化のためのトップ10のベストプラクティス])https://img-cdn.gateio.im/webp-social/moments-a141884dcdcdc56faff12eee2601b7b7.webp###

その他の一般的な推奨事項

( 1. 無駄なコードを削除する

契約に未使用の関数や変数が存在する場合は、それを削除することをお勧めします。これは契約のデプロイコストを削減し、契約のサイズを小さく保つ最も直接的な方法です。

以下は幾つかの実用的な提案です:

  • 最も効率的なアルゴリズムを使用して計算を行います。契約内で特定の計算結果を直接使用する場合は、これらの冗長な計算プロセスを削除する必要があります。本質的に、使用されていない計算は削除されるべきです。

  • イーサリアムでは、開発者はストレージスペースを解放することでGas報酬を得ることができます。もし特定の変数が不要になった場合は、deleteキーワードを使用して削除するか、デフォルト値に設定する必要があります。

  • ループ最適化: 高コストのループ操作を避け、ループをできるだけ結合し、繰り返し計算をループ本体から移動させる。

) 2. プリコンパイルされたスマートコントラクトを使用する

プレコンパイル契約は、暗号化やハッシュ操作などの複雑なライブラリ関数を提供します。コードはEVM上ではなく、クライアントノードのローカルで実行されるため、必要なガスは少なくなります。プレコンパイル契約を使用することで、スマートコントラクトの実行に必要な計算作業量を減らすことにより、ガスを節約できます。

予めコンパイルされたコントラクトの例には、楕円曲線デジタル署名アルゴリズム###ECDSA###やSHA2-256ハッシュアルゴリズムが含まれます。スマートコントラクトでこれらの予めコンパイルされたコントラクトを使用することで、開発者はガスコストを削減し、アプリケーションの実行効率を向上させることができます。

( 3. インラインアセンブリコードを使用する

インラインアセンブリ)in-line assembly###は、開発者がEVMによって直接実行される低レベルで効率的なコードを書くことを可能にし、高価なSolidityオペコードを使用する必要がありません。インラインアセンブリは、メモリとストレージの使用をより正確に制御することも可能にし、Gas費用をさらに削減します。また、インラインアセンブリは、Solidityだけでは実現が難しい複雑な操作を実行でき、Gas消費の最適化に対してより多くの柔軟性を提供します。

しかし、インラインアセンブリの使用はリスクを伴い、エラーを引き起こしやすいです。したがって、注意して使用し、経験豊富な開発者のみが操作すべきです。

( 4. Layer 2ソリューションを使用する

Layer 2ソリューションを使用することで、イーサリアムのメインネットに保存および計算する必要があるデータ量を削減できます。

rollups、サイドチェーン、状態チャネルなどのLayer 2ソリューションは、取引処理を主イーサリアムチェーンからオフロードすることができ、より速く、より安価な取引を実現します。

大量のトランザクションを束ねることで、これらのソリューションはオンチェーンのトランザクション数を減らし、Gas費用を削減します。Layer 2ソリューションを使用することで、エーテルのスケーラビリティも向上し、より多くのユーザーやアプリケーションがネットワークに参加できるようになりますが、

ETH2.09%
原文表示
このページには第三者のコンテンツが含まれている場合があり、情報提供のみを目的としております(表明・保証をするものではありません)。Gateによる見解の支持や、金融・専門的な助言とみなされるべきものではありません。詳細については免責事項をご覧ください。
  • 報酬
  • 4
  • 共有
コメント
0/400
GateUser-beba108dvip
· 20時間前
ガス費圧が私を一頭はそうだ
原文表示返信0
BTCBeliefStationvip
· 21時間前
Gasも内巻きになるのか ドロップしてもいいだろう
原文表示返信0
ParanoiaKingvip
· 21時間前
このガス代は人を食べて骨を吐き出さないですね。
原文表示返信0
DegenGamblervip
· 21時間前
ガスが狂っている、終わりがない
原文表示返信0
いつでもどこでも暗号資産取引
qrCode
スキャンしてGateアプリをダウンロード
コミュニティ
日本語
  • 简体中文
  • English
  • Tiếng Việt
  • 繁體中文
  • Español
  • Русский
  • Français (Afrique)
  • Português (Portugal)
  • Bahasa Indonesia
  • 日本語
  • بالعربية
  • Українська
  • Português (Brasil)