[EIP4844] Shard Blob Transactionsの仕組みについて理解しよう！

# はじめに

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

https://cryptogames.co.jp/

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

https://cryptospells.jp/

今回は、**blob-carrying transactions**という、Ethereumネットワークにおいて大量のデータを含む新しいトランザクションの仕組みを提案している**EIP4844**についてまとめていきます！

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

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

:::note warn
**4844**は現在（2024年1月20日）では「**Review**」段階です。
:::

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

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

# 概要

「**blob-carrying transactions**」とは、イーサリアムネットワークにおいて、非常に大量のデータを含む新しいタイプのトランザクションを指します。
従来のトランザクションと異なり、これらのトランザクションに含まれるデータは、EVMによって直接処理されることはありません。
しかし、これらのトランザクションが保持するデータの「**コミットメント**」、つまりデータの存在や整合性についての証明は、ネットワーク参加者によって確認することができます。

この新しいフォーマットの重要な特徴は、将来的にイーサリアムが展開する予定の「**完全なシャーディング**」に対応している点です。
シャーディングは、ブロックチェーンネットワークの処理能力を向上させるために、ネットワークを複数の小さな部分に分割し、それぞれの部分でトランザクションを処理する技術です。
このフォーマットは、そうした将来のシャーディング環境においても効率的に機能し、ネットワーク全体のパフォーマンス向上に貢献することを目的としています。

# 動機

現在、イーサリアムのスケーリング（処理能力拡大）において、ロールアップは短期的、中期的、おそらく長期的にも、信頼できる唯一のソリューションと見なされています。
第1層（L1）のトランザクション手数料が非常に高い状況が続いているため、ロールアップへの移行を促進することが急務となっています。
ロールアップ、特にOptimismやArbitrumのようなものは、イーサリアムと比べてかなり低い手数料で取引を提供しており、ZKロールアップなどはさらに低い手数料（基層の約40〜100分の1）を実現しています。

ただし、これらの手数料も多くのユーザーにとっては依然として高額です。
長期的な問題解決策としてデータシャーディングが考えられています。
データシャーディングは、イーサリアムチェーンにブロックごとに約`16MB`の専用データスペースを追加し、ロールアップがこのスペースを利用することを可能にするものです。
しかしこの実装には時間がかかります。

この文脈でのEIPは、シャーディングの完全な実装までの中間的な解決策を提供します。
この提案では、シャーディングで使われるトランザクションフォーマットを実装しますが、トランザクション自体はシャーディングしません。
代わりに、このフォーマットからのデータはビーコンチェーンの一部として存在し、全てのコンセンサスノードがダウンロードしますが、削除は比較的短期間後に可能です。
このEIPは、完全なデータシャーディングに比べて、含まれるトランザクションの数に制限を設けており、ブロック当たり約`0.375MB`を目指し、上限は約0.75MBとされています。

:::note info
### ビーコンチェーン（Beacon Chain）
ビーコンチェーンは、イーサリアム2.0の中核となるブロックチェーンの一部です。
イーサリアムの現行システム（イーサリアム1.0）とは異なり、ビーコンチェーンは「**Proof of Stake**」（**PoS**）というコンセンサスメカニズムを採用しています。
これは、ネットワークのセキュリティと整合性を維持するために「**ステーキング**」（特定の量の暗号通貨を担保として保持すること）に依存する方式です。
ビーコンチェーンの主な役割は、ネットワーク全体のコンセンサス（合意形成）を維持し、ネットワークのアップグレードをスムーズに行うことです。
また、将来的にはイーサリアムのシャーディング（データを小さな断片に分割すること）にも重要な役割を果たす予定です。

**Proof of Stake (PoS) コンセンサスメカニズム**
ビーコンチェーンは、イーサリアムが従来の**Proof of Work (PoW)**から**PoS**に移行するための基盤を提供します。
**PoS**では、マイナー（**PoW**での計算処理を行うノード）ではなく、ステーカー（特定の量の暗号通貨を担保として保持するユーザー）がネットワークのセキュリティと検証プロセスを担います。

**スケーラビリティと効率の向上**
ビーコンチェーンの導入は、イーサリアムネットワークのスケーラビリティを大幅に向上させることを目的としています。
**PoS**は、**PoW**に比べて計算資源とエネルギーの使用量を減少させ、ネットワークの効率を高めます。

**シャーディングの準備**
ビーコンチェーンは将来的にシャーディングをサポートするための基礎を築きます。
シャーディングは、ネットワークを複数の小さな部分（シャード）に分割し、それぞれのシャードが独立して取引とブロックの検証を行うことで、トランザクション処理の能力を高める技術です。

**ネットワークアップグレードの基盤**
ビーコンチェーンはイーサリアム2.0への移行の基礎となり、将来のアップグレードや機能拡張のためのプラットフォームを提供します。

**ステーキングと報酬**
ユーザーは、イーサリアムをステーキングすることでビーコンチェーンに参加し、ネットワークのセキュリティに貢献すると同時に、新しいイーサリアムの生成や手数料による報酬を得ることができます。

**分散化とセキュリティの強化**
**PoS**メカニズムにより、イーサリアムネットワークはより分散化され、セキュリティが強化されます。
これにより、ネットワーク攻撃や中央集権的なコントロールのリスクが減少します。

### コンセンサスノード（Consensus Nodes）
コンセンサスノードは、ブロックチェーンネットワークにおいて重要な役割を果たすコンピューターのノード（端末）です。
これらのノードは、ネットワーク上で行われる取引の検証と記録に責任を持ち、ネットワークのセキュリティと透明性を確保するために必要です。
コンセンサスノードは、ネットワーク上の取引が有効であることを確認し、取引の記録（ブロック）をブロックチェーンに追加するプロセスに参加します。
**PoS**の場合、これらのノードは暗号通貨をステーキングすることでネットワークのセキュリティに貢献し、その見返りとして報酬を受け取ることができます。

上記の文脈で言えば、新しいデータフォーマットがビーコンチェーンに統合され、ネットワークのすべてのコンセンサスノードによってダウンロードされるが、このデータは長期間保存する必要はなく、短期間後に削除できるということを意味しています。
これにより、ネットワークの効率性と管理の容易さが向上します。
:::

# 仕様

## パラメータ

了解しました。指定されたパラメーターをマークダウンのテーブル形式で出力します。


| Parameter                               | Value                                                         |
|-----------------------------------------|---------------------------------------------------------------|
| `BLOB_TX_TYPE`                          | `Bytes1(0x03)`                                                |
| `BYTES_PER_FIELD_ELEMENT`               | `32`                                                          |
| `FIELD_ELEMENTS_PER_BLOB`               | `4096`                                                        |
| `BLS_MODULUS`                           | `52435875175126190479447740508185965837690552500527637822603658699938581184513` |
| `VERSIONED_HASH_VERSION_KZG`            | `Bytes1(0x01)`                                                |
| `POINT_EVALUATION_PRECOMPILE_ADDRESS`   | `Bytes20(0x0A)`                                               |
| `POINT_EVALUATION_PRECOMPILE_GAS`       | `50000`                                                       |
| `MAX_BLOB_GAS_PER_BLOCK`                | `786432`                                                      |
| `TARGET_BLOB_GAS_PER_BLOCK`             | `393216`                                                      |
| `MIN_BLOB_GASPRICE`                     | `1`                                                           |
| `BLOB_GASPRICE_UPDATE_FRACTION`         | `3338477`                                                     |
| `GAS_PER_BLOB`                          | `2**17`                                                       |
| `HASH_OPCODE_BYTE`                      | `Bytes1(0x49)`                                                |
| `HASH_OPCODE_GAS`                       | `3`                                                           |
| `MIN_EPOCHS_FOR_BLOB_SIDECARS_REQUESTS` | `4096`                                                        |

この表は、与えられたパラメーターを整理したもので、各項目の値は「`」で囲まれています。

## エイリアス


| Type            | Base Type                                             | Additional Checks                                             |
|-----------------|-------------------------------------------------------|---------------------------------------------------------------|
| `Blob`          | `ByteVector[BYTES_PER_FIELD_ELEMENT * FIELD_ELEMENTS_PER_BLOB]` |                                                             |
| `VersionedHash` | `Bytes32`                                             |                                                               |
| `KZGCommitment` | `Bytes48`                                             | Perform IETF BLS signature “KeyValidate” check but do allow the identity point |
| `KZGProof`      | `Bytes48`                                             | Same as for `KZGCommitment`                                   |

## Cryptographic Helpers

この改善提案では、[**consensus 4844 specs**](https://github.com/ethereum/consensus-specs/tree/86fb82b221474cc89387fa6436806507b3849d88/specs/deneb)という特定の仕様に基づいて定義された暗号学的方法やクラスが利用されています。
ここでの「**consensus 4844 specs**」とは、ブロックチェーンのセキュリティや性能に関する一連の基準やアルゴリズムを指す可能性があります。

提案において特に使用されるメソッドは、`polynomial-commitments.md`というドキュメントに記載されている2つの関数です。
1. `verify_kzg_proof()`
    - この関数は**KZG（Kate-Zaverucha-Goldberg）**証明の検証を行うもので、ブロックチェーンの取引やデータの正当性を確認する際に使用される可能性があります。
2. `verify_blob_kzg_proof_batch()`
    - この関数もKZG証明の一種を検証するものですが、特に「**バッチ処理**」形式で複数の証明を同時に検証することに特化していると考えられます。

これらの関数は、ブロックチェーンのセキュリティを高めるための重要なツールとして機能し、ブロックチェーンネットワーク上でのデータの整合性と信頼性を保証するために使用されます。

## Helpers

### `kzg_to_versioned_hash`関数

```js
def kzg_to_versioned_hash(commitment: KZGCommitment) -> VersionedHash:
    return VERSIONED_HASH_VERSION_KZG + sha256(commitment)[1:]
```

この関数は、**KZG（Kate-Zaverucha-Goldberg）**コミットメントの暗号ハッシュを生成するために使用されます。
入力された**KZG**コミットメントに対して`SHA256`ハッシュ関数を適用し、その結果の最初のバイトを除いた残りの部分に`VERSIONED_HASH_VERSION_KZG`（バージョンを示す特定の値）を先頭に追加します。
これにより、特定のバージョンのハッシュ値が生成されます。

:::note info
### KZGコミットメント

まず、**KZGコミットメント**とは、ブロックチェーン技術における一種の「**数学的な約束**」です。
これは、ある情報（例えば、取引のデータ）を数学的な方法で処理して、その情報の「**要約**」や「**証明**」を作る技術です。
この技術の目的は、情報が後で変更されていないことを効率的に証明することにあります。

**レシピの共有（from ChatGPT）

あなたは友達に特別なケーキのレシピを教えたいと思っています。
しかし、このレシピは秘密にしたいので、全文をそのまま渡すのではなく、レシピの「**要約**」を渡すことにしました。

1. **KZGコミットメントの作成**
   - あなたはレシピを特定の数学的な方法（KZGコミットメントのアルゴリズム）で処理して、一種の「**要約**」を作ります。
   - この「**要約**」は、元のレシピがどういうものであったかを完全には明かさないものの、レシピが後で変わっていないことを証明できるものです。

2. **友達への共有**
   - この「**要約**」を友達に渡します。
   - 友達は、この「**要約**」を使って、あなたが後でレシピを変更しないことを確認できます。

3. **レシピの確認**
   - 後日、あなたは友達に本当のレシピを見せます。
   - 友達は、そのレシピと最初にもらった「**要約**」を照らし合わせることで、あなたが最初に教えたレシピと同じであることを確認できます。

この例での「**レシピの要約**」がKZGコミットメントに相当します。
つまり、KZGコミットメントは、ブロックチェーンにおいて取引やデータの「**要約**」を作り、そのデータが後で改ざんされていないことを効率的に証明するための方法です。
ブロックチェーンでは、この技術を使って、多くの取引やデータが安全で信頼性が高いことを保証しています。
:::

詳細は全然理解できなかったので、知りたい方は以下の記事などが参考になると思います。

https://zenn.dev/dantehrani/articles/e8882dd72b514e

### `fake_exponential`関数

```js
def fake_exponential(factor: int, numerator: int, denominator: int) -> int:
    i = 1
    output = 0
    numerator_accum = factor * denominator
    while numerator_accum > 0:
        output += numerator_accum
        numerator_accum = (numerator_accum * numerator) // (denominator * i)
        i += 1
    return output // denominator
```

`fake_exponential`関数は、指数関数の近似値を求めるために使用されます。
テイラー展開は、複雑な数学的関数を多項式の和として近似する方法です。
この関数では、与えられた分子と分母を用いて、`e`（自然対数の底）の累乗の近似値を計算します。
ループを使用して項を順次追加し、各ステップで分母とインデックス`i`で値を調整し、最終的な結果を得るために分母で割ります。
この方法は、特に計算資源が限られている環境や高速な計算が必要な場合に有用です。

:::note info
### テイラー展開

テイラー展開を使うと、複雑な関数を多項式の形で近似することができます。
簡単に言うと、テイラー展開は複雑な関数をよりシンプルな形に表す方法です。

基本的なアイデアは以下の通りです。

- **関数を点の周りで近似**
    - テイラー展開は、特定の点（よく「**展開点**」と呼ばれます）の周りで関数を近似します。
    - たとえば、点 $( a )$ の周りで関数 $( f(x) )$ を近似したい場合、その点での関数の値と導関数（微分係数）を使用します。

- **多項式で表現**
    この近似は多項式で表され、その多項式の各項は関数の導関数に基づいています。
    具体的には、関数の値、一階導関数（微分）、二階導関数、三階導関数...などを使用します。

- **テイラー展開の式**
    - 関数 $( f(x) )$ のテイラー展開は以下のように表されます。

```math
f(x) \approx f(a) + f'(a)(x - a) + \frac{f''(a)}{2!}(x - a)^2 + \frac{f'''(a)}{3!}(x - a)^3 + \cdots 
```

ここで $( f'(a) )$、$( f''(a) )$、$( f'''(a) )$ はそれぞれ $( a )$ での一階、二階、三階の導関数です。
$( n! )$（nファクトリアル）は $( n )$ の階乗を意味し、1から $( n )$ までの整数の積です。

- **近似の精度**
    - 多項式の項が多いほど、近似の精度は高くなります。
    - しかし、実際の計算では、無限に続く項をすべて考慮するのは不可能なので、通常は必要な精度に応じて項数を決めます。

テイラー展開は物理学や工学など様々な分野で利用され、複雑な問題を解く際に重要な役割を果たします。
例えば、物理法則をモデル化するときや工学的な計算を行うときに、この方法を使って複雑な関数をより扱いやすい形に変換します。

テイラー展開は、難しい関数を簡単な多項式で近似する方法です。

例えば、ある複雑な山の形をした曲線があります。
この曲線は、数学的な関数で表されていますが、その形は非常に複雑です。
ここで、この山の一点に立っているとします。その点のまわりの小さな範囲では、山はほぼ平らに見えるかもしれません。
その平らな部分を表すのが、テイラー展開の最初の項、つまり関数の値です。

次に、その点から少し離れたところを見ると、山は少しずつ傾いているのがわかります。
この傾きを表すのが、テイラー展開の二番目の項、つまり一階導関数です。

さらに遠くを見ると、山は曲がっているのがわかります。
この曲がり具合を表すのが、テイラー展開の三番目の項、つまり二階導関数です。

このように、テイラー展開では、特定の点の周りで関数を近似し、その点での値（高さ）、傾き、曲がり具合などを多項式で表しています。
そして、この多項式の項を増やせば増やすほど、元の複雑な曲線に近い近似ができるようになります。
:::

## Blob transaction

「**blob transaction**」とは、**EIP2718**フレームワークの下で新しく導入されたトランザクションのタイプです。
このトランザクションは、通常のイーサリアムトランザクションと異なり、特定のデータ構造を持っています。

### TransactionPayload

```
[chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, to, value, data, access_list, max_fee_per_blob_gas, blob_versioned_hashes, y_parity, r, s]
```

このペイロードは、一連の要素（`chain_id`、`nonce`、`max_priority_fee_per_gas`など）を含むリストとして**RLP（Recursive Length Prefix）** 形式でシリアライズされます。
これらの要素の多くは、**EIP1559**（イーサリアムガス代の改善を目的とした提案）で導入されたフィールドと同じ意味を持ちます。

:::note info
### RLP
**RLP（Recursive Length Prefix）**　形式は、イーサリアムブロックチェーンでデータをエンコードする方法です。
このエンコード方式は、任意のバイナリデータ（数値、文字列、リストなど）を、一貫性のある形式に変換し、ブロックチェーンが理解できるようにします。

**RLPエンコードの基本**

**RLP**エンコードでは、データの種類とサイズに基づいて、エンコードの方法が決まります。
簡単なデータ（例えば、小さな数値や短い文字列）は直接エンコードされますが、複雑なデータ（リストや長い文字列など）は、その長さと内容に基づいてエンコードされます。

**具体例: 文字列とリストのエンコード**

- **文字列のエンコード**

例えば、文字列 "dog" を**RLP**エンコードする場合を考えます。
"dog" は単純な文字列なので、以下のステップでエンコードされます。

1. 文字列の長さを計算します（"dog" は3文字）。
2. 長さに基づいて、適切なプレフィックスを決定します（通常、長さが`55`文字未満の場合、長さに`128`を加えた値がプレフィックスになります。
    - "dog"の場合、プレフィックスは` 128 + 3 = 131`、または`16`進数で `0x83`）。
3. プレフィックスに続けて元のデータを配置します。
    - したがって、"dog" の**RLP**エンコードは `0x83646f67` となります。

- **リストのエンコード**

次に、["cat", "dog"] という文字列のリストをエンコードする場合を考えます。

1. まず、各要素を個別にエンコードします。
    - "cat" は `0x83636174`、"dog" は `0x83646f67` となります。
2. 次に、これらのエンコードされた要素を結合します。
    - これにより、`0x8363617483646f67` が得られます。
3. 最後に、全体の長さ（この場合は8バイト）に基づいてプレフィックスを計算し、これをエンコードの先頭に追加します。
    - `8`バイトのため、プレフィックスは `192 + 8 = 200`、または`16`進数で `0xC8` です。
4. 結果として、["cat", "dog"] の**RLP**エンコードは `0xC88363617483646f67` となります。

**まとめ**

**RLP**エンコードは、イーサリアムブロックチェーンにおいてデータを統一的かつ効率的に表現するために使用されます。
単純なデータはその長さと内容に基づいて直接エンコードされ、複雑なデータ（特にリスト）は再帰的にエンコードされます。
この方法により、ブロックチェーン上でのデータの取り扱いが一貫性を持ち、効率的になります。
:::

### `to`フィールドの特徴
`to`フィールドは、必ず`20`バイトのアドレスを表す必要があり、これは通常のトランザクションとは異なります。
**blob transaction** は新しいスマートコントラクトを作成する形式を取ることはできません。

### `max_fee_per_blob_gas`と`blob_versioned_hashes`
`max_fee_per_blob_gas`は、**blob transaction**のガス料金の上限を定義し、`blob_versioned_hashes`は、特定のハッシュ関数を通じて生成されたハッシュ値のリストです。

### ReceiptPayload
このトランザクションのレシートは、トランザクションのステータス、使用されたガスの累計量、ログのブルームフィルタ、およびログ自体を含むRLP形式のデータです。

```
rlp([status, cumulative_transaction_gas_used, logs_bloom, logs])
```

この「**blob transaction**」は、イーサリアムのデータ処理能力と効率を向上させるために設計されており、特に大量のデータを扱うトランザクションをより効率的に処理することを目的としています。

### 署名

```
keccak256(BLOB_TX_TYPE || rlp([chain_id, nonce, max_priority_fee_per_gas, max_fee_per_gas, gas_limit, to, value, data, access_list, max_fee_per_blob_gas, blob_versioned_hashes])).
```

ブロックチェーンのトランザクションにおける署名の作成方法について説明しています。
署名はトランザクションの正当性とセキュリティを保証する重要な部分です。

- **署名の値**
    - `y_parity`、`r`、`s` は、トランザクション署名のための3つの要素です。
    - これらはトランザクションが送信者によって正当に生成されたことを証明するために使用されます。

- **secp256k1 署名**
    - **secp256k1** は、イーサリアムなどの多くのブロックチェーンシステムで使用される、暗号学的な署名アルゴリズムです。
    - このアルゴリズムは、特定のデータに対する署名を生成するために使用されます。

- **ダイジェストの生成**
    - 署名は、特定のデータの「**ダイジェスト**」、つまり要約されたハッシュ値に対して行われます。
    - この場合、ダイジェストは `keccak256` ハッシュ関数を使用して生成され、`BLOB_TX_TYPE`（トランザクションの種類を表す値）と、`rlp`（Recursive Length Prefix）形式でエンコードされたトランザクションデータの組み合わせから作成されます。

- **トランザクションデータ**
    - トランザクションデータには以下のデータが含まれます。
    - `chain_id`（チェーンの識別子）
    - `nonce`（トランザクション数）
    - ガス料金関連の値（`max_priority_fee_per_gas`、`max_fee_per_gas`）`gas_limit
    - 送信先アドレス（`to`）
    - 送信額（`value`）
    - 送信データ（`data`）
    - アクセスリスト（`access_list`）
    - blobガス料金（`max_fee_per_blob_gas`）
    - blobハッシュ値（`blob_versioned_hashes`）

この署名プロセスにより、トランザクションは改ざんから保護され、ネットワーク上で安全に送信されます。

## ヘッダー拡張

ブロックチェーン（特にイーサリアム）のブロックヘッダーに新しい要素を追加することを説明しています。
これにより、ブロック内のトランザクションに関連するガス消費情報がより詳細に記録されることになります。

```
rlp([
    parent_hash,
    0x1dcc4de8dec75d7aab85b567b6ccd41ad312451b948a7413f0a142fd40d49347, # ommers hash
    coinbase,
    state_root,
    txs_root,
    receipts_root,
    logs_bloom,
    0, # difficulty
    number,
    gas_limit,
    gas_used,
    timestamp,
    extradata,
    prev_randao,
    0x0000000000000000, # nonce
    base_fee_per_gas,
    withdrawals_root,
    blob_gas_used,
    excess_blob_gas,
])
```

- **blob_gas_used**
    - これはブロック内のトランザクションによって消費されたblobガス（特定の種類のガス）の合計量を表します。
    - これにより、ブロックごとのガス消費の詳細が明確になります。

- **excess_blob_gas**
    - これは、ブロックが生成される前に、設定された目標値を超えて消費された**blob**ガスの累計量を示します。
    - この値は、新しいブロックが生成されるたびに更新され、目標を超えたガス消費があれば増加し、目標未満であれば減少します。

```python
def calc_excess_blob_gas(parent: Header) -> int:
    if parent.excess_blob_gas + parent.blob_gas_used < TARGET_BLOB_GAS_PER_BLOCK:
        return 0
    else:
        return parent.excess_blob_gas + parent.blob_gas_used - TARGET_BLOB_GAS_PER_BLOCK
```

- **計算方法**
    - `calc_excess_blob_gas` 関数は、親ブロックの `excess_blob_gas` と `blob_gas_used` の値を使って、新しいブロックの `excess_blob_gas` 値を計算します。
    - この計算により、ブロックごとの目標ガス消費量を追跡し、ブロックチェーン全体のガス消費の調整を行うことができます。

- **RLPエンコード**
    - ブロックヘッダーの**RLP**エンコードには、これらの新しいフィールドが含まれます。
    - これにより、ブロックチェーンネットワーク上でのブロックの送付と検証が、これらの新しいガス消費情報を含めて行われることになります。

この変更は、ブロックチェーンのトランザクション処理とガス消費の管理において、より高い透明性と効率性をもたらすことが期待されています。

## Gas accounting

ブロックチェーン（特にイーサリアム）における新しいタイプのガス、blobガスについて説明しています。

- **Blobガスの導入**
    - **Blob**ガスは、ブロックチェーン内のトランザクションに関連するデータ処理のための新しいガスタイプです。
    - これは、通常のガスとは異なる扱いを受け、**EIP1559**のような価格設定の規則に従います。

- **Blobガス価格の計算**
    - ブロックヘッダーに保存される `excess_blob_gas` フィールドを使用して、**blob**ガスの価格が計算されます。
    - この価格は、トランザクションに含まれる**blob**データの量に基づいて決定されます。

- **データ料金の計算**
    - `calc_data_fee` 関数は、トランザクションによって消費される**blob**ガスの量と、その時点での**blob**ガス価格を基に、トランザクションに対するデータ料金を計算します。

- **トランザクションの条件変更**
    - ブロックの妥当性条件は、**blob**ガスの使用量をチェックするように変更されています。
    - これにより、ブロックチェーン上でのトランザクションの処理が、新しい**blob**ガスの枠組みに適合するように調整されます。

- **データ料金の取り扱い**
    - トランザクション実行前に、計算されたデータ料金は送信者の残高から差し引かれ、`burn`されます。
    - この料金はトランザクションが失敗しても返金されません。

この変更により、ブロックチェーンにおけるデータ処理のコストがより明確になり、トランザクションの処理コストを適切に反映させることが可能になります。

## バージョン管理されたハッシュを取得するためのオペコード

ブロックチェーン（特にイーサリアム）のスマートコントラクトにおける新しい命令 `BLOBHASH` について説明しています。

- **BLOBHASH命令の機能**
    - `BLOBHASH` はスマートコントラクト内で特定のデータを参照するための命令です。
    - この命令はスタックのトップにある値（インデックス）を取り出し、そのインデックスに対応するトランザクションの `blob_versioned_hashes` 配列の要素をスタックに戻します。
    - `blob_versioned_hashes` は、トランザクションに関連する特定のデータのハッシュ値の配列です。

- **インデックスの処理**
    - もしインデックスが `blob_versioned_hashes` の長さより小さい場合、対応するハッシュ値がスタックにプッシュされます。
    - インデックスが配列の長さ以上の場合、代わりに`0`で埋められた `bytes32` 値がスタックにプッシュされます。

- **ガスコスト**
    - この命令を実行するためのガスコストは `HASH_OPCODE_GAS` と定義されています。
    - ガスコストは、ブロックチェーン上での操作にかかる計算資源の量を示します。

この命令の追加により、スマートコントラクトはトランザクション内の特定のデータ要素に対してより効率的にアクセスできるようになり、より複雑な操作や条件分岐が可能になります。

## ポイント評価プリコンパイル

```py
def point_evaluation_precompile(input: Bytes) -> Bytes:
    """
    Verify p(z) = y given commitment that corresponds to the polynomial p(x) and a KZG proof.
    Also verify that the provided commitment matches the provided versioned_hash.
    """
    # The data is encoded as follows: versioned_hash | z | y | commitment | proof | with z and y being padded 32 byte big endian values
    assert len(input) == 192
    versioned_hash = input[:32]
    z = input[32:64]
    y = input[64:96]
    commitment = input[96:144]
    proof = input[144:192]

    # Verify commitment matches versioned_hash
    assert kzg_to_versioned_hash(commitment) == versioned_hash

    # Verify KZG proof with z and y in big endian format
    assert verify_kzg_proof(commitment, z, y, proof)

    # Return FIELD_ELEMENTS_PER_BLOB and BLS_MODULUS as padded 32 byte big endian values
    return Bytes(U256(FIELD_ELEMENTS_PER_BLOB).to_be_bytes32() + U256(BLS_MODULUS).to_be_bytes32())
```

`POINT_EVALUATION_PRECOMPILE_ADDRESS` に配置される新しいプリコンパイル（事前計算された関数）は、blob（コミットメントによって表される）が特定の点で与えられた値に評価されることを主張するKZG証明を検証します。

このプリコンパイルのコストは `POINT_EVALUATION_PRECOMPILE_GAS` で、次のロジックを実行します：

```python
def point_evaluation_precompile(input: Bytes) -> Bytes:
    """
    Verify p(z) = y given commitment that corresponds to the polynomial p(x) and a KZG proof.
    Also verify that the provided commitment matches the provided versioned_hash.
    """
    # データは次のようにエンコードされています：versioned_hash | z | y | commitment | proof | zとyはパディングされた32バイトのビッグエンディアン値
    assert len(input) == 192
    versioned_hash = input[:32]
    z = input[32:64]
    y = input[64:96]
    commitment = input[96:144]
    proof = input[144:192]

    # 提供されたコミットメントがversioned_hashと一致することを検証
    assert kzg_to_versioned_hash(commitment) == versioned_hash

    # ビッグエンディアン形式のzとyを使用してKZG証明を検証
    assert verify_kzg_proof(commitment, z, y, proof)

    # FIELD_ELEMENTS_PER_BLOBとBLS_MODULUSをパディングされた32バイトのビッグエンディアン値として返す
    return Bytes(U256(FIELD_ELEMENTS_PER_BLOB).to_be_bytes32() + U256(BLS_MODULUS).to_be_bytes32())
```

ブロックチェーン（特にイーサリアム）における新しいプリコンパイル機能について説明しています。
この機能は、特定の数学的証明（KZG証明）を検証するために使用されます。

- **プリコンパイルの目的**
    - このプリコンパイルは、ある**ポリノミアル（多項式）p(x)**に対応するコミットメントと、そのポリノミアルが特定の点`z`で与えられた値`y`に等しいことを示す**KZG**証明を検証するために使用されます。

- **入力データの処理**
    - 入力データは、`versioned_hash`、`z`、`y`、`commitment`、`proof` の5つの部分に分かれており、それぞれが特定の役割を持っています。
    - このプリコンパイルは、これらの部分を読み取り、必要な検証を行います。

- **コミットメントとバージョン化ハッシュの検証**
    - 提供されたコミットメントが、提供されたバージョン化ハッシュと一致することを検証します。
    - これは、データの整合性を保証するための重要なステップです。

- **KZG証明の検証**
    - 提供された`commitment`、`z`、`y`を使用して**KZG**証明を検証し、`p(z) = y` が真であることを確認します。
    - これにより、コミットメントが正確に**ポリノミアルp(x)**を表しているかを検証します。

- **出力**
    - 最終的には、`FIELD_ELEMENTS_PER_BLOB` と `BLS_MODULUS` の値をビッグエンディアン形式で返します。

このプリコンパイルは、ブロックチェーン上のデータの整合性と正確性を保証するために重要な役割を果たします。
また、正規でないフィールド要素を拒否することで、データの信頼性をさらに高めています。

:::note info
### ポリノミアルp(x)

ポリノミアル（多項式）は数学における非常に基本的な概念の1つです。
ポリノミアルは、変数（通常は $( x )$）の異なるべき乗に対する係数の和で表されます。

**ポリノミアルの例**

例えば、次の式はポリノミアルです。

```math
[ p(x) = 3x^2 + 2x + 5 ]
```

この式において、

- $( x )$ は変数です。
- $( 3x^2 )$、$( 2x )$、$( 5 )$ は「**項**」です。
- $( 3 )$、$( 2 )$、$( 5 )$ はそれぞれの項の「**係数**」です。

**ポリノミアルのべき乗**

ポリノミアルの各項は、変数 $( x )$ の異なるべき乗です。
この例では、

- $( 3x^2 )$ は $( x )$ の2乗に対する項で、係数は`3`です。
- $( 2x )$ は $( x )$ の1乗に対する項で、係数は`2`です。
- $( 5 )$ は \$( x )$ の0乗（つまり定数項）に対する項で、係数は`5`です。

**ポリノミアルの評価**

$( x )$ に具体的な値を代入して、ポリノミアルの値を計算することができます。
例えば、$( x = 1 )$ のとき、ポリノミアル $( p(x) )$ の値は以下のようになります。

```math
[ p(1) = 3(1)^2 + 2(1) + 5 = 3 + 2 + 5 = 10 ]
```

このように、ポリノミアルは変数 $( x )$ にさまざまな値を代入することで、異なる結果を得ることができる数学的表現です。


**まとめ**

ポリノミアルは、変数のべき乗とそれに対応する係数の和で構成される式です。
これは、代数学や微積分学など数学の多くの分野で基本的な役割を果たします。
また、実世界のさまざまな現象をモデル化するためにも使われます。
:::

## コンセンサスレイヤーの検証

ブロックチェーンのコンセンサス層（特にイーサリアム2.0のビーコンチェーン）における新しいデータ管理方法について説明しています。

- **サイドカー設計**
    - ブロックチェーンのブロックは、その中に含まれるすべてのトランザクションデータを完全にエンコードします。
    - しかし、この新しい設計では、**blob** （大量のデータを持つトランザクション）はビーコンブロック本体に直接埋め込まれるのではなく、別途「**サイドカー**」として伝播されます。
    - これにより、データの伝播がより効率的になります。

- **データ可用性の確保**
    - コンセンサスレイヤーは、ネットワーク上でデータが利用可能であることを保証する責任があります。
    - これは、システムの完全性と信頼性を維持するために重要です。

- **ethereum/consensus-specsリポジトリの役割**
    - このリポジトリは、ビーコンチェーンの処理、P2Pネットワークの同期、およびバリデーターの行動に関連するコンセンサス層の変更を定義します。
    - これには、**blob**を含むビーコンブロックの生成と、それに関連するサイドカーの公開が含まれます。

この変更により、ブロックチェーンネットワークは、データ量が増加する将来にも柔軟に対応できるようになり、同時に全ノードが大量のデータをダウンロードする必要性を減らすことができます。
これにより、ネットワークの帯域幅が節約され、全体的な効率が向上します。

## 実行レイヤーの検証

```py
def validate_block(block: Block) -> None:
    ...

    # check that the excess blob gas was updated correctly
    assert block.header.excess_blob_gas == calc_excess_blob_gas(block.parent.header)

    blob_gas_used = 0

    for tx in block.transactions:
        ...

        # modify the check for sufficient balance
        max_total_fee = tx.gas * tx.max_fee_per_gas
        if get_tx_type(tx) == BLOB_TX_TYPE:
            max_total_fee += get_total_blob_gas(tx) * tx.max_fee_per_blob_gas
        assert signer(tx).balance >= max_total_fee

        ...

        # add validity logic specific to blob txs
        if get_tx_type(tx) == BLOB_TX_TYPE:
            # there must be at least one blob
            assert len(tx.blob_versioned_hashes) > 0

            # all versioned blob hashes must start with VERSIONED_HASH_VERSION_KZG
            for h in tx.blob_versioned_hashes:
                assert h[0] == VERSIONED_HASH_VERSION_KZG

            # ensure that the user was willing to at least pay the current blob gasprice
            assert tx.max_fee_per_blob_gas >= get_blob_gasprice(block.header)

            # keep track of total blob gas spent in the block
            blob_gas_used += get_total_blob_gas(tx)

    # ensure the total blob gas spent is at most equal to the limit
    assert blob_gas_used <= MAX_BLOB_GAS_PER_BLOCK

    # ensure blob_gas_used matches header
    assert block.header.blob_gas_used == blob_gas_used
```

ブロックチェーンの実行層におけるブロック検証プロセスの拡張について説明しています。
具体的には、新しいタイプのトランザクション（**blob**トランザクション）とそれに関連するガス消費（**blob**ガス）に関連する追加のチェックが含まれています。

- **Excess Blob Gasのチェック**
    - 各ブロックのヘッダーに記載された `excess_blob_gas` 値が、親ブロックのヘッダー情報を用いた計算結果と一致することを確認します。

- **トランザクションごとのチェック**
    - ブロック内の各トランザクションに対して、十分な残高があること、**blob**トランザクションの特定の条件（**blob**ハッシュの形式、最小**blob**ガス価格の確認など）が満たされていることを確認します。

- **Blobガスの使用量追跡**
    - ブロック内で消費された**blob**ガスの合計量を計算し、これが設定された最大値を超えていないことを確認します。

- **ヘッダーとの一致**
    - 計算された**blob**ガスの合計使用量が、ブロックヘッダーに記載された値と一致していることを確認します。

これらの拡張された検証プロセスにより、**blob**トランザクションの扱いとガス消費に関するルールが厳格に管理され、ブロックチェーンの整合性とセキュリティが保たれます。

## ネットワーキング

**Blob**トランザクションは、ネットワーク上で2つの異なる形式で表現されます。
これらの形式は、トランザクションの伝播の方法や検証のプロセスにおいて重要な役割を果たします。

- **トランザクションのラッピング**
    - **PooledTransactions**の間に、**EIP2718**に基づく**blob**トランザクションの`TransactionPayload`は特定の形式でラップされます。
    - このラップされた形式は `rlp([tx_payload_body, blobs, commitments, proofs])` となり、トランザクションの本体、**blob**データ、それに対応するコミットメント、そして証明が含まれます。

- **各要素の役割**
    - `tx_payload_body`
        - トランザクションのペイロード本体。
    - `blobs`
        - **blob**アイテムのリスト。
    - `commitments`
        - 対応する**blob**の`KZGCommitment`のリスト。
    - `proofs`
        - 対応する**blob**と`commitmentsのKZGProof`のリスト。

- **検証プロセス**
    - ノードは `tx_payload_body` を検証し、ラップされたデータと照合する必要があります。
    - これには、**blob**バージョン化ハッシュ、**blob**データ、コミットメント、証明の数が等しいこと、KZGコミットメントがバージョン化ハッシュにハッシュされていること、そしてKZGコミットメントが対応する**blob**と**proofs**に一致することを確認する作業が含まれます。

- **トランザクションの伝播**
    - **blob**トランザクションは自動的にブロードキャストされず、`NewPooledTransactionHashes`メッセージを通じてのみアナウンスされます。
    - これにより、ネットワークの帯域幅が節約され、必要なトランザクションのみがノードによってリクエストされることが可能になります。

このように、**blob**トランザクションのネットワーク上での扱いは、ブロックチェーンのパフォーマンスと効率性を高めるために重要です。
また、トランザクションの検証プロセスは、ネットワークのセキュリティとデータの正確性を保証するために不可欠です。

# 補足

## シャーディングへの道

このEIPはイーサリアムにおけるシャーディングへの道のりにおいて、重要な段階を示しています。

### blobトランザクションの導入

この提案では、シャーディングの最終的な仕様で期待されている形式の**blob**トランザクションが導入されます。
これにより、ロールアップは当初からスロットあたり`0.375MB`までスケールアップできるようになり、このシステムの使用が限られている間は料金が非常に低く抑えられます。

### 中間的な解決策の目的
現在、ロールアップは`calldata`を使用していますが、将来的にはよりコスト効率の良いシャーディングされたデータ（**blob**）を使用することになります。
このEIPは、ロールアップがデータ処理方法を一度だけ大きくアップグレードすることを可能にし、これによりロールアップは将来のシャーディングに対してより効率的に準備することができます。

### 完全なシャーディングに向けた作業
このEIPによって既に導入されている要素には、完全なシャーディングに必要な新しいトランザクションタイプや実行層のロジックが含まれています。
また、ビーコンブロック検証とデータ可用性サンプリングの間の層分離や、**blob**のための独立したガス価格調整機能も導入されています。

### 完全なシャーディングに向けて残された作業
このEIPでまだ実装されていない要素には、データ可用性サンプリングの実装や、個々のバリデータが大量のデータを一度に処理する必要性を回避するためのPBS（提案者/ビルダー分離）などが含まれています。

このEIPは、イーサリアムの将来的な発展とシャーディングに向けた重要なステップであり、ネットワークのスケーラビリティと効率性を向上させることを目的としています。

## ロールアップの機能

ロールアップのデータ処理方法は従来の`calldata`を使用する方式から、新しい**blob**ベースの方法へと変化します。
この変更により、ロールアップはデータの可用性を保証しつつ、コストを大幅に削減できるようになります。

- **データの可用性とコスト削減**
    - ロールアップブロックのデータは**blob**に格納されることで、データの可用性が保証され、同時に`calldata`を使用するよりもコストが削減されます。
    - ロールアップにとって重要なのは、データが一定期間利用可能であることですが、永続的に保持する必要はありません。

- **楽観的ロールアップの詐欺証明**
    - 楽観的ロールアップでは、詐欺証明の時にのみデータを提供する必要があります。
    - このプロセスでは、**blob**からのデータ読み込みとKZG証明を使用して、提出されたデータの正確性を確認し、詐欺があった場合にその証明を行います。

- **ZKロールアップのコミットメントと証明**
    - ZKロールアップは、**blob**コミットメントとロールアップ自体のコミットメントの両方を提供し、これらが同じデータを指すことを証明します。
    - これにより、ZKロールアップは内部的に使用する証明システムと、プロトコルによって保証されるデータの可用性との間に一致を保ちます。

この新しいアプローチにより、ロールアップはより効率的にデータを処理し、シャーディングに向けた移行を容易にすることができます。
データの処理と検証におけるコストと複雑さの削減は、ロールアップのスケーラビリティと実用性を大幅に向上させます。

## バージョン・ハッシュとプリコンパイル・リターン・データ

将来の変更に対する前方互換性を確保するために、実行層で**blob**にアクセスする時にバージョン化されたハッシュがどのように使用されるかを説明しています。

- **バージョン化されたハッシュの使用**
    - ロールアップや他のスマートコントラクトは、量子安全な技術への移行など将来の変更に対応するために、コミットメントの代わりにバージョン化されたハッシュを使用します。
    - これにより、将来的に異なるデータ構造や証明方法が導入された場合でも、ロールアップはEVMレベルでの変更を行う必要がなくなります。

- **ポイント評価と有限体**
    - ポイント評価は有限体内で行われるため、正確な計算を行うにはその法（`modulus`）が必要です。
    - スマートコントラクトは将来の変更に対応するために、この法を動的に取得することが重要です。

- **プリコンパイルの戻り値**
    - 新しいポイント評価プリコンパイルは、法と多項式の次数を直接返します。
    - これにより、スマートコントラクトは将来的なアップグレードや変更に対して柔軟に対応できるようになります。
    - また、この戻り値は呼び出し側が無視しても追加コストがかからないため、将来的にアップグレードが必要なシステムでも利用することができます。

このアプローチにより、イーサリアムは将来的な技術的変更に柔軟に対応し、スマートコントラクトやロールアップの開発者は、変更が行われるたびにコードを大幅に変更する必要がなくなります。
これは、長期的なプロトコルの持続可能性とアップグレードの容易性を向上させる重要なステップです。

## Blobガス価格更新ルール

イーサリアムネットワークの**blob**ガス価格の自己調整式に関するものです。
このルールは、ネットワーク上での**blob**ガスの使用量が目標値とどの程度異なるかに基づいて、ガス価格を自動的に調整します。

### 自己補正式の動作原理

**Blob**ガス価格の更新ルールは、**blob**ガス価格を `MIN_BLOB_GASPRICE * e**(excess_blob_gas / BLOB_GASPRICE_UPDATE_FRACTION)` の公式に近似することを目的としています。
ここで、`excess_blob_gas` は、チェーンが「**目標**」とする数値（ブロックあたりの `TARGET_BLOB_GAS_PER_BLOCK`）に対して消費した**blob**ガスの「**余分な**」合計量を指します。
**EIP1559**と同様に、これは自己補正式です。

この公式は、ネットワークが目標よりも多くの**blob**ガスを使用すると、次のブロックでの**blob**ガス価格が指数関数的に増加するという原理に基づいています。
これにより、使用量が過剰になるとコストが増え、使用量が自然と減少することでシステムが目標値に戻ります。

### ブロックごとの振る舞い

各ブロックが特定量の**blob**ガスを消費すると、次のブロックの**blob**ガス価格が調整されます。
この価格は、前のブロックの消費量が目標値からどれだけ離れているかに応じて増加します。

ブロックごとの振る舞いは大まかに以下の通りです。
ブロック`N`が**X blob**ガスを消費すると、ブロックN+1で `excess_blob_gas` は `X - TARGET_BLOB_GAS_PER_BLOCK` だけ増加し、したがってブロック`N+1`の**blob**ガス価格は `e**((X - TARGET_BLOB_GAS_PER_BLOCK) / BLOB_GASPRICE_UPDATE_FRACTION)` の係数で増加します。

### 安定性の確保
このルールは、**blob**ガスの使用量がどのように分配されても、同じ総使用量に対して同じように反応するため、価格の安定性を保証します。
これは、**EIP1559**に似ていますが、より一貫した反応を示すことで、より予測可能な価格動向を提供します。

### 最大変更率の制御

パラメータ `BLOB_GASPRICE_UPDATE_FRACTION` はblobガス価格の最大変更率を制御します。
ブロックあたり `e(TARGET_BLOB_GAS_PER_BLOCK / BLOB_GASPRICE_UPDATE_FRACTION) ≈ 1.125` の最大変更率を目標として選択されています。
これは、ブロックごとにblobガス価格が急激に変動しないようにするためのもので、ネットワークの安定性と予測可能性を維持するために重要です。

この自己調整式は、ネットワークの負荷に応じてガス価格を適切に調整し、過度の使用を防ぎつつ、ユーザーに対して公平かつ効率的な価格設定を提供することを目的としています。
これにより、イーサリアムネットワークの持続可能性とスケーラビリティが向上します。

## スループット

イーサリアムネットワークの**blob**トランザクションに関するガス消費量の目標と最大値について説明しています。

- **目標と最大値の設定**
    - ブロックあたりの**blob**ガス消費量の目標値として設定されている `TARGET_BLOB_GAS_PER_BLOCK` は、ブロックあたり`3blob`、すなわち`0.375MB`に相当します。
    - また、最大値として設定されている `MAX_BLOB_GAS_PER_BLOCK` は、ブロックあたり最大`6blob`、すなわち`0.75MB`に相当します。

- **初期限界の目的**
    - これらの値は初期段階では比較的小さく設定されており、これは新しいEIPがネットワークに与える影響を最小限に抑えるためです。
    - 初期の小さな限界は、ネットワークに過度の負担をかけずに、新しいシステムの信頼性を確認し、安定性を保つために重要です。

- **将来のアップグレードに向けて**
    - ネットワークがより大きなブロックに対する信頼性を実証するにつれて、これらの値は将来的に増加することが期待されます。
    - これにより、ネットワークのスループットを段階的に増加させることが可能になり、シャーディングに向けた移行をサポートします。

このように、**blob**トランザクションの導入によるネットワークへの影響は慎重に管理されており、将来的な拡張性とスケーラビリティを確保しつつ、現在のネットワークの安定性を保つための工夫がなされています。

# 互換性

## Blob non-accessibility

このEIPによって導入される新しいトランザクションタイプは、メモリプール（ネットワーク上でのトランザクションの一時的な保持場所）とブロックチェーンの実行ペイロード（トランザクションが実際にブロックに含まれる形式）で異なる形式を持ちます。
これらの形式間では、一方向の変換のみが可能という制約があります。

- **Blobの位置とアクセシビリティ**
    - この新しいトランザクションタイプでは、**blob**（大量のデータを含むトランザクションの一部）はネットワーク層に存在しますが、コンセンサス層（ブロックチェーンの合意された状態）には存在しません。
    - 代わりに、これらの**blob**はビーコンブロック（イーサリアム2.0の一部として提案されている新しいブロックタイプ）に結び付けられます。

- **web3 APIの制限**
    - この変更により、トランザクションの一部がweb3 API（イーサリアムネットワークとのインターフェースを提供する標準的なAPI）を通じて直接アクセス可能でなくなります。
    - これは、開発者がこれらのトランザクションの一部のデータにプログラムで直接アクセスする時に考慮すべき重要なポイントです。

このEIPの導入は、トランザクションデータの扱い方において新しいアプローチを提供し、イーサリアムの将来のアップグレードにおける柔軟性と拡張性を考慮したものです。ただし、開発者はこれらの変更を認識し、適応する必要があります。

## Mempool問題

このテキストでは、**blob**トランザクションがイーサリアムネットワークのメモリプールに与える影響と、その対策について説明しています。

- **メモリプールでの大きなデータサイズ**
    - **Blob**トランザクションは、メモリプール層で比較的大きなデータサイズを持つため、ネットワークに対するDoS攻撃のリスクが高まります。
    - これは、大量の`calldata`を含む通常のトランザクションでも同様のリスクがあるため、全く新しい問題ではありませんが、注目すべきリスクです。

- **アナウンスによる制御**
    - **Blob**トランザクションのアナウンスのみをブロードキャストすることで、各ノードは受信するトランザクションの量を制御できます。
    - これにより、ノードはスループットを自身の処理能力に応じて調整し、過負荷を防ぐことが可能になります。

- **EIP-5793による細かい制御**
    - **EIP5793**は、トランザクションのタイプとサイズを含む`NewPooledTransactionHashes`アナウンスメッセージの拡張を提案しています。
    - これにより、ノードはより精密にトランザクションを選択し、メモリプールにおけるリソースの使用を最適化できます。

- **ガス価格上昇要件の導入**
    - さらに、メモリプールのトランザクション置き換えルールに1.1倍の**blob**ガス価格上昇要件を追加することが推奨されています。
    - これにより、メモリプールのトランザクションが置き換えられる時には、新しいトランザクションが前のものよりも高いガス価格を必要とすることが要求され、過度なトランザクションの流入を防ぐ助けとなります。

これらの措置により、**blob**トランザクションがメモリプールに与える影響を管理し、ネットワークの安定性とセキュリティを確保することを目指しています。

# セキュリティ


このEIPは、イーサリアムネットワークにおける帯域幅要件の増加と、その持続的な負荷の影響について説明しています。

- **帯域幅要件の増加**
    - ビーコンブロックごとの最大約`0.75MB`の増加は、現在のブロックサイズの理論的最大値に比べて`40%`大きいですが、帯域幅を大幅に増加させません。
    - つまり、ネットワークに対する影響は限定的であり、既存のインフラストラクチャに対する負担はそれほど大きくないと考えられます。

- **ブロック時間の静的化**
    - イーサリアムがマージ後には、ブロック時間は静的になります。
    - これは、大きなブロックの伝播に必要な時間が保証されることを意味し、ネットワークの安定性と予測可能性を向上させます。

- **持続的負荷の軽減**
    - このEIPによる持続的な負荷は、`calldata`コストを削減する他の提案よりも低いです。
    - **blob**データは実行ペイロードほど長く保持される必要がないため、短期間（約18日間）の保持が必要とされ、これは実行ペイロード履歴の保持期間（1年間）よりも短いです。

これらの点を考慮すると、このEIPはネットワークの帯域幅要件を増加させますが、その影響は管理可能であり、ネットワークの持続可能性と効率性を損なうことなく、イーサリアムの将来的な発展をサポートしています。

# 引用

Vitalik Buterin (@vbuterin), Dankrad Feist (@dankrad), Diederik Loerakker (@protolambda), George Kadianakis (@asn-d6), Matt Garnett (@lightclient), Mofi Taiwo (@Inphi), Ansgar Dietrichs (@adietrichs), "EIP-4844: Shard Blob Transactions [DRAFT]," Ethereum Improvement Proposals, no. 4844, February 2022. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-4844.

# 参考

より詳しくは以下の記事などが参考になります。

https://www.eip4844.com/

https://zenn.dev/qope/articles/b8d09ae260f1aa

https://recruit.gmo.jp/engineer/jisedai/blog/2024_ethereum_upgrade_dencun/

# よくある質問

以下の記事に記載されているよくある質問からいくつか抜粋して日本語に翻訳しつつ説明します。

https://notes.ethereum.org/@vbuterin/proto_danksharding_faq

## ダンクシャルディングとは何ですか？

Dankshardingはイーサリアムにおけるシャーディングの新しいアプローチで、従来のシャーディング提案と比較していくつかの大幅な簡素化が導入されています。

### ロールアップ中心のロードマップ
Dankshardingは、イーサリアムのロールアップ中心のロードマップを採用しています。
これは、トランザクションのスペースを増やすのではなく、データのblobのためのスペースを提供することを意味します。
blobのデータはイーサリアムプロトコルによって直接解釈されず、利用可能性が確認されるだけです。
これらのblobは、高いトランザクション処理能力を持つレイヤー2のロールアッププロトコルで使用されることを目的としています。

### 統合された手数料市場の導入
Dankshardingの大きな革新の一つは、統合された手数料市場です。
個別のブロックを持つ複数のシャードではなく、1人の提案者が1つのスロットに含まれるすべてのトランザクションとデータを選択します。

### 提案者/ビルダーの分離（PBS）
この新しい設計は、ブロックの提案者とブロックビルダーを分離することで、バリデーターに高いシステム要件を課すことを回避します。
ブロックビルダーはスロットの内容を選択する権利を入札し、提案者は最高の入札を持つ有効なヘッダーを選ぶだけです。
これにより、ブロック全体を処理する必要があるのはブロックビルダーだけとなり、他のバリデーターやユーザーはデータ可用性サンプリングを通じて効率的にブロックを検証できます。

これらの変更により、イーサリアムはより効率的でスケーラブルなシャーディングシステムを実現し、将来の拡張性とユーザビリティを確保しています。

![upload_817c16c28fa3c89254aac622c277416a.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/570269/7909e521-c351-04c7-dc63-49652c59a24b.png)
引用: https://notes.ethereum.org/@vbuterin/proto_danksharding_faq#What-is-Danksharding

## プロトダンクシャーディング (別名 EIP-4844) とは何ですか?

プロトダンクシャーディング（EIP-4844）は、Dankshardingに向けた準備段階の一環として提案されています。

### 主要機能
プロトダンクシャーディングの主な特徴は、**blob**キャリングトランザクションという新しいトランザクションタイプの導入です。
これは従来のトランザクションに似ていますが、追加で大きなデータ（**blob**）を含みます。
**blob**は大量のデータ（約`125kB`）を格納でき、`calldata`よりもコストが低いですが、EVM実行にはアクセスできません。

### データ帯域幅の管理
この提案では、バリデーターとクライアントは**blob**の全内容をダウンロードして検証する必要があります。
このため、データ帯域幅はスロットあたり最大`1MB`に制限され、Dankshardingの完全実装時の`16MB`よりも少なくなっています。

### スケーラビリティの向上
このアプローチにより、既存のイーサリアムトランザクションのガス使用と競合せず、ネットワークの負荷を軽減しつつ、大量のデータを効率的に処理することが可能になります。
これは、イーサリアムネットワークのスケーラビリティを大きく向上させることを目的としています。

プロトダンクシャーディングは、Dankshardingに向けた途中段階の提案であり、イーサリアムネットワークのスケーラビリティを向上させるための重要なステップです。

## なぜ、誰もがダウンロードしなければならないブロックに1MBのデータを追加するのはOKで、calldataを10倍安くするのはダメなのか？

イーサリアムネットワークにおける現在の負荷管理問題と、それを解決するための提案について解説しています。

### 平均負荷と最悪ケース負荷
現在のイーサリアムネットワークでは、平均ブロックサイズは`90kB`程度ですが、理論上の最大ブロックサイズは`1.8MB`に達します。
この大きな差は、`calldata`のガスコストがどのように設定されるかに依存します。

### ガス価格体系の問題
現在のガス価格体系では、平均負荷と最悪ケース負荷を分離することが困難です。
これは、ユーザーが`calldata`と他のリソースにどれだけガスを使うかによって異なります。
その結果、ガス価格は最悪ケースの可能性に基づいて設定され、システムが処理できる量よりも平均負荷が低くなってしまいます。

### 多次元手数料市場への変更
ガス価格を変更し、多次元手数料市場を作ることで、平均ケースと最悪ケースの負荷の不一致を解消できます。
これにより、各ブロックに安全に処理できる最大量のデータを含めることが可能になります。

### プロトダンクシャーディングとEIP-4488
プロトダンクシャーディングでは平均ケースが`1MB`、最悪ケースが`2MB`となり、**EIP4488**では`calldata`の使用量が5倍増加した場合の平均ケースが`350kB`、最悪ケースが`1.4MB`となります。

|  | Average case block size | Worst case block size |
| :-: | :-----------------: | :-------------------: |
| Status quo | 85 kB | 1.8 MB |
| EIP-4488 | Unknown; 350 kB if 5x growth in calldata use | 1.4 MB |
| Proto-danksharding | 1 MB (tunable if desired) | 2 MB |

これらの提案により、イーサリアムネットワークは平均的な利用状況に合わせてより効率的にデータを処理し、同時に最悪ケースのシナリオにおいてもシステムの限界を超えることなく安全に運用できるようになります。

## 大きなブロックのせいでディスク容量が膨れ上がったらどうするか？

**EIP4488**およびプロトダンクシャーディングは、イーサリアムのデータ保存要件に大きな影響を与えると予想されています。

### データ成長率の増加
これらの提案により、年間約`2.5TB`のデータ成長率が期待され、これはイーサリアムが現在必要とするレートよりもはるかに高いです。
特にフルシャーディングが実装されると、年間約`40TB`の**blob**データが追加されるため、クライアントに大きな負担がかかります。

### 履歴の期限切れによる解決策
**EIP4488**では、履歴の期限切れ（**EIP4444**）が必要になります。
これにより、クライアントは特定の期間を超える古いデータを保持する必要がなくなります。
プロトダンクシャーディングでは、コンセンサス層がblobデータを一定期間（例えば30日）後に自動的に削除するロジックを実装できます。

### コンセンサスクライアントのディスク負荷
これらの戦略により、コンセンサスクライアントの追加ディスク負荷は数百ギガバイト以内に制限されますが、長期的には履歴の期限切れメカニズムの採用が不可欠です。

### 期限切れメカニズムの重要性
ユーザーが実際に保存できるデータ量には限りがあるため、フルシャーディングによって追加される大量のデータを維持するためには、いくつかの履歴の期限切れメカニズムが必要になります。
このようなメカニズムは、イーサリアムネットワークの長期的な持続可能性を確保するために不可欠です。

このように、**EIP4488**およびプロトダンクシャーディングは、イーサリアムの将来的なデータ管理戦略に重要な役割を果たすことが期待されています。

## データが30日後に削除される場合、ユーザーは古いブロブにどのようにアクセスするのか？

イーサリアムネットワークにおける履歴データ管理のアプローチと長期的な保存の実践に関する重要な情報が提供されています。

### コンセンサスプロトコルの目的
イーサリアムのコンセンサスプロトコルは、履歴データの永久保存を保証することではなく、セキュアなリアルタイム掲示板を提供し、他のプロトコルが長期保存を行う余地を残すことが目的です。

### 長期保存の実現可能性
年間`2.5TB`のデータ量は管理可能で、特に専念するユーザーや研究者にとっては負担にならないレベルです。

### 履歴データの保存方法
アプリケーション固有のプロトコルがそのデータを保存する責任を負うほか、BitTorrentなどの分散型ストレージ、Ethereum Portal Networkの拡張、ブロックエクスプローラーやAPIプロバイダー、趣味家や学者、サードパーティのインデックスプロトコルなどによる保存が提案されています。

### 履歴データの保存の限界
年間`500TB`のような大容量のデータ保存では、一部のデータの忘れ去られるリスクが高まります。
これはシャーディングされたブロックチェーンのスケーラビリティの限界を示唆しています。

このように、イーサリアムネットワークは、履歴データの管理と保存において様々な戦略を採用しており、長期的な持続可能性を確保するために、これらのアプローチが重要になっています。

## ブロブデータはどのような形式で、どのようにコミットされるのか？

イーサリアムの**EIP4844**に関連する**blob**とKZGコミットメントについて詳述しています。

### Blobの定義
**blob**は`4096`個のフィールド要素からなるベクトルで、それぞれが特定の範囲内の数値です。
**blob**は有限フィールド上の多項式として数学的に扱われますが、実装においては多項式の数学的詳細にこだわる必要はありません。

### KZGコミットメント
**blob**へのコミットメントは、多項式のKZGコミットメントをハッシュ化したものです。
実装においては、楕円曲線点のベクトル（ラグランジュ基準の信頼されたセットアップ）として表され、KZGコミットメントは線形結合として計算されます。

### 実装の簡素化
実装者にとっては、このプロセスを特殊なハッシュ関数のように扱うことが推奨されます。
これにより、KZGコミットメントの計算が簡略化され、実装が容易になります。

## なぜKZGを直接使うのではなく、KZGのハッシュを使うのか？

**EIP4844**で採用されている**blob**の表現方法に関しての説明です。

### KZGとバージョン化されたハッシュの選択
KZGコミットメントを直接使用する代わりに、**EIP4844**はバージョン化されたハッシュを採用しています。
これは、KZGの`SHA256`ハッシュの最後の`31`バイトに、バージョンを示す`0x01`バイトを前置する形式です。

### EVM互換性のための設計
この設計は、EVMの動作に適した`32`バイトの値との互換性を考慮しています。
KZGコミットメントは本来`48`バイトですが、EVMでは`32`バイトの値を扱うことがより一般的です。

### 将来の互換性
このバージョン化されたハッシュの使用は、将来的にKZGから別の技術（例えば、量子コンピューターに対する耐性を持つ技術）に移行する可能性にも対応しています。
このような場合でも、コミットメントは`32`バイトのままであり続けることができます。

このアプローチは、**EIP4844**がEVMの現在の制約に適応しつつ、将来的な技術の変化にも柔軟に対応できるように設計されていることを示しています。

## プロト・ダンクシャーディングで導入された2つのプリコンパイルとは？


プロトダンクシャーディングは、blob検証プリコンパイルとポイント評価プリコンパイルの二つのプリコンパイルを導入します。

> Optimistic rollups only need to actually provide the underlying data when fraud proofs are being submitted. The fraud proof submission function would require the full contents of the fraudulent blob to be submitted as part of calldata. It would use the blob verification function to verify the data against the versioned hash that was submitted before, and then perform the fraud proof verification on that data as is done today.

> オプティミスティックロールアップは、不正証明が提出される際にのみ、基礎となるデータを実際に提供する必要があります。不正証明提出機能は、不正なblobの完全な内容をcalldataの一部として提出する必要があります。これはblob検証機能を使用して以前に提出されたバージョン化されたハッシュとデータを検証し、その後、現在行われているようにそのデータに対する不正証明検証を行います。

ポイント評価プリコンパイルは、バージョン化されたハッシュ、x座標、y座標、証明（blobのKZGコミットメントとKZG評価証明）を入力として受け取ります。
これは、`P(x) = y`を満たすかどうか、つまり与えられたバージョン化されたハッシュを持つblobによって表される多項式Pをチェックするための証明を検証します。
このプリコンパイルは、ZKロールアップによって使用されることを意図しています。

> ZK rollups would provide two commitments to their transaction or state delta data: the kzg in the blob and some commitment using whatever proof system the ZK rollup uses internally. They would use a commitment proof of equivalence protocol, using the point evaluation precompile, to prove that the kzg (which the protocol ensures points to available data) and the ZK rollup’s own commitment refer to the same data.

> ZKロールアップは、トランザクションや状態デルタデータに対して二つのコミットメントを提供します：blob内のkzgと、ZKロールアップが内部で使用する証明システムを用いた何らかのコミットメントです。彼らは、点評価プリコンパイルを使用したコミットメント証明の等価プロトコルを使用して、利用可能なデータを指すことがプロトコルによって保証されているkzgと、ZKロールアップ自身のコミットメントが同じデータを指すことを証明します。

ほとんどの主要なオプティミスティックロールアップ設計は、最終ラウンドで小さなデータ量のみを取る多ラウンドの不正証明スキームを使用しています。
したがって、オプティミスティックロールアップは、blob検証プリコンパイルの代わりにポイント評価プリコンパイルを使用することもでき、そうする方が安価になります。

### Blob検証プリコンパイルの役割
このプリコンパイルは、提供されたバージョン化されたハッシュがblobに対して有効であることを検証します。
この機能は、オプティミスティックロールアップによって主に使用され、不正証明の提出に関わるデータの検証に役立ちます。

### ポイント評価プリコンパイルの役割
このプリコンパイルは、与えられたバージョン化されたハッシュを持つblobによって表される多項式が特定のx座標でy値を持つことを確認する証明を検証します。
この機能は、ZKロールアップによって使用され、トランザクションや状態データのコミットメントの検証に役立ちます。

### オプティミスティックロールアップとポイント評価プリコンパイル
オプティミスティックロールアップの多くは、最終ラウンドで少量のデータのみを要求する多ラウンドの不正証明スキームを採用しています。
このため、ポイント評価プリコンパイルを使用することで、オプティミスティックロールアップのコストを削減することが可能です。

# 最後に

今回は「**blob-carrying transactions**という、Ethereumネットワークにおいて大量のデータを含む新しいトランザクションの仕組みを提案している**EIP4844**」についてまとめてきました！
いかがだったでしょうか？

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