# [ERC7521] コントラクトウォレットで新しいインテント規格に簡単に対応できる仕組みを理解しよう！

> この内容は、新しいインテント規格に対応するための汎用的なエントリーポイントコントラクトに関するものです。

- URL: https://cardene.dev/articles/f9468a5fe68c1a123574
- 公開日: 2023-10-17
- 更新日: 2023-10-17
- トピック: Blockchain
- タグ: ethereum, solidity, smartcontract, ブロックチェーン

## はじめに

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

https://cryptogames.co.jp/

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

https://cryptospells.jp/

今回は、コントラクトウォレット用の標準化されたインテント仕様を提案し、署名時に現在・将来のインテント構造を承認する仕組みを提案している規格である**ERC7521**についてまとめていきます！

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

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

:::message alert
**7521**は現在（2023年10月15日）では「**Draft**」段階です。
:::

## 概要

この内容は、新しいインテント規格に対応するための汎用的なエントリーポイントコントラクトに関するものです。
従来、スマートコントラクトウォレットは新しいインテント規格に対応するために頻繁にアップグレードする必要がありましたが、この新しいアプローチでは、単一のエントリーポイントコントラクトが署名の検証を担当し、その後の低レベルなインテントデータの処理と定義を、ユーザーがインテントを署名する時に指定した他のコントラクトに委託します。
これらの署名済みメッセージは**UserIntent**と呼ばれ、MEV（最大効用者価値）サーチャーが検索し、自身の**UserIntent**と組み合わせるために、さまざまなメンプール戦略を使用して共有されます。
MEVサーチャーは、構築した**IntentSolution**と呼ばれるオブジェクトを作成し、それをトランザクションにパッケージ化して、特別なコントラクトに対して**handleIntents**呼び出しを行います。
このトランザクションは、通常のMEVチャネルを介して最終的にブロックに含まれるまで進行します。

:::message
**インテント**
スマートコントラクトやブロックチェーン上で特定のアクションや操作の意図を定義するための規則や標準のことです。
これは、ブロックチェーンベースのアプリケーションやプラットフォームで、ユーザーが特定のタスクを実行するためにどのような情報やパラメータを提供する必要があるかを明確にする役割を果たします。

具体例を挙げて説明します。
例えば、仮想通貨のトランザクションを行う場合、インテント規格は次のような情報を定義することがあります。

1. 送金の金額
    - ユーザーがどれだけの仮想通貨を送金するかを指定します。
2. 送金先アドレス
    - 送金の相手の仮想通貨アドレスを指定します。
3. 送金手数料
    - トランザクション処理にかかる手数料の金額を指定します。

これらの情報は、トランザクションの意図や目的を明確にし、スマートコントラクトやブロックチェーンノードがトランザクションを正しく処理するために必要です。
インテント規格は、ユーザーがこれらの情報を指定する方法や形式を標準化し、異なるアプリケーションやプラットフォーム間で互換性を確保するのに役立ちます。

インテント規格は、ブロックチェーン上での操作やトランザクションの意図を明確にし、異なるシステム間でスムーズなやり取りを可能にするためのルールや標準です。
:::

## 動機

**[ERC4337のエントリーポイントコントラクトの使用によるアカウント抽象化](https://eips.ethereum.org/EIPS/eip-4337)** も参照してください。

:::message
**ERC4337**については以下を参考にしてください。
:::

https://mirror.xyz/0xcE77b9fCd390847627c84359fC1Bc02fC78f0e58/-qoixMc413uT4FFM61uhXYUiL05Hw-wahq9hV_JtjJs

[\[ERC4337\] プロトコルの変更をせずにAAを実装する仕組みを理解しよう！](/articles/8c97ca7c93c4557ebfc2)

この提案は、将来のスマートコントラクトウォレットにおいて、新しいインテント規格に対応できる柔軟なインターフェースを提供するために、同じエントリーポイントコントラクトのアイデアを活用しています。以下はこの提案の主な目標です。

#### ユーザーに対するインテントの有効化

ユーザーが、スマートコントラクトウォレット内で特定の操作や意図を指定できるようにします。
これにより、ユーザーはスマートコントラクトがどのようなアクションを実行するかを制御できます。

#### 分散化

署名されたインテントの解決プロセスに、どのMEVサーチャーでも参加できるようにします。
これにより、プロセスが中央集権化されず、多くの参加者が協力できます。

#### 独自のインテント規格定義

新しいインテント規格を開発する開発者は、ユーザーが署名時に選択できるように、独自の規格を追加できます。
これにより、インテントのカスタマイズが可能になります。

#### 将来のインテント規格との互換性

未来のインテント規格が登場した場合、それに対応できるように、現在の実行コンテキストに関する情報へのアクセスを提供するインテント規格インターフェースを定義します。

#### 最小限のガスコスト

一般的な使用ケースにおいて、ガスの効率を最適化するために、エントリーポイントコントラクトに一部の重要なインテント処理ロジックを組み込みます。

#### ユーザーエクスペリエンスの向上

ユーザーが新しいインテント規格を使用したい場合に、スマートコントラクトウォレットのアップグレードが不要で、複雑なインテントの組み合わせを容易にします。

この提案は、スマートコントラクトウォレットとブロックチェーン上でのインテントの管理を効率化し、ユーザーと開発者の柔軟性と利便性を向上させることを目指しています。

## 仕様

以下は、ユーザーがスマートコントラクトウォレットに含めたいインテント情報です。

| フィールド     | タイプ      | 説明                              |
|--------------|------------|-----------------------------------|
| standard     | bytes32    | インテント規格の識別子。            |
| sender       | address    | 操作を行うウォレットのアドレス。    |
| nonce        | uint256    | アンチリプレイパラメータ。            |
| timestamp    | uint256    | 時間の有効性パラメータ。               |
| intentData   | bytes[]    | インテント規格によって定義されたデータ、実行のために複数のセグメントに分割されています。 |
| signature    | bytes      | 検証ステップ中に nonce と一緒にウォレットに渡されるデータ。     |

この表は、ユーザーがウォレットに対して特定のインテントを指定するための情報を示しており、それぞれのフィールドがインテントの詳細や実行に関連する情報を提供しています。

`intentData`パラメータは、インテント規格によって定義される任意のバイトの配列で、この配列内の各アイテムは「**インテントセグメント**」と呼ばれます。
ユーザーは、**UserIntent**オブジェクトを、使用されているインテント規格に最適なメンプール戦略に送信します。
MEVサーチャーという専門的なクラスは、これらのインテントを見つけ、それらが他のインテント（自身を含む）とどのように組み合わせられるかを探し、それらを組み合わせてABIエンコードされた構造体である**IntentSolution**を生成します。

:::message
ユーザーはインテントデータを含む**UserIntent**オブジェクトを特定のプロトコルに送り、MEVサーチャーはそれらのインテントを見つけて組み合わせ、最終的に**IntentSolution**としてエンコードしたものを生成します。
これにより、スマートコントラクトやプロトコル間での対話がスムーズに行われ、異なるインテントが結合されて実行される仕組みが実現されます。
:::

| フィールド      | タイプ         | 説明                                      |
|--------------|---------------|-------------------------------------------|
| timestamp    | uint256       | インテントの評価が行われる予定の時間。        |
| intents      | UserIntent[]  | 実行するインテントのリスト。                 |
| order        | uint256[]     | 含まれるインテントの実行順序。               |

その後、ソルバーは**IntentSolution**オブジェクトを含む解決トランザクションを生成し、それを一つの**handleIntents**呼び出しにまとめて、事前に公開されたグローバルエントリーポイントコントラクトに送信します。

:::message
**Solver**
ソルバー（Solver）は、特定のタスクを解決するためのアルゴリズムやプログラムを指す用語です。
一般的に、ソルバーは問題を解析し、最適な解決策を見つけることを目的として設計されます。
ソルバーはさまざまな分野で使用されており、特に数学、コンピュータサイエンス、工学、人工知能、オペレーションズリサーチなどの領域で活用されています。

ソルバーの具体的な用途は多岐にわたります。
たとえば、以下のような例があります。

- 最適化問題の解決
    - ソルバーは、リソースの最適な配置やコストの最小化など、最適化問題の解を見つけるのに使用されます。
- パズルの解決
    - ソルバーは、数独、クロスワード、ナップサック問題などの論理パズルや問題を解くのに役立ちます。
- ゲームプレイ
    - ソルバーは、チェスや囲碁などのボードゲームや、ビデオゲームにおけるAIの戦術決定に使用されます。
- 金融モデリング
    - ソルバーは、リスク分析、ポートフォリオ最適化、価格設定モデルなどの金融分野で利用されます。
- シミュレーション
    - ソルバーは、物理シミュレーション、交通流モデル、気象予測など、シミュレーションベースの研究や予測に応用されます。

文脈によっては、特定のプログラムやアルゴリズムを指す際に「**ソルバー**」という用語が使用されます。
ソルバーは、複雑な問題を効率的に解決し、最適な結果を提供するための重要なツールの一つとして広く利用されています。
:::

グローバルエントリーポイントコントラクトの主要なインターフェースは次のようになります。

```javascript
function handleIntents
    (IntentSolution calldata solution)
    external;

function simulateHandleIntents
    (IntentSolution calldata solution, address target, bytes calldata targetCallData)
    external;

function simulateValidation
    (UserIntent calldata intent)
    external;

function registerIntentStandard
    (IIntentStandard intentStandard)
    external returns (bytes32);

function verifyExecutingIntentForStandard
    (IIntentStandard intentStandard)
    external returns (bool);

error ValidationResult
    (bool sigFailed, uint48 validAfter, uint48 validUntil);

error ExecutionResult
    (bool success, bool targetSuccess, bytes targetResult);
```

インテントの規格が持つべきコアとなるインターフェースは以下の通りです。

```javascript
function validateUserIntent
    (UserIntent calldata intent)
    external;

function executeUserIntent
    (IntentSolution calldata solution, uint256 executionIndex, uint256 segmentIndex, bytes memory context)
    external returns (bytes memory);

function isIntentStandardForEntryPoint
    (IEntryPoint entryPoint)
    external returns (bool);
```

ウォレットに必要なコア・インターフェースは以下の通りです。

```javascript
function validateUserIntent
    (UserIntent calldata intent, bytes32 intentHash)
    external returns (uint256);

function generalizedIntentDelegateCall
    (bytes memory data)
    external returns (bool);
```

### エントリーポイントコントラクトの必要な機能

エントリーポイントの`handleIntents`関数は、2つのループ、検証ループと実行ループを実行する必要があります。

**検証ループ**では、`handleIntents`呼び出しは各**UserIntent**に対して以下のステップを実行する必要があります。

1. **IntentSolution**の`timestamp`値の検証。
    - `block.timestamp`またはそれより前の時間の許容範囲内であることを確認します。
2. ハッシュされたインテントのハッシュを含む**UserIntent**と一緒に、ウォレット上で`validateUserIntent`を呼び出します。
    - ウォレットはインテントの署名を検証する必要があります。
    - `validateUserIntent`呼び出しが失敗した場合、`handleIntents`は少なくともそのインテントの実行をスキップし、完全に`revert`することもあります。
3. **UserIntent**で指定されたインテント規格に`validateUserIntent`を呼び出します。
    - **UserIntent**を渡し、`intentData`パラメータがその規格が期待する形式で正常に解析できることを確認する必要があります。
    - `validateUserIntent`呼び出しが失敗した場合、`handleIntents`は少なくともそのインテントの実行をスキップし、完全に`revert`することもあります。

**実行ループ**では、`handleIntents`呼び出しは各**UserIntent**の`intentData`バイト配列パラメータ内のすべてのセグメントに対して以下のステップを実行する必要があります。

1. **UserIntent**で指定されたインテント規格に`executeUserIntent`を呼び出します。
    - この呼び出しには**IntentSolution**全体と、現在の実行インデックス（この関数が既にこの前にどの規格またはインテントのために呼び出された回数）、セグメントインデックス（実行するための`intentData`配列内のインデックス）、およびコンテキストデータが含まれます。
    - `executeUserIntent`関数は、インテントごとに覚えておく必要がある任意のバイトを返します。
    - 次の`executeUserIntent`呼び出しに同じインテントのために渡す必要があります。
2. **intent**規格は、`intentData`セグメントバイトをどのように解析し、インテント実行中に持続するコンテキストデータをどのように利用するかを選択します。

`intentData`配列パラメータ内の**UserIntent**セグメントの実行順序は、常に`intentData`パラメータで定義された同じ順序に従います。
ただし、**UserIntent**オブジェクト間のセグメントの実行順序は、`IntentSolution`オブジェクトの`order`パラメータで指定できます。
たとえば、`order`配列が`[1,1,0,1]`の場合、2番目のインテントが2回実行されます（インテント2のセグメント1および2）、次に最初のインテントが実行されます（インテント1のセグメント1）、その後に2番目のインテントが3回目に実行されます（インテント2のセグメント3）。ソリューションに順序が指定されていないか、`order`配列を終了した後もすべてのインテントのすべてのセグメントが処理されていない場合、デフォルトの順序が使用されます。
このデフォルトの順序は、最初のインテントから最後のインテントまで

必要な回数だけループし、すべてのインテントのすべてのセグメントが実行されるまで続きます。
順序がインテントのすべてのセグメントの実行後にインテントの実行を指示する場合、`executeUserIntent`呼び出しは単にスキップされ、すべてのインテントで実行が続行されます。

ソルバーは**UserIntent**を受け入れる前に、エントリーポイントの`simulateValidation`関数をローカルに呼び出すためにRPCメソッドを使用する必要があります。
これは、署名とデータのフォーマットが正しいことを検証するものです。

#### 新しいエントリーポイントインテント規格の登録

エントリーポイントの`registerIntentStandard`関数は、新しいインテント規格コントラクトを登録するためのプロセスを提供します。
このプロセスでは、許可なしに新しいインテント規格コントラクトを登録できます。登録プロセスでは、エントリーポイントコントラクトが、登録されるインテント規格コントラクトが適切であることを確認します。
これを確認するために、エントリーポイントコントラクトは、インテント規格コントラクトの`isIntentStandardForEntryPoint`関数を呼び出します。
この関数には、エントリーポイントコントラクトのアドレスが渡され、インテント規格コントラクトはこのアドレスを検証し、`true`または`false`を返すことができます。
インテント規格コントラクトが`true`を返した場合、エントリーポイントコントラクトはそのインテント規格コントラクトを登録し、一意の標準IDを付与します。
この標準IDは、インテント規格コントラクト、エントリーポイントコントラクト、およびチェーンIDに固有です。

### 拡張機能: デフォルトなインテント規格

この拡張機能により、エントリーポイントのロジックがデフォルトなインテント規格をサポートし、ソルバーがガス効率的な方法で基本的な操作を実行できるようになります。
デフォルトなインテント規格は、エントリーポイントコントラクトの作成時に独自の標準IDで登録されます。
この規格には、`validateUserIntent`および`executeUserIntent`という関数が含まれており、これらはエントリーポイントコントラクトのコードの一部として提供されます。
これにより、外部呼び出しを減らすことができます。

デフォルトなインテント規格の`intentData`は、インテントの送信元に対して`calldata`として使用されます。
これにより、ソルバーは自分のウォレットから基本的な操作のリストをよりガス効率的な方法で実行できるようになります。
ソルバーは、このデフォルトなインテント規格を活用して、ウォレット内での操作を最適化し、トランザクションのガスコストを節約できるようになります。

### インテントを実行するインテント標準動作

インテント規格の`executeUserIntent`関数は、非常に柔軟で汎用性があり、将来のさまざまな使用ケースに適用できるように設計されています。
この関数には広範なデータアクセスが提供され、完全な**IntentSolution**にアクセスできるため、将来的に役立つかもしれないあらゆるロジックを実装できます。

各インテント規格コントラクトは、**UserIntent**オブジェクトの`intentData`パラメータを解析し、その規格に関連する制約を検証したり、規格に関連するアクションを実行したりするためにこのデータを利用することが期待されています。
また、`executeUserIntent`関数の最後に返すことができるコンテキストデータを活用することもできます。
このコンテキストデータはエントリーポイントによって保持され、次回のイベントのために`executeUserIntent`関数が呼び出される時にパラメータとして渡されます。
これにより、インテント規格は他のインテントが実行される間に他のインテントにアクセスでき、永続的なデータストアへのアクセスが可能です。

一つの使用例は、インテント規格がインテントの実行中に状態の変更を監視し、トークンを解放し、他のトークンを受け取ることを期待している場合です。

:::message
インテント規格は、多くの異なるインテントの実行に適応できる柔軟性を持ち、その振る舞いをカスタマイズするために多くの手段を提供します。
:::

### インテントを実行するスマート・コントラクト・ウォレットの動作

スマートコントラクトウォレットは、インテントの実行後に、エントリーポイントから何らかの操作を実行することは期待されていません。
ただし、インテント規格がスマートコントラクトウォレットに対して特定のアクションを実行することを要求する場合があります。
この時、スマートコントラクトウォレット内の`generalizedIntentDelegateCall`関数を使用します。
この関数は、指定された`calldata`（関数呼び出しに必要なデータ）をもとに、呼び出し元のインテント規格コントラクトに対してデリゲートコールを実行します。
デリゲートコールは、外部コントラクトのコードを実行する一種の方法で、その外部コントラクトのコンテキスト内で実行されます。

ただし、スマートコントラクトウォレットがデリゲートコールを実行する前に、エントリーポイントコントラクトが信頼できるかどうかを確認する必要があります。
そのために、以下の2つの条件を検証します。

1. `generalizedIntentDelegateCall`関数を呼び出すスマートコントラクトウォレットの`msg.sender`（呼び出し元）が、エントリーポイントが現在`executeUserIntent`を呼び出しているインテント規格コントラクトであること。
2. スマートコントラクトウォレット自体が、エントリーポイントが現在`executeUserIntent`を呼び出している**UserIntent**の送信者であること。

これらの条件を満たす場合、スマートコントラクトウォレットはデリゲートコールを実行し、特定のアクションを実行することができます。
これにより、インテント規格がスマートコントラクトウォレットを介して追加の操作を実行でき、柔軟性が向上します。

### インテントの検証

ユーザーの意図（**UserIntent**）を検証するプロセスは以下のようになります。

1. ソルバーはエントリーポイント上の`simulateValidation(intent)`というビューコールを実行します。
    - このビューコールは、トランザクションを発生させずに、意図をシミュレートして検証するために使用されます。

2. `simulateValidation`関数は、常に成功の結果として`ValidationResult`を返します。
    - ソルバーはこの結果を受け取り、ユーザーの意図が検証に合格したことを確認します。
    - つまり、エントリーポイントは常に検証を成功させます。

3. 同時に、ソルバーは呼び出しの実行トレースを監視します。
    - これは、実際にはトランザクションを送信せずに、関数の実行プロセスを観察することを意味します。
    - ソルバーは、このトレースが禁止されたオペコードを含む命令を実行していないことを確認します。
    - もし禁止されたオペコードが実行された場合、ソルバーはユーザーの意図を拒否します。

このプロセスにより、ユーザーの意図はエントリーポイントを介して確実に検証され、意図の合法性が確保されます。

:::message
エントリーポイントは常に検証を成功させ、ソルバーは安全な実行を確認するためにトレースを行います。
:::

#### 禁止されているオペコード

特定のオペコードは、深度（コントラクトの実行の深さ）が`2`を超える場合に禁止されます。
具体的には、ウォレット、インテント規格、またはそれらによって呼び出される他のコントラクトが実行される場合に制限がかかります。
これらの禁止されるオペコードは以下です。

- `GASPRICE`
- `GASLIMIT`
- `DIFFICULTY`
- `TIMESTAMP`
- `BASEFEE`
- `BLOCKHASH`
- `NUMBER`
- `SELFBALANCE`
- `BALANCE`
- `ORIGIN`
- `GAS`


ただし、GASオペコードは、`CALL`、`DELEGATECALL`、`CALLCODE`、`STATICCALL`に直接続く場合を除いて禁止されます。
これらのオペコードは、検証（シミュレーション）の時にのみ禁止され、実際の実行中には制限されません。
この制約の理由は、これらのオペコードの出力がシミュレーションと実際の実行とで異なる可能性があるためです。
そのため、これらのオペコードを使用して呼び出しをシミュレートしても、後でこれらの呼び出しが実際にチェーン上で行われた場合の正確な動作を予測することができないため、禁止されています。

:::message
深度が`2`を超える場合、特定のオペコードは検証（シミュレーション）中にのみ禁止され、実際の実行中には制限されません。
これは、シミュレーションと実行の結果が異なる可能性があるためです。
例外的に、GASオペコードは、それに続く直接的な`CALL`、`DELEGATECALL`、`CALLCODE`、`STATICCALL`の場合に限り許可されています。
:::

### シミュレーション

`IntentSolution`の実行をシミュレーションするプロセスは以下のステップに従います。

1. ソルバーはエントリーポイント上の`simulateHandleIntents(solution)`というビューコールを行います。
    - この関数はトランザクションを実行せずに呼び出されるため、実際のブロックチェーン上での操作を模倣します。

2. `simulateHandleIntents`関数は、常に成功の結果として`ExecutionResult`を返します。
    - ソルバーはこの結果を受け取り、`IntentSolution`が有効であることを確認します。
    - 有効でない場合、エラーが返され、ソルバーはそれを検知します。

3. ソルバーはオプションで`targetCallData`を提供することができます。
    - シミュレーションの最後に、エントリーポイントはこの`targetCallData`を使用して指定されたターゲットコントラクトを呼び出します。
    - この呼び出しは最終的な分析のために行われ、その結果は`ExecutionResult`エラーを介して返されます。
    - これにより、`IntentSolution`が実際にチェーン上で実行された場合の動作を模倣し、最終的な結果を返します。

このプロセスにより、`IntentSolution`の実行をブロックチェーン上で実行する前に、事前にシミュレートし、検証できるため、安全性が向上します。
また、エラーや問題がある場合、実際のトランザクションを発生させる前にそれを検知することができます。

## 補足

一般化されたインテント規格の主要な課題は、インテントの進化に適応することです。
ユーザーは、スマートコントラクトウォレットを継続的に更新せずに、シームレスに自分の意図を表現できる方法が必要です。

この提案では、ウォレットが`validateUserIntent`関数を持つことが期待されています。
この関数は**UserOperation**を入力として受け取り、その操作の署名を検証します。
信頼性のあるエントリーポイントコントラクトは、この関数を使用して署名を検証し、**UserOperation**に指定されたインテント処理のロジックを実行するためのインテント規格コントラクトに転送します。
その後、ウォレットは`generalizedIntentDelegateCall`関数を持つことが期待されます。
この関数を使用することで、ウォレットはセキュリティの確保のためにエントリーポイント上で`verifyExecutingIntentForStandard`関数を呼び出し、インテント規格コントラクトからのインテントに関連するアクションを実行できます。

このエントリーポイントベースのアプローチにより、検証とインテントの実行が清潔に分離され、ユーザーが最新のインテント構成を使用したい場合でも、ウォレットを継続的に更新する必要がなくなります。
代替案では、新しいインテント規格の開発者がウォレットソフトウェアの開発者に新しい規格をサポートするよう説得する必要があります。
この提案により、インテントの中核的な定義がユーザーによって署名時に制御され、柔軟性が向上します。

### ソルバー

ソルバー（Solvers）は、ユーザーの意図を実現し、同時に自身のMEV（最大効用値）を追求する役割を果たします。
具体的には、ユーザーが実行したい操作やトランザクションを助け、そのために必要なオンチェーンの処理を行います。
これには、トランザクションの発送やガス手数料の負担などが含まれます。

ソルバーは、ユーザーが提供した意図（インテント）に従って、最適な方法で処理を実行し、その結果MEVを得ることを目指します。
また、ソルバーはオンチェーンでのトランザクションの発起者として機能し、通常のユーザーに代わってトランザクションを送信し、それに関連するガス手数料を支払います。

ソルバーは、ゴシップネットワークやソリューションアルゴリズムを利用して、意図（インテント）の処理方法を決定します。
各インテント規格には、その実装に関連する特定のゴシップネットワークやアルゴリズムが定義されており、ソルバーはこれらを活用して最適な解決策を見つけ出します。

:::message
ソルバーはユーザーの意図を実現し、同時に自身のMEVを獲得するための役割を果たします。
彼らはオンチェーンの処理を担当し、ユーザーが意図した操作を円滑に実行するのに役立ちます。
:::

### エントリーポイントのアップグレード

ウォレットは、`DELEGATECALL`フォワーディングコントラクトとして機能することが推奨されています。
これは、ウォレットのガス効率を向上させ、ウォレットのアップグレードを可能にするための方法です。
ウォレットのコード内でエントリーポイントをハードコードすることが期待されています。
これにより、ガスの効率的な使用が可能になります。
新しいエントリーポイントが導入される場合（新しい機能の追加、ガスの効率向上、重要なセキュリティのバグ修正など）、ユーザーは自分のウォレットのコードアドレスを、新しいエントリーポイントを指すコードが含まれた新しいコードアドレスに置き換えることができます。
これはセルフコールとして知られ、ユーザー自身がウォレットのアップグレードを行うプロセスです。

ウォレットのアップグレードプロセス中には、インテント規格コントラクトも新しいエントリーポイントに再デプロイし、新しいエントリーポイントに登録する必要があると考えられています。
これにより、ウォレットと関連するインテント規格が同じアップグレードプロセスに従い、シームレスな動作が確保されます。

:::message
ウォレットのエントリーポイントのアップグレードは、ガス効率を向上させ、ウォレットの柔軟性を高めるための重要な手段です。
新しいエントリーポイントが必要な場合、ユーザーは自身のウォレットを新しいコードアドレスにアップグレードし、関連するインテント規格も更新することが期待されています。
:::

#### インテント規格のアップグレード

インテント規格はウォレットに固定的に組み込まれていないため、ユーザーは新たに登録されたインテント規格を使用するために、特別な操作を実行する必要はありません。
ユーザーは、新しいインテント規格でインテントを署名するだけで済みます。

:::message
インテント規格はウォレットのコードに硬直的に組み込まれていないため、ユーザーは新しいインテント規格を利用するために追加の手続きを行う必要がありません。
ユーザーは新しいインテント規格でインテントを署名するだけで、新しい規格を簡単に利用できます。
:::

## 後方互換性

このERCはEthereumのコンセンサス層を変更しないため、Ethereum全体で後方互換性の問題は発生しません。
ただし、既存のスマートコントラクトウォレットとの統合に関してはいくつかの課題が存在します。
既存のウォレットがすでに**ERC4337**をサポートしている場合、新しい`validateUserIntent`関数を実装することは、`validateUserOp`関数と非常に似ていますが、ユーザーがウォレットのアップグレードを行う必要があります。

:::message
このERCはEthereum全体の逆互換性には影響を与えないため、Ethereumの基本的な動作に変更を加えません。
ただし、既存のスマートコントラクトウォレットと統合する場合、ウォレットがすでに**ERC4337**をサポートしている場合、新しい`validateUserIntent`関数を実装するためにユーザーがアップグレードを行う必要があります。
これは、新しい機能やセキュリティの改善を活用するためのステップです。
:::

## 参考実装

以下のGithubに格納されています。

https://github.com/essential-contributions/ERC-7521

## セキュリティ考慮事項

エントリーポイントコントラクトは、**ERC7521**対応のすべてのウォレットにとって中央の信頼ポイントとして機能するため、非常に厳格な監査と形式的な検証が必要です。
このアーキテクチャを通じて、個々のウォレットが実行する必要のある作業が大幅に削減されるため、エコシステム全体での監査および形式的な検証の負担が軽減されます。
ウォレットは単に`validateUserIntent`関数とその「**署名の確認、nonceの増加**」ロジックを確認し、`generalizedIntentDelegateCall`に対する呼び出しを`verifyExecutingIntentForStandard`関数を使用してエントリーポイントで確認するだけで済みます。

ただし、エントリーポイントコントラクトにはセキュリティリスクが集中しているため、非常に堅牢であることを検証する必要があります。
検証には主に以下の主要な要件が含まれます（ソルバーを保護し、インテント規格関連のインフラストラクチャを保護するための要件は含まれていません）。

1. 任意のハイジャックに対するセキュリティ
    - エントリーポイントは、**UserIntent**の署名を正常に検証し、`msg.sender`と同じ送信者を持つ**UserIntent**で指定された標準で`executeUserIntent`を呼び出している場合にのみ、`verifyExecutingIntentForStandard`関数に対して`true`を返すことができます。

また、ユーザーが対話するインテント規格コントラクトに対しても、追加の厳格な監査と形式的な検証が必要です。

## 引用

Stephen Monn (@pixelcircuits), Bikem Bengisu (@supiket), "ERC-7521: General Intents for Smart Contract Wallets [DRAFT]," Ethereum Improvement Proposals, no. 7521, September 2023. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7521.


## 最後に

今回は「コントラクトウォレット用の標準化されたインテント仕様を提案し、署名時に現在・将来のインテント構造を承認する仕組みを提案している規格である**ERC7521**」についてまとめてきました！
いかがだったでしょうか？

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

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

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

https://chaldene.net/

https://zenn.dev/heku

https://mirror.xyz/0xcE77b9fCd390847627c84359fC1Bc02fC78f0e58
