[ERC5189] プロトコルの変更をせずにより少ない制約でAccount Abstractionを実装する仕組みを理解しよう！

# はじめに

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

https://cryptogames.co.jp/

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

https://cryptospells.jp/

今回は、既存のコントラクトウォレットとの互換性を維持しながら、プロトコルの変更を回避するアカウント抽象化のの仕組みを提案している規格である**ERC5189**についてまとめていきます！

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

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

:::note warn
**5189**は現在（2023年12月9日）では「**Draft**」段階です。
:::

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

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

# 概要

このEIPは、イーサリアムネットワークのスマートコントラクトウォレットの仕組みを新しいレベルに引き上げようとしています。
具体的には、アカウント抽象化（AA）という技術を用いて、ウォレットの機能性と柔軟性を高めることを目指しています。

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

https://qiita.com/cardene/items/8c97ca7c93c4557ebfc2

この提案の核心は、エンドーサーコントラクトという新しいタイプのスマートコントラクトを導入することです。
これらのコントラクトは、イーサリアムネットワーク上で行われるAAトランザクション（特殊なタイプの取引）の品質をチェックするロールを持ちます。
これにより、トランザクションをネットワークに組み込むかどうかを決めるバンドラー（トランザクションをまとめるエンティティ）が、どのトランザクションをメモリプールに保持するべきかをより安全に判断できるようになります。

この仕組みを利用するためには、スマートコントラクトウォレットの開発者が自身のウォレットに合わせたエンドーサーコントラクトを作成し、イーサリアムネットワークにデプロイする必要があります。
既に存在する互換性のあるエンドーサーコントラクトを使用することも可能です。
これにより、ウォレットはより柔軟で高機能なものになり、イーサリアムの使用体験が向上します。

:::note info
**ERC4337**と同じ課題を解決する提案ですが、より制約の少ないフレームワークを提案しています。
詳しくは以下を参考にしてください。
:::

https://ethereum-magicians.org/t/erc-5189-account-abstraction-via-endorsed-operations/9799

# 動機

このアカウント抽象化（AA）の提案は、イーサリアムネットワークにおける新しいトランザクション処理システムを導入しようとしています。
このシステムは以下のような特徴を持っています。

## アカウント抽象化の主要目標
これにより、ユーザーは従来の外部所有アカウント（EOA）ではなく、自由に検証と実行ロジックを設定できるスマートコントラクトウォレットをメインアカウントとして使用できるようになります。

## 分散化
このシステムは、どのバンドラーもAAトランザクションを含むプロセスに参加できるようにし、活動を公開されたメモリプールで行い、集中化されたリレイヤーに依存しない構造を提供します。
また、無効や悪意のあるペイロードからメモリプールを保護するための構造を提供し、バンドラー、開発者、ウォレット間の信頼の仮定を避けます。

## 既存のスマートコントラクトウォレットサポート
既に活動しているスマートコントラクトウォレットと連携し、それぞれのウォレットインスタンスを手動でアップグレードする必要なく、既存のウォレットとの互換性を確保します。

## 制約のないフレームワーク提供
スマートコントラクトウォレットは様々なデザイン、制限、機能を持っていますが、この提案はこれらの異なるバリエーションに対応するよう設計されています。

## オーバーヘッドのないサポート
スマートコントラクトウォレットはEOAよりもコストがかかりますが、この提案は現在のコスト状況を悪化させることはありません。

## 他のユースケースへのサポート
プライバシーを保護するアプリケーション、原子的な複数操作（**EIP3074**に似ています）、**ERC20**トークンを使用したトランザクション手数料の支払い、ユーザーの入力なしにスマートコントラクトをスケジュール実行、一般的なリレイヤーが必要なアプリケーションなど、様々な用途に対応しています。

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

https://chaldene.net/erc20

# 仕様

このイーサリアムのアカウント抽象化（AA）提案では、イーサリアムの基本的な合意形成メカニズムを変更せずに、AAトランザクションを効率的に扱う方法を提案しています。
このシステムでは、新しいトランザクションタイプを作成する代わりに、「**Operation**」という構造体を使用してAAトランザクションを管理します。

「**Operation**」とは、以下の情報を含む構造体です。

| フィールド | 型 | 説明 |
| :-------: | :-: | :---: |
| entrypoint | address | オペレーションを実行するために`callData`と共に呼び出されるコントラクトのアドレスです。 |
| callData | bytes | オペレーションを実行するためにエントリポイントの呼び出しに渡されるデータです。 |
| gasLimit | uint64 | オペレーションを実行する際に必要な最小のガスリミットです。 |
| feeToken | address | バンドラーに返済するために使用される**ERC20**トークンのコントラクトアドレスです（ネイティブトークンの場合はaddress(0)）。 |
| endorser | address | オペレーションを検証するために使用されるエンドーサーコントラクトのアドレスです。 |
| endorserCallData | bytes | `isOperationReady()`を呼び出す際にエンドーサーに渡される追加データです。 |
| endorserGasLimit | uint64 | オペレーションを検証する際にエンドーサーに渡されるガス量です。 |
| maxFeePerGas | uint256 | オペレーション実行に期待される最大ベースフィーの金額です（**EIP1559**の`max_fee_per_gas`に似ています）。 |
| priorityFeePerGas | uint256 | オペレーション実行に期待されるバンドラーへの固定手数料の金額です（EIP-1559のmax_priority_fee_per_gasに似ています）。 |

これらのフィールドは、オペレーション（トランザクション）が正しく実行されるために必要な情報を提供します。

これらの「**Operation**」オブジェクトは専用のメモリプールに送信され、バンドラー（ブロックを生成する特別なコードを実行するエンティティ、またはブロックプロデューサーにトランザクションを中継するユーザー）がこれを監視し、トランザクションを実行します。

トランザクションは、提供されたコールデータを使ってエントリポイントを呼び出すことで実行されます。
エントリポイントは、一般的にウォレットコントラクト自体か、ウォレットをデプロイしてトランザクションを実行するための中間ユーティリティコントラクトになります。

## エンドユーザー機能

この提案において、エンドーサーはメモリプール内で「**良いオペレーション**」と「**悪いオペレーション**」を区別する役割を果たします。
「**良いオペレーション**」はバンドラーへの手数料を適切に支払うものであり、「**悪いオペレーション**」は支払いが不足しているか、全く機能しないものを指します。

```javascript
interface Endorser {
  struct BlockDependency {
    uint256 maxNumber;
    uint256 maxTimestamp;
  }

  struct Dependency {
    address addr;
    bool balance;
    bool code;
    bool nonce;
    bool allSlots;
    bytes32[] slots;
  }

  function isOperationReady(
    address _entrypoint,
    bytes calldata _data,
    bytes calldata _endorserCallData,
    uint256 _gasLimit,
    uint256 _maxFeePerGas,
    uint256 _maxPriorityFeePerGas
  ) external view returns (
    bool readiness,
    BlockDependency memory blockDependency,
    Dependency[] memory dependencies
  );
}
```

## 構造体

---

### BlockDependency

```javascript
struct BlockDependency {
    uint256 maxNumber;
    uint256 maxTimestamp;
}
```

**概要**

ブロックの依存関係を表す構造体。

**詳細**

この構造体は特定のブロックの最大ブロック番号と最大タイムスタンプを保持します。


**パラメータ**

- `maxNumber`
    - 依存するブロックの最大ブロック番号。
- `maxTimestamp`
    - 依存するブロックの最大タイムスタンプ。

---

### Dependency

```javascript
struct Dependency {
    address addr;
    bool balance;
    bool code;
    bool nonce;
    bool allSlots;
    bytes32[] slots;
}
```

**概要**

コントラクトの依存関係を表す構造体。

**詳細**

この構造体はコントラクトのアドレス、バランス、コード、ノンス、スロットなどの依存情報を保持します。

**パラメータ**

- `addr`
    - 依存するコントラクトのアドレス。
- `balance`
    - コントラクトの残高情報に依存するかどうかを示すフラグ。
- `code`
    - コントラクトのコード情報に依存するかどうかを示すフラグ。
- `nonce`
    - コントラクトのノンス情報に依存するかどうかを示すフラグ。
- `allSlots`
    - すべてのスロット情報に依存するかどうかを示すフラグ。
- `slots`
    - 依存するスロットのリスト。

---

## 関数

---

### isOperationReady

```javascript
function isOperationReady(
    address _entrypoint,
    bytes calldata _data,
    bytes calldata _endorserCallData,
    uint256 _gasLimit,
    uint256 _maxFeePerGas,
    uint256 _maxPriorityFeePerGas
) external view returns (
    bool readiness,
    BlockDependency memory blockDependency,
    Dependency[] memory dependencies
);
```

**概要**

オペレーション（操作）が実行可能か確認する関数。

**詳細**

この関数は、特定のオペレーションが実行可能かどうかを判断します。
実行可能かどうかは、指定された引数と依存関係によって決定されます。
関数は、オペレーションの実行準備ができているかどうかを示す真偽値を返し、オペレーションの実行に必要なブロックの依存関係と依存コントラクトの情報も提供します。

**引数**

- `_entrypoint`
    - エントリーポイントコントラクトのアドレス。
- `_data`
    - オペレーションデータ。
- `_endorserCallData`
    - エンドーサーコールデータ。
- `_gasLimit`
    - ガス制限。
- `_maxFeePerGas`
    - ガスごとの最大手数料。
- `_maxPriorityFeePerGas`
    - ガスごとの最大優先手数料。

**戻り値**

- `readiness`
    - オペレーションの実行準備ができている場合は`true`、そうでない場合は`false`。
- `blockDependency`
    - オペレーションの実行に必要なブロックの依存関係情報。
- `dependencies`
    - オペレーションの実行に必要な依存関係情報のリスト。

---

エンドーサーは、上記の特定のインターフェースを実装したスマートコントラクトとしてデプロイされる必要があります。
このインターフェースには、トランザクションが準備完了かどうかを判断するための`isOperationReady`関数が含まれています。
この関数は、オペレーションが実行可能かどうか（`readiness`）、ブロック依存性（`blockDependency`）、及び依存関係のリスト（`dependencies`）を返します。
これらの情報は、メモリプールの運営者が正しく機能するAAトランザクションのプールを維持するのに役立ちます。

また、エンドーサーは**EndorserRegistry**に登録されるべきであり、登録のためには最低限のETHを`burn`させる必要があります。
これは、サービス妨害攻撃へのリスクを減らすための措置です。
ただし、メモリプールの運営者はETHを`burn`させていないエンドーサーからのオペレーションを受け入れることもできますが、その場合はリスクが増加します。

エンドーサーは`isOperationReady`関数を通じてオペレーションの準備状況を評価し、その結果に基づいてメモリプールの運営者がオペレーションを適切に管理できるようにサポートします。
なお、効率を高めるために、エンドーサーには`_endorserCallData`を用いて追加情報を提供することが可能です。
この場合、エンドーサーは提供された`_endorserCallData`が有効であり、他の提供された値に関連していることを確認する必要があります。

## ブロックの依存関係

エンドーサーがオペレーションの「**readiness（準備完了状態）**」が有効である期間を設定するために使用するフィールドです。
具体的には、以下の二つのフィールドが含まれます。

| フィールド     | 説明 |
|----------------|----------------------------------------------------------------------------------------------------------------------|
| maxNumber      | `readiness`が適用される`block.number`の最大値です。<br />オペレーションが特定の期間内のみ有効である場合に役立ちます。 |
| maxTimestamp   | `readiness`が適用される`block.timestamp`の最大値です。<br />こちらも、オペレーションが特定の時間内のみ有効である場合に使用されます。 |

これらの値は、エンドーサーによって設定され、オペレーションが有効とされる期間を制限するために使用されます。
もしエンドーサーがオペレーションの有効性を無期限と判断した場合、これらのフィールドは`type(uint256).max`（最大値）に設定されることになります。
これにより、オペレーションの実行可能性の有効期限を特定のブロック番号やタイムスタンプに制限することが可能となります。

## 依存関係

オペレーションが正しく実行されるためにエンドーサーが考慮すべき特定のコントラクトの特性や状態を指します。
これらはオペレーションの実行可能性に影響を与える要素として重要です。
以下が各フィールドの詳細な説明です。

| フィールド             | 説明 |
|-------------------------|-----------------------------------------------------------------------------------|
| アドレス（addr）        | 依存関係となる特定のコントラクトのアドレス。<br />同じアドレスに対して複数のエントリは許可されません。 |
| バランス（balance）     | `addr`のバランスがオペレーションの実行に影響を及ぼす場合、このフィールドは`true`に設定されます。 |
| コード（code）          | `addr`のコードがオペレーションに影響を与える場合、このフィールドは`true`に設定されます。 |
| ノンス（nonce）         | `addr`のノンスがオペレーションの実行に影響を与える場合、このフィールドが`true`になります。 |
| 全ストレージスロット（allSlots） | `addr`のすべてのストレージスロットがオペレーションの依存関係になる場合、このフィールドは`true`に設定されます。 |
| ストレージスロットのリスト（slots） | オペレーションの実行に影響を与える可能性がある、`addr`の特定のストレージスロットのリストです。 |

エンドーサーは、オペレーションの準備完了状態に影響を与える可能性のあるストレージスロットのみを依存関係リストに含める必要があります。
`allSlots`と`slots`は相互に排他的であり、`allSlots`がtrueの場合、`slots`は空の配列であるべきです。
エンドーサーは、可能な限り`allSlots`より`slots`を使用することが推奨されます。

例として、ウォレットが**WETH**を使用して手数料を支払う場合、エンドーサーコントラクトは`isValidOperation()`を実行する際に**WETH**コントラクトの`balanceOf`メソッドを呼び出して、ウォレットに十分な**WETH**バランスがあるかどうかを確認します。
この場合、**WETH**コントラクトのETHバランスやコードにもアクセスされますが、エンドーサーはこのオペレーションにおいてユーザーの**WETH**バランスのみを重視し、他の要素は依存関係として含めないことがあります。

## 不正行為の検出

エンドーサーコントラクトが予期しないまたは悪意のある振る舞いをする可能性について説明しています。
具体的には以下のような問題が考えられます。

### 1. 手数料不足の問題
エンドーサーコントラクトがオペレーションを準備完了と判断しても、実際に実行された際にバンドラーに約束された手数料より少ない金額を送金する可能性があります。

### 2. 実行失敗の問題
オペレーションが準備完了と判断されたにもかかわらず、実行時にトップレベルのコールが失敗することがあります。

### 3. 依存関係の変化なしに準備完了状態が変わる問題
依存関係に変化がないにもかかわらず、エンドーサーコントラクトがオペレーションの準備完了状態を「**準備完了**」から「**準備未完了**」に変更することがあります。

バンドラーは、オペレーションの依存関係に変化があった場合、常に準備完了状態を破棄し、再評価する必要があります。
これにより、準備完了とされるオペレーションのみが次のブロックを構築するための候補となります。

バンドラーがオペレーションの最終的な含まれることをシミュレートした時に、正しい支払いが行われないこと（トランザクションが失敗するか、送金額が定められた手数料より少ない場合）が判明した場合、バンドラーはエンドーサーを禁止するべきです。
その理由としては、オペレーションがブロックに含まれるべきではないにもかかわらず`isOperationReady()`が`true`を返すことや、依存関係に変化がないにもかかわらず準備完了状態が`true`から`false`に変わることが挙げられます。

エンドーサーが禁止された後、メモリプールの運営者は、そのエンドーサーに関連するすべてのオペレーションを排除すべきです。

> Notice: The mempool operator could call one last time isOperationReady to determine if the endorser should be banned because (1) or (2), but this step is not strictly necessary since both scenarios lead to the endoser being banned.

注意点として、メモリプールの運営者はエンドーサーを禁止する前に最後にもう一度`isOperationReady`を呼び出すことで、禁止の理由が(1)と(2)か(3)を判断することができますが、これは必須ではありません。
なぜなら、どちらの場合もエンドーサーの禁止につながるからです。

## オペレーションを受け取った際のバンドラーの振る舞い

「バンドラーがAAトランザクションを効果的に処理し、その中継に対して報酬を受け取るために行うべき基本的な手順について説明しています。
以下がその手順です。

1. **バンドラーが行うべき基本チェック**
   - エンドーサーコントラクトが指定したガスリミット（`endorserGasLimit`）が`MAX_ENDORSER_GAS`以下であることを確認します。
   - エンドーサーコントラクトが正しく登録され、必要な最低限のETH（`MIN_ENDORSER_BURN`）を`burn`しており、禁止されていないことを確認します。
   - オペレーションのガスリミットが非ゼロ値のCALLを行うのに十分であることを確認します。
   - 手数料トークンが`address(0)`、またはバンドラーが受け入れ可能としている**ERC20**トークンであることを確認します。
   - オペレーションの`maxFeePerGas`と`priorityFeePerGas`がバンドラーの設定する最低値以上であることを確認します。

2. **メモリプール内の他のオペレーションとの比較**
   - 同じ依存関係とエンドーサーアドレスを持つ他のオペレーションがメモリプール内に存在する場合、新たに受け取ったオペレーションの`maxFeePerGas`と`priorityFeePerGas`は、既存のものよりも`12%`高く設定する必要があります。

:::note info
`maxFeePerGas`と`priorityFeePerGas`を既存のオペレーションよりも`12%`高く設定する必要がある理由は、主にメモリプール内の競争と優先順位の管理に関連しています。
このルールは、次のような目的で設計されています：

### メモリプール内のトランザクション競争を管理する
- ブロックチェーンのメモリプールでは、限られたスペースの中で多くのトランザクションがブロックに組み込まれる機会を競っています。
- バンドラー（トランザクションをブロックに組み込む者）は、より高い手数料を提供するトランザクションを優先してブロックに組み込む傾向があります。

### トランザクションの優先順位を設定する
`12%`という値は、既存のトランザクションと新しいトランザクションの間で明確な優先順位の差を設けるために設定されています。
これにより、新しいトランザクションがメモリプール内で優先され、より迅速に処理される可能性が高まります。

### スパムトランザクションの防止
- このような規則は、メモリプールを無差別に満たす低手数料のスパムトランザクションを防ぐのにも役立ちます。
- トランザクションがメモリプールに残るためには、他と比較して明らかな手数料の優位性を持つ必要があるためです。

### ネットワークの健全性を維持する
- このようなメカニズムは、ネットワークの過負荷を防ぎ、メモリプールの健全性を保つのに寄与します。
- トランザクションが適切に価格設定され、資源の浪費を防ぐことができます。

この`12%`という具体的な数字は、十分な差を設けつつも過度に高くなりすぎないようにバランスを取るための一つの基準です。
この値は、ネットワークの特性やバンドラーの戦略によって異なる場合があります。
:::

3. **`isOperationReady()`の呼び出しとオペレーションの処理**
   - 上記のチェックに合格した場合、バンドラーはエンドーサーコントラクトの`isOperationReady()`を呼び出します。
   - このメソッドがオペレーションの準備完了（`readiness == true`）と判断した場合のみ、オペレーションはメモリプールに追加されます。
   - そうでない場合はオペレーションは破棄されます。

4. **依存関係の変更に伴う再評価**
   - 依存関係に変更があった場合、オペレーションの準備完了状態は再評価されます。
   - もし準備完了状態が`false`に変わった場合は、オペレーションは破棄されます。

5. **ブロック組み込み前の最終シミュレーション**
   - オペレーションをブロックに組み込む前に、エンドーサーコントラクトを呼び出すことなく最終的なシミュレーションが行われます。
   - このシミュレーションで問題が発生した場合、エンドーサーコントラクトは禁止される可能性があります。

6. **シミュレーション失敗時のエンドーサーコントラクトの禁止**
   - オペレーションのシミュレーションが失敗した場合、エンドーサーコントラクトは誤った準備完了状態を返したか、依存関係に関係なくオペレーションの準備完了状態を変更したために禁止されます。

7. **準備完了状態の無効化**
   - 指定されたオペレーションより前にキューに入れられたトランザクションやオペレーションが、依存関係として指定されたストレージスロットを変更した場合、オペレーションの準備完了状態は無効となります。

これらの手順により、バンドラーは効率的かつ安全にAAトランザクションを処理し、その中継に対する報酬を確実に受け取ることができます。

## オペレーションルール

メモリプールのクライアントが悪意のあるトランザクションから保護するために追加で実装できるルールについて述べています。
これらのルールはメモリプールの安全性と効率を高めることを目的としています。

### 依存関係のサイズ制限
メモリプールのクライアントは、受け入れる依存関係のサイズを「`MAX_OPERATION_DEPENDENCIES`」という設定値以下に制限することができます。
これにより、設定値を超える依存関係を持つオペレーションは破棄されます。

### 再評価回数の制限
オペレーションが再評価を必要とする回数にも「`MAX_OPERATION_REEVALS`」という上限を設けることができます。
この上限を超えるオペレーションは、再評価の回数が多すぎると判断され、破棄されます。

### メモリプール内のオペレーション数の制限
同じ依存関係スロットに依存するオペレーションの数に制限を設けることもできます。
これにより、特定の依存関係に集中するオペレーションの過剰な蓄積を防ぐことができます。

これらのルールが広く採用されると、ウォレット開発者は依存関係の使用を最小限に抑えるようになります。
この目的は、メモリプールをより効率的かつ安全に管理するために、不必要な負荷やリスクを避けることです。

## 評価

バンドラーがAAトランザクションを適切に処理するために行うべき評価プロセスについて説明しています。
これは、オペレーションがブロックに含まれる準備ができているかを判断するための重要な手順です。
具体的な流れは以下の通りです。

1. **`isOperationReady()`の呼び出し**
   - バンドラーは、オペレーションを評価するためにエンドーサーコントラクトの`isOperationReady()`メソッドを呼び出します。
   - この時、ガスリミットはエンドーサーが指定した`endorserGasLimit`以上でなければなりません。

2. **結果に基づくオペレーションの扱い**
   - `isOperationReady()`の呼び出しが失敗したり、エンドーサーが準備完了ではない（`readiness == false`）と返した場合、そのオペレーションはメモリプールから排除されるべきです。
   - 逆に、呼び出しが成功し、準備完了（`readiness == true`）という結果が返された場合は、オペレーションはメモリプールに保持され、ブロックの構築に使用されることができます。

このプロセスにより、バンドラーはオペレーションがブロックに組み込むために適切であるかどうかを適切に判断できます。
エンドーサーコントラクトによる`isOperationReady()`の評価結果は、オペレーションが実行可能かどうかを示す重要な情報源となり、バンドラーのオペレーションの取り扱いに直接影響を与えます。

## オペレーションの組み込み後

バンドラーがオペレーションをブロックに組み込んだ後の対応方法について説明しています。
このプロセスの要点は以下の通りです。

### オペレーションの再実行制限の欠如
現行のルールでは、オペレーションが一回限りで実行されるべきだという制限は設けられていません。
つまり、オペレーションは複数回実行される可能性があります。

### オペレーションのメモリプールでの維持
バンドラーは、オペレーションをブロックに組み込んだ後、それをメモリプールから削除してはなりません。
オペレーションはメモリプール内に残し、エンドーサーコントラクトの`isOperationReady()`を最後に一度呼び出す必要があります。

### エンドーサーの準備完了状態の確認
もしエンドーサーコントラクトが、オペレーションのブロック組み込み後も準備完了（`readiness == true`）を返す場合、そのオペレーションは他の健全なオペレーションと同様に扱われ、メモリプール内に保持される可能性があります。

このガイドラインに従うことで、バンドラーはオペレーションを効率的に管理し、必要に応じて再度ブロックに組み込む準備をすることができます。
`isOperationReady()`の結果は、オペレーションが引き続き実行に適しているかどうかを判断するための重要な指標です。

## エンドーサーレジストリ

エンドーサーコントラクトの信頼性を示すために、ETHを`burn`登録するシステムです。
このシステムの主な機能と目的は以下になります。

### `burn`の登録
エンドーサーレジストリは、各エンドーサーコントラクトに対して行われたETHの`burn`量を記録します。
これにより、エンドーサーコントラクトの信頼性や責任感を示す指標となります。

### `addBurn()`関数の使用
誰でも`addBurn()`関数を使用して、任意のエンドーサーコントラクトの`burn`量を増やすことができます。
これにより、エンドーサーコントラクトへの信頼を外部から高めることが可能になります。

### `burn`されたETHの永久的なロック
レジストリで`burn`されたETHは事実上永遠にロックされ、取り戻すことはできません。
これは、オンチェーン上でのスラッシング（罰則）を確実に証明することが現在のプロトコルでは難しいためです。

### 仮想イベントとしてのスラッシング
スラッシングは、実際には発生しない仮想のイベントとして扱われ、メモリプールの運営者は預けられたETHを無視することになります。

エンドーサーレジストリはエンドーサーコントラクトの責任感や信頼性を高めるためのツールですが、`burn`されたETHは実際には取り戻せないため、主に信頼度の向上に寄与するシステムと言えます。

### 参考実装

```javascript
// SPDX-License-Identifier: UNLICENSED
pragma solidity ^0.8.15;

contract EndorserRegistry {
  event Burned(
      address indexed _endorser,
      address indexed _sender,
      uint256 _new,
      uint256 _total
  );

  mapping(address => uint256) public burn;

  function addBurn(address _endorser) external payable returns (uint256) {
    uint256 total = burn[_endorser] + msg.value;
    burn[_endorser] = total;

    emit Burned(_endorser, msg.sender, msg.value, total);

    return total;
  }
}
```

# 補足

## グリーフィング防止

スマートコントラクトウォレットを基盤としたアカウント抽象化システムにおけるDoS（サービス拒否）攻撃への対応策について説明しています。

:::note info
**アカウント抽象化システムにおけるDoS（サービス拒否）攻撃**

アカウント抽象化とは、イーサリアムのようなブロックチェーンにおいて、ユーザーのアカウントをより柔軟に扱うためのシステムです。
通常、ブロックチェーンでは**「外部所有アカウント（EOA）**」と「**スマートコントラクト**」の2種類のアカウントがあります
。EOAは個々のユーザーが所有し、プライベートキーで管理されます。
一方、スマートコントラクトはコードによって管理され、より複雑なロジックや操作を実行できます。

アカウント抽象化では、これらの区別をなくし、すべてのアカウントをスマートコントラクトのように扱うことができます。
これにより、ユーザーは自分のアカウントにカスタムロジックやセキュリティ機能を追加できるようになります。

しかし、このシステムにはDoS攻撃のリスクが伴います。
DoS攻撃とは、サービスを過度に利用または悪用することにより、システムの正常な機能を妨害する行為です。
アカウント抽象化の文脈では、特に次のようなリスクが考えられます。

- **リソースの消費**
    - 攻撃者が複雑な操作を含むスマートコントラクトを大量に作成し、ネットワークのリソースを過度に消費することで、正常なトランザクションの処理を遅延させたり妨害したりする可能性があります。

- **メモリプールの混雑**
    - スマートコントラクトによる操作が増えると、それらを処理するためのトランザクションがメモリプールに溜まります。
    - 不必要または悪意のあるトランザクションが多くなると、メモリプールが混雑し、正当なトランザクションの処理が妨げられる可能性があります。

- **バンドラーへの影響**
    - トランザクションをブロックに組み込むバンドラーは、各トランザクションを適切に評価し処理する必要があります。
    - 攻撃者が複雑なスマートコントラクトを使用してシステムを悪用すると、バンドラーの負担が増大し、ネットワークの効率が低下する可能性があります。

これらのリスクに対処するため、アカウント抽象化システムでは通常、トランザクションの検証や処理の方法を工夫する必要があります。
例えば、エンドーサーコントラクトの導入やトランザクションの優先順位付けなどが挙げられます。
これにより、DoS攻撃のリスクを減らしつつ、アカウントの柔軟性と機能性を高めることが目指されています。
:::

このシステムの主要な課題と解決策は以下の通りです。

### オペレーションの実行と報酬の保証
バンドラーは、オペレーションを実行することなく、そのオペレーションから報酬を得ることができる保証が必要です。
しかし、オペレーションの健全性を確認するために全体を実行することは、コストと複雑性の点で問題があります。

### 実行の難しさ
オペレーションを完全に実行することは、以下の理由により困難です。
     - バンドラーは減らされたガス量でのシミュレーションができず、全ガスリミットを使用する必要があり、これによりグリーフィングのリスクが増加します。
     - 状態の変更がオペレーションに影響を及ぼすかどうかをバンドラーが知る方法がないため、すべての変更後にオペレーションを再評価する必要があります。
     - 状態の変更がメモリプールの大部分を無効にするかどうかも不明です。

### エンドーサーコントラクトの導入
この提案では、バンドラーが任意のオペレーションを制御された方法で検証できるようにエンドーサーコントラクトが導入されています。
これにより、バンドラーはオペレーションの内部動作を知らずに済みます。

### 責任のウォレット開発者への移行
ウォレット開発者は、エンドーサーコントラクトをコーディングし、デプロイし、ETHを`burn`させる必要があります。
このシナリオは理想的で、開発者は自身のウォレットオペレーションを理解しているため、これらを効率的に評価するツールを構築できます。

### 仕様の簡素化
仕様はシンプルに保たれており、スマートコントラクトウォレットトランザクションに対する高度に構造化された振る舞いを強制しないため、新しいタイプのウォレットや共有標準の採用が停滞することはありません。

このシステムにより、バンドラーはオペレーションを安全かつ効率的に検証し、グリーフィング攻撃のリスクを最小限に抑えることができます。

:::note info
**グリーフィング攻撃（Griefing Attack）**

オンラインゲームやデジタルコミュニティにおいて、他のプレイヤーやユーザーに意図的に迷惑をかける行為です。
この攻撃は、他者の楽しみを妨げたり、ゲーム内での活動を妨害することを目的としています。
グリーフィングは、攻撃者にとって特に利益をもたらさないことが多く、単に他人を困らせたりゲームの経験を台無しにしたりするために行われます。

例えば、オンラインゲームにおけるグリーフィング行為には以下のようなものがあります。

- **故意にチームメイトを妨害する**
    - 味方を攻撃する、ゲームの目的に反する行動をとるなど。
- **リソースの破壊や盗難**
    - 他のプレイヤーが築いた建築物を破壊したり、アイテムを盗んだりする。
- **チャットでの迷惑行為**
    - 不快な言葉を使ったり、スパムメッセージを送ったりする。

グリーフィングは、プレイヤー間のコミュニティの雰囲気を悪化させ、ゲーム体験を損なうことから、多くのオンラインゲームでは禁止されています。

ブロックチェーンやスマートコントラクトの文脈では、グリーフィング攻撃はシステムを悪用して他のユーザーやプロセスを妨害する行為を指します。
例えば、意図的にネットワークを混雑させたり、リソースを過剰に消費させるトランザクションを発行することが含まれます。
これらの行為は、ネットワークの効率を低下させ、他のユーザーの操作を妨害することを目的としています。
:::

## `burn`されたETH

エンドーサーコントラクトに関連する重要な側面について説明しています。
ここでの主要なポイントは以下の通りです。

### エンドーサーコントラクトのデプロイ
誰でもエンドーサーコントラクトをデプロイすることが可能です。
ウォレットクライアントは、どのエンドーサーコントラクトを特定のトランザクションに使用するかを決定します。

### エンドーサーレジストリの活用
バンドラーは、個別のオフチェーンレジストリに依存する代わりに、エンドーサーレジストリを使用して要求されたエンドーサーコントラクトが存在し、それにどれだけのETHが`burn`されたかを確認できます。

### `burn`されたETHの閾値設定
バンドラーは、エンドーサーコントラクトが受け入れられるために必要な`burn`されたETHの最低量を自身で設定することができます。

### レジストリ外のエンドーサーコントラクトのサポート
バンドラーは、レジストリに含まれていないエンドーサーコントラクトや、レジストリに含まれていても関連する`burn`されたETHがないエンドーサーコントラクトをサポートする自由があります。

これにより、バンドラーはトランザクションをより効率的に管理し、信頼できるエンドーサーコントラクトを使用することが可能になります。
`burn`されたETHの量は、エンドーサーコントラクトの信頼性を示す指標として機能し、バンドラーがその信頼性を評価する際の基準となります。

## 最小のオーバーヘッド

アカウント抽象化（AA）トランザクションがどのようにして効率的に処理されるかについて述べています。
このシステムの特徴は以下の通りです。

### オフチェーンでのAAトランザクション検証
AAトランザクションの検証はトランザクションが実行される時ではなく、事前にオフチェーンで行われます。
この検証はバンドラーによって実施されます。
バンドラーは、ブロックチェーン上でトランザクションをブロックに組み込む役割を担います。

### 追加のガス料金のオーバーヘッドがない
このプロセスにより、AAトランザクションを実行する時に追加のガス料金のオーバーヘッドが発生することはありません。
通常、トランザクションの実行にはガス料金が必要ですが、このシステムではその追加コストがかかりません。

### リスクはバンドラーが負担
トランザクションの検証に伴うリスクは、全てのユーザーではなくバンドラーが負担します。
これにより、各ユーザーがセキュリティのために追加料金を支払う必要がなくなります。

結果として、AAトランザクションによる追加のコストはユーザーには影響せず、バンドラーが効率的にリスクを管理することで、トランザクションはより経済的に処理されます。
このシステムは、ネットワーク全体の負担を軽減し、ユーザーに低コストでのトランザクション実行を可能にします。

## 代替案との相違点

この提案は以下の点代替案と異なります。

### 制約の不要
この提案では、ウォレットはEVMの機能を制限する必要がありません。
他の提案では制約がある場合があります。

### リプレイプロテクションロジックの指定なし
この提案ではリプレイプロテクションロジックが指定されていません。
代わりにノンス(`nonce`)を使って制御します。

### 事前デプロイロジックの指定なし
この提案では事前デプロイロジックが必要ありません。
エントリーポイントで処理可能です。

### 信頼性の高いエントリーポイントコントラクトの受け入れなし
この提案ではウォレットは信頼性の高いエントリーポイントコントラクトからのトランザクションを受け入れなくても良いです。

### 実行と署名ペイロードの区別なし
実行と署名のペイロードの区別は実装に依存します。

これらの違いにより、この提案は柔軟性を持ち、既存のウォレットとの互換性を維持しながら、セキュリティと効率性を向上させます。

# 後方互換性

このEIPはコンセンサスレイヤーを変更するものではなく、既存のスマートコントラクトウォレットに変更を課すものでもないため、後方互換性の問題はありません。

# セキュリティ考慮事項

このEIP（Ethereum Improvement Proposal）は、オンチェーンのやり取りに変更を加えません。
エンドーサーは明示的にオフチェーンの検証のためのものです。

バンドラーは自身のセキュリティを管理し、ブロックに含めるトランザクションに対して支払いを受ける責任を持っています。

# 引用

Agustín Aguilar (@agusx1211), Philippe Castonguay (@phabc), Michael Standen (@ScreamingHawk), "ERC-5189: Account Abstraction via Endorsed Operations [DRAFT]," Ethereum Improvement Proposals, no. 5189, June 2022. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-5189.

# 最後に

今回は「既存のコントラクトウォレットとの互換性を維持しながら、プロトコルの変更を回避するアカウント抽象化のの仕組みを提案している規格である**ERC5189**」についてまとめてきました！
いかがだったでしょうか？

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