[EIP3529] ガス代の返金を削減する提案を理解しよう！

# はじめに

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

https://cryptogames.co.jp/

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

https://cryptospells.jp/

今回は、`SELFDESTRUCT`によるガスリファンドの削除と、`SSTORE`操作によるガスリファンドを低減させる提案をしている**EIP3529**についてまとめていきます！

:::note info
以下にまとめられているものを翻訳・要約・補足しながらまとめていきます。
:::

https://eips.ethereum.org/EIPS/eip-3529

他にも様々なEIPについてまとめています。

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

# 概要

Ethereumのブロックチェーンでは、トランザクションを処理するために「**ガス**」と呼ばれる単位が使われます。
トランザクションにはさまざまな種類があり、それぞれ異なる量のガスを消費します。
ガスは、トランザクションを実行するために必要な計算資源の量を表しています。

「`SELFDESTRUCT`」と「`SSTORE`」は、Ethereumのスマートコントラクトで使える操作の一部です。

**SELFDESTRUCT** は、スマートコントラクトを破棄するために使われる操作です。
この操作を行うと、コントラクトに残っているEtherが指定したアドレスに送られ、コントラクトはブロックチェーンから削除されます。
`SELFDESTRUCT`を使うと、ガスの返金（ガスリファンド）があります。
これは、ブロックチェーンの状態を簡素化することでネットワーク全体の負担を減らすことを奨励するためです。

**SSTORE** は、スマートコントラクトのストレージを更新するために使われる操作です。
この操作も特定の状況下でガスの返金を受けることができます。
特に、ストレージの値をゼロに設定する（つまり、データを削除する）ことで、リファンドを受けることが可能です。

提案されている変更は、`SELFDESTRUCT`によるガスの返金を完全に取り除き、`SSTORE`による返金を減らすというものです。
ただし、`SSTORE`の返金はまだかなりの量になるように設定されていますが、現在のメカニズムを利用した「**悪用**」が行えない程度には減らされます。

この変更の目的は、ガスリファンドメカニズムを利用した特定の戦略（例えば、ガスの価格が高いときにコントラクトを大量に破棄してガスを節約するなど）を防ぐことです。
これらの戦略は、一部のユーザーにとってはコスト削減になるかもしれませんが、ネットワーク全体のセキュリティや効率性に悪影響を与える可能性があります。

つまり、提案はEthereumネットワークの健全性を保つために、ガスリファンドポリシーを調整しようとするものです。

# 動機

ガスリファンド機構は、開発者が必要ないと判断したストレージスロットやコントラクトをクリアすることで「**良い状態衛生**」を実践するよう動機付けるために導入されました。
しかし、この技術の利点は予想よりもはるかに低く、ガスリファンドは予期しない悪い結果をいくつか引き起こしました。

:::note info
プログラムにおける「good state hygiene（良い状態衛生）」は、プログラムの状態を適切に管理し、不要になったデータやリソースを適時にクリアすることで、メモリの無駄遣いを避け、パフォーマンスを向上させることを指します。

### 不要なデータの削除
プログラム内で不要になった変数やオブジェクトを適切に削除することで、メモリリークを防ぎ、メモリ使用量を最適化します。

### リソースの適切な解放
ファイルやデータベース接続など、システムリソースを使用した後は、それらを適切に閉じてリソースを解放します。
これにより、リソースリークを防ぎ、システムの安定性を保ちます。

### キャッシュの効率的な利用
必要なデータのキャッシュを効率的に管理し、過剰なキャッシュがシステムのパフォーマンスを低下させないようにします。

### 状態の明確な管理
プログラムの状態（変数やオブジェクトの現在の値）を明確に管理し、不整合や予期せぬ挙動を避けます。

### メモリ管理のベストプラクティスの適用
ガーベジコレクション言語では、不要なオブジェクトへの参照を保持しないことで、ガーベジコレクタが効率的に動作するようにします。
C/C++のような手動でメモリを管理する言語では、割り当てられたメモリを適切に解放することが重要です。

良い状態衛生を実践することで、プログラムはより効率的に動作し、リソースの無駄遣いを避けることができます。
特に、長時間実行されるアプリケーションや大規模なシステムでは、良い状態衛生がシステムの安定性とパフォーマンスに直結します。
:::

## ガスリファンドによる問題点

### GasTokenの出現
**GasToken**は、低料金期間から高料金期間へのガス使用量を移動することでメリットを提供しますが、ネットワークに対しては特に問題があります。
具体的には、ステートスロットがガスを「**蓄える**」ための「**バッテリー**」として実質的に使用されるため、ステートサイズを悪化させ、ブロックチェーンのガス使用を非効率的にふさいでしまいます。

:::note info
**GasToken**というのは、Ethereumのようなブロックチェーンネットワーク上で、ガスのコストを効率化するために考案された仕組みです。
ガスはEthereumネットワークでトランザクションを処理するために必要な料金の単位で、ネットワークの混雑状況によって価格が変動します。

### GasTokenの仕組み
- **低料金期間に「貯蔵」**
    - **GasToken**は、ガスの価格が比較的低い時に、スマートコントラクトに特定の操作（例えば、ストレージを使用する操作）を行わせることで「**生成**」されます。
    - これは、ステートスロット（ブロックチェーンのデータを保存する場所）を占有することにより、ガスを「**蓄える**」ようなものです。
- **高料金期間に「使用」**
    - 後にガスの価格が上昇した時、これらのスマートコントラクトを「**消費**」または「**破棄**」することで、その時の高いガス価格に対してリファンド（返金）を受けることができます。
    - このリファンドは、低料金期間に支払ったガス代よりも高くなることがあり、これによりガスコストの節約が可能になります。

### 問題点
- **ステートサイズの増大**
    - **GasToken**が生成される過程で多くのステートスロットが使用されるため、ブロックチェーンの全体的な「**状態**」のサイズが増大します。
    - これは、ネットワークのパフォーマンスに悪影響を及ぼし、データの同期や処理が遅くなる原因となります。
- **ガスの使用が非効率に**
    - 本来、ブロックチェーンのガスは、トランザクションを効率的に処理するためのリソースとして設計されています。
    - しかし、**GasToken**による「**蓄積**」と「**消費**」のプロセスは、このシステムを回避し、ガスの利用を非効率的にします。
    - これは、特に高料金期間に、他のユーザーのトランザクション処理に影響を及ぼす可能性があります。

**GasToken**は一見、個々のユーザーにとってはガスコストの節約というメリットがあるものの、ブロックチェーンネットワーク全体の効率性とパフォーマンスに悪影響を及ぼす可能性があるという問題点があります。
:::

### ブロックサイズの変動の増加
リファンドにより、理論上、ブロックで実際に消費されるガスの最大量が公式に定められたガスリミットのほぼ2倍になります（リファンドによってトランザクションのガス使用量の50%までが補填され、ブロック内の後続のトランザクションのためのガススペースが追加されるため）。
これは致命的ではありませんが、特に**EIP1559**では2倍の使用量のスパイクを遥かに長く維持するためにリファンドを使用できるため、望ましくありません。

:::note info
「**on-paper gas limit**」という表現は、ブロックチェーンにおける理論上または公式に定められた、一つのブロックに含めることができるガスの最大量を指しています。
これは、ブロックチェーンのプロトコルや仕様によって定められ、ネットワークの安定性やセキュリティを保つために設定されています。

Ethereumのようなブロックチェーンでは、各ブロックに含めることができるトランザクションの量や計算量は、そのブロックのガスリミットによって制限されます。
このガスリミットは「**on-paper**」として公表されている値であり、ネットワークのノード間で合意されています。

しかし、ガスのリファンドメカニズムが存在するため、実際にはこの「**on-paper**」のガスリミットを超えて、ブロック内で消費されるガスの量が増加することがあります。
リファンドは、特定の条件下でトランザクションが実行された時に、使用されたガスの一部が返金される仕組みです。
このため、ブロック内での実際のガス使用量が理論上のガスリミットの約2倍まで増加する可能性がありますが、返金されるガスはトランザクションごとの使用ガスの50%に制限されています。

このようなメカニズムは、ブロックサイズの変動性を増加させ、特定の状況下でネットワークの予測可能性や安定性に影響を与えることがあります。
:::

## まとめ
ガスリファンド機構は、Ethereumネットワークにとっていくつかの否定的な副作用をもたらしました。
これには、ネットワークのステートサイズの増加やブロックサイズの変動の増加が含まれます。
これらの問題を解決するために、`SELFDESTRUCT`のリファンドを削除し、`SSTORE`のリファンドを減らすことが提案されています。
これは、現在のリファンドメカニズムを利用した「**悪用**」が行われないようにするためです。

# 仕様

| パラメータ               | 値  |
|---------------------|----|
| FORK_BLOCK         | TBD |
| MAX_REFUND_QUOTIENT | 5  |

ブロック番号が `FORK_BLOCK` 以上の場合、以下の変更が適用されます。

- **SELFDESTRUCTのリファンドを削除**。
- **SSTORE_CLEARS_SCHEDULEの置き換え**
    - **EIP2200**で定義されている`SSTORE_CLEARS_SCHEDULE`を`SSTORE_RESET_GAS + ACCESS_LIST_STORAGE_KEY_COST`（**EIP2929**と**EIP2930**によると`4,800`ガス）に置き換えます。

:::note info
**EIP2929**については以下の記事を参考にしてください。
:::

https://qiita.com/cardene/items/ca94d8fd0159bb3cc9fb

:::note info
**EIP2930**については以下の記事を参考にしてください。
:::

https://qiita.com/cardene/items/632180dfb44d66344e70

- **トランザクション後の最大ガスリファンドの削減**
    - トランザクション後に返金される最大ガスを`gas_used // MAX_REFUND_QUOTIENT`に減少させます。
    - 以前は`gas_used // 2`でしたが、`MAX_REFUND_QUOTIENT`という定数を導入し、その値を`5`に変更します。

- **FORK_BLOCK**
    - この変更が適用されるブロック番号はまだ未定です。
    - これは、提案が実装されるタイミングを指します。
- **MAX_REFUND_QUOTIENTの変更**
    - トランザクションで使用されたガスに対する最大リファンド量が変更されます。
    - 以前は使用されたガスの半分までがリファンドされる可能性がありましたが、提案ではこれを使用ガスの5分の1に制限します。
    - これは、ガスのリファンド量を減らし、ブロック内でのガスの使用量をより予測可能にするためです。
- **SELFDESTRUCTのリファンド削除**
    - スマートコントラクトが自己破棄する際のガスリファンドが削除されます。
    - これは、ネットワーク上での悪用を防ぐための措置です。
- **SSTORE_CLEARS_SCHEDULEの置き換え**
    - ストレージの値をクリアするためのガスリファンドの計算方法が変更されます。
    - 新しい計算方法では、ストレージの値をリセットする際の基本ガス料金と、アクセスリストにストレージキーを追加するコストを合算したものが使用されます。

これらの変更は、Ethereumネットワークの効率とセキュリティを向上させ、ガスの使用量をより適切に管理することを目的としています。
特に、リファンドの削減は、ガスの節約戦略としてのガストークンの使用を減少させることを意図しています。

# 補足

**EIP2200**は、Ethereumのガスリファンドに関する改良を提案したEthereum Improvement Proposal（イーサリアム改善提案）です。
このEIPでは、スマートコントラクトのストレージを変更する際に、3つの特定のケースでガスリファンドが発生するようになりました。

## 3つのケースについて

### 元の値が非ゼロで新しい値がゼロの場合
このケースでは、ストレージスロットをクリアすることで、`SSTORE_CLEARS_SCHEDULE`（現在は`15,000`ガス）がリファンドカウンターに追加されます。
これは、ステートの簡素化を奨励するためです。

### 元の値がゼロで、現在の値が非ゼロ、そして新しい値がゼロの場合
この場合は、`SSTORE_SET_GAS - SLOAD_GAS`（現在は`19,900`ガス）がリファンドカウンターに追加されます。
しかし、このケースではガストークンを生み出すことはできません。
なぜなら、`19,900`ガスのリファンドを得るためには、同じストレージスロットを以前にゼロから非ゼロに変更する必要があり、そのコストは`20,000`ガスです。
つまり、リファンドを得るためには、それ以上のガスを先に使う必要があります。

### 元の値が非ゼロで、現在の値が異なる非ゼロの値、そして新しい値が元の値と同じ場合
このケースでは、`SSTORE_RESET_GAS - SLOAD_GAS`（現在は`4,900`ガス）がリファンドカウンターに追加されます。
この場合も、リファンドを得るためには、以前に同じストレージスロットに`5,000`ガスを使っている必要があります。

## EIPの焦点
このEIPは特にケース1に焦点を当てています。
ケース1では、非ゼロの値を持つストレージスロットをゼロに変更することでガストークンが生成される可能性があります。
これにより、ブロックがブロックガスリミット以上のガスを消費することが可能になる場合があります。

## EIPの目的
このEIPの目的は、ガストークンが「**非実行可能**」になる条件を確立することです。
つまり、ストレージスロットから投入したガスよりも多くのガスを取り出すことができないようにすることです。
これは、各リファンドを、同じトランザクション内の同じストレージスロットにおける以前の支出と「**ペアリング**」することによって達成されます。

## 解決策
ストレージスロットに費やされた合計ガスが必ず正であることを保証するために、`SSTORE_CLEARS_SCHEDULE`は`SSTORE_RESET_GAS + ACCESS_LIST_STORAGE_KEY_COST`以下でなければなりません。
このEIPでは、`SSTORE_CLEARS_SCHEDULE`をこれら2つのコストの合計に減少させることを提案しています。

## 結論
このEIPによって、未読の（おそらく「無用」な）データのクリアにはネットリファンドがなくなりますが、読まれた（おそらく「有用」な）データのクリアには引き続きネットリファンドが存在するようになります。これにより、ブロックチェーンの効率とパフォーマンスが向上することが期待されます。

:::note info
このEIP（Ethereum Improvement Proposal）による変更の目的は、Ethereumネットワークの効率を高めることにあります。
スマートコントラクト内の「**無用**」なデータと「**有用**」なデータの扱いを区別し、それに応じてガスのリファンド（返金）のルールを変更します。

### 「無用」なデータとは？
「**無用**」なデータとは、スマートコントラクトの実行において読み込まれることがない、または将来的に利用される可能性が低い情報のことです。
例えば、一時的に使用されるが、その後は不要となる変数や、過去のトランザクションから残された、もはや関連性のない情報などがこれに該当します。
このようなデータをブロックチェーン上からクリア（削除）する時には、EIPによる変更後は追加のガスリファンドが得られなくなります。
これにより、開発者は不要なデータを保持することによるコストを意識するようになり、ブロックチェーンの状態をより効率的に保つことが奨励されます。

### 「有用」なデータとは？
一方で「**有用**」なデータは、スマートコントラクトの実行過程で読み込まれ、何らかの形で利用される情報を指します。
このようなデータは、コントラクトのロジックや状態の管理に直接関わっており、その価値が認められるものです。
有用なデータをクリアする場合は、ブロックチェーンの効率を高める行為とみなされ、引き続きガスリファンドが提供されます。
これにより、有用なデータの管理と更新が奨励され、ブロックチェーンの有効利用が促進されます。

### 効果
この変更により、Ethereumネットワーク上でのデータ管理がより合理的になり、ブロックチェーンのパフォーマンスと効率が向上することが期待されます。
無用なデータの削除に対するインセンティブが減少することで、開発者は本当に必要なデータのみをブロックチェーン上に残すようになり、結果的に全体のステートサイズが最適化されます。
同時に、有用なデータの適切な管理と更新に対するリファンドが維持されることで、スマートコントラクトの効率的な運用が支援されます。
:::

# 互換性

Ethereumのトランザクション実行におけるガスリファンド（返金）のメカニズムと、その変更がいくつかのアプリケーションや機能にどのような影響を与えるかについて説明しています。

### ガスリファンドの現状
ガスリファンドはトランザクションの実行後にのみ適用されるため、実行中の特定のコールフレームで利用可能なガス量に影響を与えることはありません。
このため、リファンドを削除してもコードの実行能力自体は損なわれませんが、一部のアプリケーションが経済的に成り立たなくなる可能性があります。

### ガストークンの影響
ガストークンは、トランザクションのガスコストを削減するために使用されている仕組みです。
しかし、リファンドメカニズムの変更により、これらのガストークンは価値を失います。
その結果、DeFi（分散型金融）のアービトラージボットなど、ガストークンを利用してオンチェーンコストを削減しているユーザーは、これらの機能がもはや機能しないため、コードを書き換えることが望ましいです。

### 特定のユースケースへの影響
「**新しい = オリジナル = 現在0ではない（`new = original = 0 != current`）**」のケースでリファンドを完全に維持し、非ゼロからゼロへの他のケースでも一部のリファンドを保持することで、特定の重要なユースケースが引き続き好ましいガスコスト処理を受けることが保証されます。
例えば、「ゼロ→非ゼロ→ゼロ」というストレージ設定パターンは、引き続き約`100`ガスのみを消費します。
このパターンには以下のような重要な例が含まれます。
    - **アンチリエントラシーロック**
        - 子コールが開始する直前に0から1に切り替えられ、子コールが終了すると再び0に戻されます。
    - **ERC20の承認と送信**
        - トークン転送が承認されると「**承認された値**」がゼロから非ゼロになり、トークン転送が処理されると再びゼロに戻ります。

これらの変更により、Ethereumのガスコストとリファンドポリシーがより効率的かつ公平になることが期待されています。

:::note info
「**新しい = オリジナル = 現在0ではない（`new = original = 0 != current`）**」という表現は、Ethereumのスマートコントラクトにおける特定のストレージ操作の状況を指しています。

- **オリジナル**
    - ストレージスロットの値がトランザクション実行前に持っていた値。
- **現在**
    - トランザクション実行中にスロットが持っている値（トランザクションの中で値が変更された後の値）。
- **新しい**
    - トランザクションの結果としてスロットに設定される値。

「**新しい = オリジナル = 現在0ではない（`new = original = 0 != current`）**」というのは、トランザクションの終わりにおいて、スロットの「**新しい**」値が「**オリジナル**」の値に戻り、その間に「**現在**」の値が一時的に0以外の値になっていた状況を指します。
具体的には、以下の3つの条件が該当します。

1. **オリジナルの値**が特定の値（たとえばX）である。
2. トランザクションの実行中に、このスロットの値が0以外の値（たとえばY）に一時的に変更される（**現在の値**）。
3. トランザクションの終わりにスロットの値が「**オリジナル**」と同じ値（X）に戻る（**新しい値**）。

この状況では、スロットの値が最終的にはトランザクション実行前と同じになるため、変更が「**無かった**」ことになります。
しかし、トランザクション実行中にスロットの値が変更されたという事実に基づき、一定のガスリファンドが認められることがあります。
これは、スマートコントラクトの実行効率を高め、不必要なストレージの変更を避けるインセンティブを提供するためです。

このようなリファンドポリシーは、例えばアンチリエントラシーロックや**ERC20**のapprove-and-sendパターンなど、一時的な値の変更が必要とされる重要なユースケースをサポートするために重要です。
これらの操作では、セキュリティやトークンの転送ロジックを正しく実行するために、値の一時的な変更が頻繁に行われます。
:::

## ストレージ清算インセンティブへの影響

Ethereum Improvement Proposals（EIP）におけるガスリファンドの変更がストレージ（スマートコントラクトのデータ保存領域）のクリア動機に与える影響について述べています。

### ストレージクリアのインセンティブ
以前のEIP（**EIP3298**や**EIP3403**など）では、ストレージスロット（スマートコントラクトにおけるデータ保存場所）の値をゼロに設定する動機付けが完全に取り除かれることが批判されていました。
その結果、ユーザーが将来そのストレージスロットを再利用する可能性がわずかでもある場合、スロットを完全にクリアするインセンティブが低下します。

### 具体例
**ERC20**トークンを1単位持っていて、それを全て譲渡または販売する場合、`0.999999`単位を譲渡してわずかに残すことができます。
将来同じアカウントでそのトークンを再度取得することになった場合、ゼロから非ゼロへの設定に必要なガスは`20,100`ガスではなく、非ゼロから非ゼロへの変更であれば`5,000`ガス（読み込みに`2,100`ガス+非ゼロから非ゼロへの設定に`2,900`ガス）で済みます。
現在は、クリアに対して`15,000`ガスのリファンドがあるため、この行動にインセンティブが生まれるのは、スロットを再利用する確率が87.7%以上である場合のみです。
**EIP3298**や**EIP3403**では、このバランスを取るインセンティブが存在しないため、スロットを再利用する確率が0%より大きければ非ゼロに設定する方が有利になります。

### 新しい提案の影響
提案されている変更により、`4,800`ガスのリファンドが残ります。
これは、スロットを非ゼロに保つインセンティブが、スロットを再利用する確率が28.1%以上である場合にのみ生じることを意味します。
これは完璧ではありませんが、トークンの全残高をクリアした場合に、同じアドレスで後にトークンを再取得することの期待値よりも高い可能性があります。

### リファンドの上限
また、使用したガスの5分の1にリファンドを制限することで、リファンドを利用してブロックを処理するために必要なストレージ書き込み操作の量を最大25%しか増やすことができなくなります。
これにより、ストレージ書き込みに焦点を当てたDoS攻撃（サービス拒否攻撃）の能力が制限されます。

要するに、このEIPによって、ストレージスロットのクリアに対するインセンティブが調整され、ブロックチェーンの効率とセキュリティが向上することが期待されます。

# テスト

## EIP-2929 ガス料金

**EIP2929**はEthereumのガスコストに関する変更を行う提案で、特に「**ホット**」と「**コールド**」のストレージスロットの扱いに焦点を当てています。
ここでの「**ホット**」スロットとは、トランザクション実行中に既にアクセスされた（触れられた）ストレージスロットを指し、「**コールド**」スロットはまだアクセスされていないスロットを指します。
**EIP2929**は、コールドスロットに初めてアクセスした際のガスコストを増加させることで、スマートコントラクトの実行時のリソース使用量をより正確に反映させることを目的としています。

以下の表は、**EIP2929**の下で、すべてのストレージスロットが既に「**ホット**」であると仮定した場合のガス消費量を示しています。
以下の表中の「オリジナル」「**1回目**」「**2回目**」「**3回目**」は、ストレージスロットが変更される回数を示し、「**実質ガス（リファンド後）**」はリファンドを考慮した後の実質的なガス消費量です。


| コード                            | 使用ガス | リファンド | オリジナル | 1回目 | 2回目 | 3回目 | 実質ガス（リファンド後） |
|-----------------------------------|---------|-----------|------------|-------|-------|-------|-----------------------|
| `0x60006000556000600055`            | 212     | 0         | 0          | 0     | 0     |       | 212                   |
| `0x60006000556001600055`            | 20,112  | 0         | 0          | 0     | 1     |       | 20,112                |
| `0x60016000556000600055`            | 20,112  | 19,900    | 0          | 1     | 0     |       | 212                   |
| `0x60016000556002600055`            | 20,112  | 0         | 0          | 1     | 2     |       | 20,112                |
| `0x60016000556001600055`            | 20,112  | 0         | 0          | 1     | 1     |       | 20,112                |
| `0x60006000556000600055`            | 3,012   | 15,000    | 1          | 0     | 0     |       | -11,988               |
| `0x60006000556001600055`            | 3,012   | 2,800     | 1          | 0     | 1     |       | 212                   |
| `0x60006000556002600055`            | 3,012   | 0         | 1          | 0     | 2     |       | 3,012                 |
| `0x60026000556000600055`            | 3,012   | 15,000    | 1          | 2     | 0     |       | -11,988               |
| `0x60026000556003600055`            | 3,012   | 0         | 1          | 2     | 3     |       | 3,012                 |
| `0x60026000556001600055`            | 3,012   | 2,800     | 1          | 2     | 1     |       | 212                   |
| `0x60026000556002600055`            | 3,012   | 0         | 1          | 2     | 2     |       | 3,012                 |
| `0x60016000556000600055`            | 3,012   | 15,000    | 1          | 1     | 0     |       | -11,988               |
| `0x60016000556002600055`            | 212 | 0 | 1 | 1 | 1 | 212 |
| `0x60016000556001600055`	| 212	| 0	| 1	| 1	| 1	 	| 212| 
| `0x600160005560006000556001600055`	| 40118	| 19900	| 0	| 1	| 0	| 1	| 20218 | 
| `0x600060005560016000556000600055`	| 5918	| 17800	| 1	| 0	| 1	| 0	| -11882 | 

## 減額分払い戻し

リファンドが部分的に削減された場合の比較表を以下に示します。
この表は、`SSTORE_CLEARS_SCHEDULE`を`15,000`ガスから`4,800`ガスに変更し、さらに`selfdestruct`のリファンドを削除した状況を想定しています。

| コード                                   | 使用ガス | リファンド | オリジナル | 1回目 | 2回目 | 3回目 | 実質ガス（リファンド後） |
|------------------------------------------|---------|-----------|------------|-------|-------|-------|------------------------|
| `0x60006000556000600055`                 | 212     | 0         | 0          | 0     | 0     |       | 212                    |
| `0x60006000556001600055`                 | 20,112  | 0         | 0          | 0     | 1     |       | 20,112                 |
| `0x60016000556000600055`                 | 20,112  | 19,900    | 0          | 1     | 0     |       | 212                    |
| `0x60016000556002600055`                 | 20,112  | 0         | 0          | 1     | 2     |       | 20,112                 |
| `0x60016000556001600055`                 | 20,112  | 0         | 0          | 1     | 1     |       | 20,112                 |
| `0x60006000556000600055`                 | 3,012   | 4,800     | 1          | 0     | 0     |       | -788                   |
| `0x60006000556001600055`                 | 3,012   | 2,800     | 1          | 0     | 1     |       | 212                    |
| `0x60006000556002600055`                 | 3,012   | 0         | 1          | 0     | 2     |       | 3,012                  |
| `0x60026000556000600055`                 | 3,012   | 4,800     | 1          | 2     | 0     |       | -788                   |
| `0x60026000556003600055`                 | 3,012   | 0         | 1          | 2     | 3     |       | 3,012                  |
| `0x60026000556001600055`                 | 3,012   | 2,800     | 1          | 2     | 1     |       | 212                    |
| `0x60026000556002600055`                 | 3,012   | 0         | 1          | 2     | 2     |       | 3,012                  |
| `0x60016000556000600055`                 | 3,012   | 4,800     | 1          | 1     | 0     |       | -788                   |
| `0x60016000556002600055`                 | 3,012   | 0         | 1          | 1     | 2     |       | 3,012                  |
| `0x60016000556001600055`                 | 212     | 0         | 1          | 1     | 1     |       | 212                    |
| `0x600160005560006000556001600055`       | 40,118  | 19,900    | 0          | 1     | 0     | 1     | 20,218                 |
| `0x600060005560016000556000600055`       | 5,918   | 7,600     | 1          | 0     | 1     | 0     | -1,682                 |

- **使用ガス**
    - トランザクション実行にかかった総ガス量です。
- **リファンド**
    - トランザクション実行後に戻されるガス量です。
- **オリジナル、1回目、2回目、3回目**
    - ストレージスロットの変更回数を表しています。
- **実質ガス（リファンド後）**
    - 使用ガスからリファンドを差し引いた後の実質的なガス消費量です。

この表からわかる主な変更点は、`SSTORE_CLEARS_SCHEDULE`のリファンドが`15,000`から`4,800`に削減されたこと、及び`selfdestruct`のリファンドが完全に削除されたことです。
これにより、特定の操作で得られるリファンドが減少し、実質的なガス消費量が増加しています。
例えば、`0x60006000556000600055`のコードの場合、リファンド後の実質ガスは以前はマイナス値（つまり、リファンドがガス消費量を上回る）でしたが、リファンド削減後はプラスの値になっています。

この変更は、特にガストークンのようにリファンドメカニズムを利用するアプリケーションに影響を与え、その経済的な実行可能性を変える可能性があります。

# セキュリティ

Ethereumのトランザクション実行とブロックのガス消費に関する仕組みについてです。

### トランザクション実行とリファンド
トランザクション実行中にリファンド（ガスの返金）が発生しても、それはトランザクションのロジックには影響しません。
つまり、リファンドはトランザクションが完了した後にのみ計算され、実行中の処理には直接関与しません。

### ブロックのガス消費制限
1つのブロックで実行されるトランザクションによるガス消費量の上限はブロックガスリミットによって設定されています。
ただし、値がゼロから非ゼロに変更された後、再びゼロに戻された`SSTORE`操作（ストレージの保存操作）はこの計算に含めないことができます。

### `SSTORE`操作とストレージの最適化
もし`SSTORE`操作で値が最初の値に戻される（つまり、新しい値がオリジナルの値と同じである）場合、実際にはストレージが拡張されないため、Merkleツリー（ブロックチェーンのデータ構造の一種）の調整は必要ありません。
この場合、消費されたガスはリファンドされますが、クライアント（Ethereumネットワークを構成するノード）がその操作を処理するために通常必要とされる労力もキャンセルされます。

### ストレージ書き込みの最適化
クライアントは、新しい値がオリジナルの値と同じ場合にはストレージ書き込みを行わないようにするべきです。
これはEthereumの初期から賢明な最適化とされていましたが、現在ではさらに重要になっています。
これにより、不必要なストレージ操作を避けて効率を高めることができます。

この説明から、Ethereumのトランザクション処理とブロック生成の効率を最適化するための仕組みとその重要性が理解できます。
特に、ガスの使用とリファンドのメカニズムは、ネットワーク全体のパフォーマンスに大きな影響を与えるため、これらの最適化は非常に重要です。

# 引用

Vitalik Buterin (@vbuterin), Martin Swende (@holiman), "EIP-3529: Reduction in refunds," Ethereum Improvement Proposals, no. 3529, April 2021. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-3529.

# 最後に

今回は「`SELFDESTRUCT`によるガスリファンドの削除と、`SSTORE`操作によるガスリファンドを低減させる提案をしている**EIP3529**」についてまとめてきました！
いかがだったでしょうか？

質問などがある方は以下のTwitterのDMなどからお気軽に質問してください！

[Twitter @cardene777](https://twitter.com/cardene777)

他の媒体でも情報発信しているのでぜひ他も見ていってください！

https://chaldene.net/

https://zenn.dev/heku

https://mirror.xyz/0xcE77b9fCd390847627c84359fC1Bc02fC78f0e58

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