[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"article-deep-evm-3-gas-rikai-kosuto-riyu":3},{"article":4,"author":54},{"id":5,"category_id":6,"title":7,"slug":8,"excerpt":9,"content_md":10,"content_html":11,"locale":12,"author_id":13,"published":14,"published_at":15,"meta_title":7,"meta_description":16,"focus_keyword":17,"og_image":18,"canonical_url":18,"robots_meta":19,"created_at":15,"updated_at":15,"tags":20,"category_name":34,"related_articles":35},"d4000000-0000-0000-0000-000000000103","a0000000-0000-0000-0000-000000000042","Deep EVM #3：ガスの理解 — コントラクトのコストが決まる理由","deep-evm-3-gas-rikai-kosuto-riyu","EVMガスコストの精密な内訳：固有ガス、EIP-2929のコールド\u002Fウォームアクセス、リファンドメカニクス、実績のある最適化パターン。","## ガスは抽象ではない\n\n開発者はしばしばガスを漠然とした「コスト」メトリクスとして扱います。実際には、ガスは正確な公式を持つ精密に定義されたリソース会計システムです。すべてのオペコード、calldataのすべてのバイト、すべてのストレージアクセスには、イエローペーパーとその後のEIPで定義された決定論的なガスコストがあります。\n\nこれらのコストを理解することで、ガス最適化は推測からエンジニアリングに変わります。\n\n## 固有ガス：ベースライン\n\nコントラクトコードが単一のオペコードを実行する前に、トランザクションはすでにガスを消費しています。これが**固有ガス**です：\n\n```\nintrinsic_gas = 21000                           \u002F\u002F 基本トランザクションコスト\n             + 16 * nonzero_calldata_bytes       \u002F\u002F 非ゼロバイトあたり\n             + 4 * zero_calldata_bytes            \u002F\u002F ゼロバイトあたり\n             + access_list_cost                   \u002F\u002F EIP-2930アクセスリストの場合\n             + 32000 (コントラクト作成の場合)       \u002F\u002F CREATEトランザクションのみ\n```\n\n## EIP-2929：アクセスリスト革命\n\nEIP-2929はトランザクションごとのアクセスセットを導入しました。最初にアクセスした時は「コールド」で追加ガスがかかり、以降は「ウォーム」で安価です。\n\n| オペコード | コールド | ウォーム | 節約 |\n|----------|--------|--------|------|\n| SLOAD | 2100 | 100 | 2000 |\n| BALANCE | 2600 | 100 | 2500 |\n| CALL | 2600 | 100 | 2500 |\n\n### EIP-2930アクセスリスト\n\nアクセスリストを含めることで、アドレスとストレージスロットを「プリウォーム」できます。ストレージキーあたり1900ガスで、コールドSLOADの2100ガスより安価です。\n\n## SSTORE：最も複雑なオペコード\n\nSSTOREのガスコストは、元の値、現在の値、新しい値の3つの要因に依存します。\n\nゼロスロットを非ゼロに設定するコストは**20000ガス**（新しいステートトライリーフノードの挿入）。既存の非ゼロスロットの変更は**2900ガス**（ウォーム）。この7倍の差は重要な最適化機会です。\n\n## 実際に効果のある最適化パターン\n\n### 1. ストレージ読み取りをメモリにキャッシュ\n\n```solidity\n\u002F\u002F 悪い例：3回のSLOAD\nfunction withdraw() external {\n    require(balances[msg.sender] > 0);\n    uint256 amount = balances[msg.sender];\n    balances[msg.sender] = 0;\n}\n\n\u002F\u002F 良い例：1回のSLOAD\nfunction withdraw() external {\n    uint256 amount = balances[msg.sender];\n    require(amount > 0);\n    balances[msg.sender] = 0;\n}\n```\n\n### 2. ストレージ変数のパッキング\n\n```solidity\n\u002F\u002F 3スロット、3回のSLOAD = 6300ガス（コールド）\nuint256 price;\nuint256 amount;\nuint256 timestamp;\n\n\u002F\u002F 1スロット、1回のSLOAD = 2100ガス（コールド）\nuint128 price;\nuint64 amount;\nuint64 timestamp;\n```\n\n### 3. メモリの代わりにCalldataを使用\n\n```solidity\n\u002F\u002F 悪い例\nfunction processOrders(Order[] memory orders) external { ... }\n\n\u002F\u002F 良い例\nfunction processOrders(Order[] calldata orders) external { ... }\n```\n\n### 4. Unchecked算術（安全な場合）\n\n```solidity\nfor (uint256 i = 0; i \u003C length;) {\n    \u002F\u002F ... ループ本体 ...\n    unchecked { ++i; }\n}\n```\n\n### 5. カスタムエラーを使用\n\n```solidity\n\u002F\u002F 悪い例\nrequire(amount > 0, \"Amount must be positive\");\n\n\u002F\u002F 良い例\nerror InvalidAmount();\nif (amount == 0) revert InvalidAmount();\n```\n\n## 実例：Uniswap V3スワップのガス内訳\n\n| コンポーネント | ガス |\n|-------------|-----|\n| 固有（21000 + calldata） | ~21,500 |\n| 関数ディスパッチ | ~100 |\n| 入力バリデーション | ~200 |\n| プール状態読み取り | ~4,200（コールド） |\n| 価格計算 | ~5,000 |\n| 残高更新（2回のSSTORE） | ~10,000 |\n| トークン転送（2回の外部コール） | ~15,000 |\n| イベント発行 | ~1,500 |\n| **合計** | **~57,500** |\n\nガスの約60%がストレージ操作と外部コールに費やされます。\n\n## まとめ\n\nガス最適化は算術オペコードのマイクロ最適化ではなく、ストレージアクセスと外部コールの最小化です。最もガスを節約するパターンはアーキテクチャ的なものです：ストレージパッキング、キャッシング、calldataの使用、アクセスリストの最適化。","\u003Ch2 id=\"\">ガスは抽象ではない\u003C\u002Fh2>\n\u003Cp>開発者はしばしばガスを漠然とした「コスト」メトリクスとして扱います。実際には、ガスは正確な公式を持つ精密に定義されたリソース会計システムです。すべてのオペコード、calldataのすべてのバイト、すべてのストレージアクセスには、イエローペーパーとその後のEIPで定義された決定論的なガスコストがあります。\u003C\u002Fp>\n\u003Cp>これらのコストを理解することで、ガス最適化は推測からエンジニアリングに変わります。\u003C\u002Fp>\n\u003Ch2 id=\"\">固有ガス：ベースライン\u003C\u002Fh2>\n\u003Cp>コントラクトコードが単一のオペコードを実行する前に、トランザクションはすでにガスを消費しています。これが\u003Cstrong>固有ガス\u003C\u002Fstrong>です：\u003C\u002Fp>\n\u003Cpre>\u003Ccode>intrinsic_gas = 21000                           \u002F\u002F 基本トランザクションコスト\n             + 16 * nonzero_calldata_bytes       \u002F\u002F 非ゼロバイトあたり\n             + 4 * zero_calldata_bytes            \u002F\u002F ゼロバイトあたり\n             + access_list_cost                   \u002F\u002F EIP-2930アクセスリストの場合\n             + 32000 (コントラクト作成の場合)       \u002F\u002F CREATEトランザクションのみ\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"eip-2929\">EIP-2929：アクセスリスト革命\u003C\u002Fh2>\n\u003Cp>EIP-2929はトランザクションごとのアクセスセットを導入しました。最初にアクセスした時は「コールド」で追加ガスがかかり、以降は「ウォーム」で安価です。\u003C\u002Fp>\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>オペコード\u003C\u002Fth>\u003Cth>コールド\u003C\u002Fth>\u003Cth>ウォーム\u003C\u002Fth>\u003Cth>節約\u003C\u002Fth>\u003C\u002Ftr>\u003C\u002Fthead>\u003Ctbody>\n\u003Ctr>\u003Ctd>SLOAD\u003C\u002Ftd>\u003Ctd>2100\u003C\u002Ftd>\u003Ctd>100\u003C\u002Ftd>\u003Ctd>2000\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>BALANCE\u003C\u002Ftd>\u003Ctd>2600\u003C\u002Ftd>\u003Ctd>100\u003C\u002Ftd>\u003Ctd>2500\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>CALL\u003C\u002Ftd>\u003Ctd>2600\u003C\u002Ftd>\u003Ctd>100\u003C\u002Ftd>\u003Ctd>2500\u003C\u002Ftd>\u003C\u002Ftr>\n\u003C\u002Ftbody>\u003C\u002Ftable>\n\u003Ch3>EIP-2930アクセスリスト\u003C\u002Fh3>\n\u003Cp>アクセスリストを含めることで、アドレスとストレージスロットを「プリウォーム」できます。ストレージキーあたり1900ガスで、コールドSLOADの2100ガスより安価です。\u003C\u002Fp>\n\u003Ch2 id=\"sstore\">SSTORE：最も複雑なオペコード\u003C\u002Fh2>\n\u003Cp>SSTOREのガスコストは、元の値、現在の値、新しい値の3つの要因に依存します。\u003C\u002Fp>\n\u003Cp>ゼロスロットを非ゼロに設定するコストは\u003Cstrong>20000ガス\u003C\u002Fstrong>（新しいステートトライリーフノードの挿入）。既存の非ゼロスロットの変更は\u003Cstrong>2900ガス\u003C\u002Fstrong>（ウォーム）。この7倍の差は重要な最適化機会です。\u003C\u002Fp>\n\u003Ch2 id=\"\">実際に効果のある最適化パターン\u003C\u002Fh2>\n\u003Ch3>1. ストレージ読み取りをメモリにキャッシュ\u003C\u002Fh3>\n\u003Cpre>\u003Ccode class=\"language-solidity\">\u002F\u002F 悪い例：3回のSLOAD\nfunction withdraw() external {\n    require(balances[msg.sender] &gt; 0);\n    uint256 amount = balances[msg.sender];\n    balances[msg.sender] = 0;\n}\n\n\u002F\u002F 良い例：1回のSLOAD\nfunction withdraw() external {\n    uint256 amount = balances[msg.sender];\n    require(amount &gt; 0);\n    balances[msg.sender] = 0;\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>2. ストレージ変数のパッキング\u003C\u002Fh3>\n\u003Cpre>\u003Ccode class=\"language-solidity\">\u002F\u002F 3スロット、3回のSLOAD = 6300ガス（コールド）\nuint256 price;\nuint256 amount;\nuint256 timestamp;\n\n\u002F\u002F 1スロット、1回のSLOAD = 2100ガス（コールド）\nuint128 price;\nuint64 amount;\nuint64 timestamp;\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>3. メモリの代わりにCalldataを使用\u003C\u002Fh3>\n\u003Cpre>\u003Ccode class=\"language-solidity\">\u002F\u002F 悪い例\nfunction processOrders(Order[] memory orders) external { ... }\n\n\u002F\u002F 良い例\nfunction processOrders(Order[] calldata orders) external { ... }\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>4. Unchecked算術（安全な場合）\u003C\u002Fh3>\n\u003Cpre>\u003Ccode class=\"language-solidity\">for (uint256 i = 0; i &lt; length;) {\n    \u002F\u002F ... ループ本体 ...\n    unchecked { ++i; }\n}\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch3>5. カスタムエラーを使用\u003C\u002Fh3>\n\u003Cpre>\u003Ccode class=\"language-solidity\">\u002F\u002F 悪い例\nrequire(amount &gt; 0, \"Amount must be positive\");\n\n\u002F\u002F 良い例\nerror InvalidAmount();\nif (amount == 0) revert InvalidAmount();\n\u003C\u002Fcode>\u003C\u002Fpre>\n\u003Ch2 id=\"uniswap-v3\">実例：Uniswap V3スワップのガス内訳\u003C\u002Fh2>\n\u003Ctable>\u003Cthead>\u003Ctr>\u003Cth>コンポーネント\u003C\u002Fth>\u003Cth>ガス\u003C\u002Fth>\u003C\u002Ftr>\u003C\u002Fthead>\u003Ctbody>\n\u003Ctr>\u003Ctd>固有（21000 + calldata）\u003C\u002Ftd>\u003Ctd>~21,500\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>関数ディスパッチ\u003C\u002Ftd>\u003Ctd>~100\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>入力バリデーション\u003C\u002Ftd>\u003Ctd>~200\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>プール状態読み取り\u003C\u002Ftd>\u003Ctd>~4,200（コールド）\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>価格計算\u003C\u002Ftd>\u003Ctd>~5,000\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>残高更新（2回のSSTORE）\u003C\u002Ftd>\u003Ctd>~10,000\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>トークン転送（2回の外部コール）\u003C\u002Ftd>\u003Ctd>~15,000\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>イベント発行\u003C\u002Ftd>\u003Ctd>~1,500\u003C\u002Ftd>\u003C\u002Ftr>\n\u003Ctr>\u003Ctd>\u003Cstrong>合計\u003C\u002Fstrong>\u003C\u002Ftd>\u003Ctd>\u003Cstrong>~57,500\u003C\u002Fstrong>\u003C\u002Ftd>\u003C\u002Ftr>\n\u003C\u002Ftbody>\u003C\u002Ftable>\n\u003Cp>ガスの約60%がストレージ操作と外部コールに費やされます。\u003C\u002Fp>\n\u003Ch2 id=\"\">まとめ\u003C\u002Fh2>\n\u003Cp>ガス最適化は算術オペコードのマイクロ最適化ではなく、ストレージアクセスと外部コールの最小化です。最もガスを節約するパターンはアーキテクチャ的なものです：ストレージパッキング、キャッシング、calldataの使用、アクセスリストの最適化。\u003C\u002Fp>\n","ja","b0000000-0000-0000-0000-000000000001",true,"2026-03-28T10:44:26.845480Z","EVMガスの精密な内訳：固有ガス、EIP-2929コールド\u002Fウォームアクセス、SSTOREコスト、リファンドメカニクス、最適化パターン。","EVM ガス最適化",null,"index, follow",[21,26,30],{"id":22,"name":23,"slug":24,"created_at":25},"c0000000-0000-0000-0000-000000000016","EVM","evm","2026-03-28T10:44:21.513630Z",{"id":27,"name":28,"slug":29,"created_at":25},"c0000000-0000-0000-0000-000000000020","Gas Optimization","gas-optimization",{"id":31,"name":32,"slug":33,"created_at":25},"c0000000-0000-0000-0000-000000000014","Solidity","solidity","ブロックチェーン",[36,42,48],{"id":37,"title":38,"slug":39,"excerpt":40,"locale":12,"category_name":34,"published_at":41},"d0000000-0000-0000-0000-000000000602","Ethereumインターオペラビリティレイヤー：55以上のL2が一つのチェーンになる方法","ethereum-interoperability-layer-55-l2-hitotsu-no-chain","Ethereumには55以上のLayer 2ロールアップがあり、流動性とユーザー体験が断片化しています。Ethereumインターオペラビリティレイヤー — クロスロールアップメッセージング、共有シーケンサー、ベースドロールアップを組み合わせて — それらを一つのコンポーザブルネットワークに統合することを目指しています。","2026-03-28T10:44:44.721589Z",{"id":43,"title":44,"slug":45,"excerpt":46,"locale":12,"category_name":34,"published_at":47},"d0000000-0000-0000-0000-000000000601","ロールアップを超えるZK証明：Ethereumでの検証可能なAI推論","rollup-wo-koeru-zk-shomei-ethereum-kensho-kanou-ai-suiron","ゼロ知識証明はもはや単なるスケーリングツールではありません。2026年、zkMLはオンチェーンでの検証可能なAI推論を実現し、ZKコプロセッサは重い計算をオフチェーンで実行してオンチェーンで検証し、SP1やJoltなどの新しい証明システムが実用化を推進しています。","2026-03-28T10:44:44.716908Z",{"id":49,"title":50,"slug":51,"excerpt":52,"locale":12,"category_name":34,"published_at":53},"d0000000-0000-0000-0000-000000000578","EIP-7702実践ガイド：Pectra後のスマートアカウントフロー構築","eip-7702-jissen-gaido-pectra-go-sumaato-akaunto-furoo-kouchiku","EIP-7702により、任意のEthereum EOAが単一トランザクション内でスマートコントラクトとして一時的に動作可能になりました。バッチトランザクション、ガススポンサーシップ、ソーシャルリカバリーの実装方法を解説します。","2026-03-28T10:44:43.184719Z",{"id":13,"name":55,"slug":56,"bio":57,"photo_url":18,"linkedin":18,"role":58,"created_at":59,"updated_at":59},"Open Soft Team","open-soft-team","The engineering team at Open Soft, building premium software solutions from Bali, Indonesia.","Engineering Team","2026-03-28T08:31:22.226811Z"]