[EIP3554] マイニングの難易度上昇を意図的に遅らせる提案を理解しよう！

# はじめに

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

https://cryptogames.co.jp/

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

https://cryptospells.jp/

今回は、ShanghaiアップグレードやMergeを実施する目標に向け、難易度爆弾を再調整するか完全に取り除く提案をしている**EIP3554**についてまとめていきます！

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

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

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

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

# 概要

ブロックチェーンの「難易度爆弾（Difficulty Bomb）」の遅延に関する提案です。
難易度爆弾とは、ブロックチェーンの特定のブロック生成アルゴリズムにおいて、時間が経つにつれてマイニングの難易度を意図的に上昇させるメカニズムのことです。
これは、特にイーサリアムのようなブロックチェーンで見られ、ネットワークをより持続可能で安全にし、またプルーフ・オブ・ステーク（Proof of Stake）などの新しいコンセンサスメカニズムへの移行を促進するために設計されています。

ある「`FORK_BLOCK_NUMBER`」というブロック番号から、クライアント（マイニングを行っているコンピューターのこと）は、実際のブロック番号よりも`9,700,000`ブロック遅れているかのように見せかける「**偽のブロック番号**」を基に難易度の計算を行います。
つまり、この変更により、難易度爆弾の効果が実際のブロック数よりも後になるよう調整され、2021年12月の第1週にその効果が表れるようになっています。

このような措置は、通常、ブロックチェーンのアップグレードや更新の一環として行われ、ネットワークの健全性を維持しつつ、新しい技術やアルゴリズムへの移行をスムーズに行うために必要です。
難易度爆弾の遅延は、マイナー（ブロックを生成し、トランザクションを承認するユーザー）にとっても、一時的にマイニングがしやすくなるため、好ましい変更となることがあります。

# 動機

ブロックチェーン、特にイーサリアムのアップグレードについて言及しています。
「**Shanghai upgrade**」とは、イーサリアムネットワークの特定のアップグレードを指します。
また、「**the Merge**」とは、イーサリアムが現在のプルーフ・オブ・ワーク（Proof of Work）コンセンサスメカニズムからプルーフ・オブ・ステーク（Proof of Stake）への移行を完了させるプロセスを指しています。
この移行は、ネットワークのスケーリングやデータ保管効率を大幅に改善し、ネットワークのセキュリティを強化することを目的としています。

2021年12月以前にShanghaiアップグレードやMergeが実施されることを目指しています。
イーサリアム開発チームがこれらの重要なアップグレードを2021年の終わりまでに実行しようとしていることを示しています。
この時期にアップグレードが行われることで、難易度爆弾に関しても変更が必要になります。

難易度爆弾をアップグレード時に再調整するか、完全に取り除きます。
アップグレード時に難易度爆弾の取り扱いをどうするかという選択肢について述べています。
難易度爆弾はマイニングの難易度を時間とともに増加させるため、Mergeが完了してマイニングが必要なくなれば、この難易度爆弾はもはや必要なくなります。
そのため、アップグレードの時にはこの難易度爆弾を再調整するか、あるいは全て取り除くかの選択を迫られることになります。
これは、ネットワークの持続可能性とセキュリティを確保するための重要な判断となります。

# 仕様

ブロックチェーン（特にイーサリアムのような）における難易度調整のための具体的な方法について説明しています。
ここでの目的は、「**難易度爆弾**」の影響を和らげることです。
難易度爆弾は、マイニングの難易度を時間と共に指数関数的に増加させるメカニズムで、ブロックチェーンネットワークをプルーフ・オブ・ステークなどの新しいコンセンサスメカニズムに移行させるための1つの動機付けとして機能します。

提案されている方法では、「`calc_difficulty`」という関数で使われている`block.number`（現在のブロック番号）を変更し、その代わりに`fake_block_number`（偽のブロック番号）を使用します。
この`fake_block_number`は以下の式によって計算されます。

```
fake_block_number = max(0, block.number - 9_700_000) if block.number >= FORK_BLOCK_NUMBER else block.number
```

- `FORK_BLOCK_NUMBER`は、この難易度調整ルールが適用される特定のブロック番号を指します。
- `block.number >= FORK_BLOCK_NUMBER`の条件が満たされる（つまり、現在のブロック番号がこの特定のブロック番号以上である）場合、`block.number`（現在のブロック番号）から`9_700_000`を引いた値を`fake_block_number`として使用します。
    - これにより、難易度爆弾の影響が実質的に`9,700,000`ブロック分遅延されます。
- ただし、引き算の結果がマイナスにならないように`max(0, block.number - 9_700_000)`が使用されています。
    - つまり、計算結果が`0`未満になる場合は`0`を使用します。
- `block.number < FORK_BLOCK_NUMBER`の場合（特定のブロック番号に達していない場合）、難易度計算には通常通り現在のブロック番号が使用されます。

この変更により、難易度爆弾の影響が一時的に和らげられ、マイニングの難易度が予定されていたよりも遅く増加することになります。
これは、ブロックチェーンネットワークが大きなアップグレードやコンセンサスメカニズムの変更に備えるための一時的な措置です。

# 補足

```py
def predict_diff_bomb_effect(current_blknum, current_difficulty, block_adjustment, months):
    '''
    Predicts the effect on block time (as a ratio) in a specified amount of months in the future.
    Vars used in last prediction:
    current_blknum = 12382958
    current_difficulty = 7393633000000000
    block adjustment = 9700000
    months = 6
    '''
    blocks_per_month = (86400 * 30) // 13.3
    future_blknum = current_blknum + blocks_per_month * months
    diff_adjustment = 2 ** ((future_blknum - block_adjustment) // 100000 - 2)
    diff_adjust_coeff = diff_adjustment / current_difficulty * 2048
    return diff_adjust_coeff 


diff_adjust_coeff = predict_diff_bomb_effect(12382958,7393633000000000,9700000,6)

```

上記のコードは、ブロックチェーン（特にイーサリアムのような）における「**難易度爆弾**」の影響を将来予測するためのものです。
難易度爆弾は、マイニングの難易度を時間とともに指数関数的に増加させるメカニズムで、これによってブロック生成時間（ブロックタイム）が長くなる効果があります。
このスクリプトは、特定の将来の時点において、ブロックタイムにどのような影響が出るかを予測します。

関数 `predict_diff_bomb_effect` は、現在のブロック番号、現在の難易度、ブロック調整値（難易度爆弾が調整されるブロック番号）、そして将来予測したい月数を引数に取ります。
関数の中で、まず1か月あたりのブロック数を計算し（`86400`秒 * 30日を平均ブロックタイム13.3秒で割る）、これを使って将来のブロック番号を推定します。
その後、この将来のブロック番号に基づいて難易度調整値を計算し、これを現在の難易度と比較して、ブロックタイムに対する影響の係数（比率）を求めます。

具体的には、`diff_adjustment` は指数関数的に増加する難易度爆弾の効果を模倣する計算で、`future_blknum - block_adjustment` で将来のブロック番号からブロック調整値を引いた後、`100,000`で割ってから`2`を引きます。
その結果の指数（2の累乗）が難易度調整値となります。
この値は現在の難易度に対する比率として計算され、ブロックタイムの変化を表す係数 `diff_adjust_coeff` を求めるために使用されます。

このスクリプトの出力値 `diff_adjust_coeff` は、予測されるブロックタイムの変化を示す比率です。
例えば、この係数が1に近ければブロックタイムに大きな変化はないことを意味し、係数が大きければブロックタイムが大きく増加することを示します。
このスクリプトの説明によれば、2021年12月の最初の週には0.1秒の遅延、月末には1秒の遅延が予測されており、難易度爆弾の効果が顕著になりつつあるが、まだ対応できる余地があるという状況を示しています。

# 互換性

互換性の問題は特にありません。

# セキュリティ

ブロックチェーン（特にイーサリアムなど）における「**難易度**」の誤算と、それがブロック生成時間（ブロックタイム）に及ぼす影響について説明しています。
難易度とは、ブロックをマイニングする時に必要とされる計算量のことで、この値が高いほど新しいブロックを生成するのが難しくなります。

「**難易度の誤算**」とは、難易度の予想外の変化が予測よりも長いブロックタイムを引き起こすことを意味します。
これは、ハードフォーク（大規模なアップデートや修正を伴うブロックチェーンの分岐）がリリースされるまで続く可能性があります。
難易度が急激に変動する（「**Wild shifts in difficulty**」）と、ブロックタイムに大きな影響を与え、ネットワークの使い勝手に悪影響を及ぼすことがあります。

また、難易度の長期的な調整によるブロックタイムの徐々な変化も、難易度爆弾のタイミング（「**difficulty bomb epochs**」）に影響を与えることがあります。
難易度爆弾は、あらかじめ設定されたブロック番号に到達すると、難易度を指数関数的に増加させるメカニズムです。
この爆弾が作動すると、マイニングの難易度が急激に高まり、ブロックタイムが大幅に延びることになります。

このような変化は、ネットワークの使い勝手に影響を与える可能性がありますが、セキュリティ上の問題にはなりにくいとされています。
ブロックタイムの延長はトランザクションの処理遅延などの不便をもたらす可能性がありますが、ブロックチェーンの基本的なセキュリティ機能には影響を与えないためです。
それでも、ユーザー体験に影響を及ぼすため、開発者は難易度の調整に注意を払い、必要に応じてハードフォークなどの措置を講じる必要があります。

# 引用

James Hancock (@madeoftin), "EIP-3554: Difficulty Bomb Delay to December 2021," Ethereum Improvement Proposals, no. 3554, May 2021. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-3554.

# 最後に

今回は「ShanghaiアップグレードやMergeを実施する目標に向け、難易度爆弾を再調整するか完全に取り除く提案をしている**EIP3554**」についてまとめてきました！
いかがだったでしょうか？

質問などがある方は以下の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