[ERC7683] クロスチェーンインテントのインターフェースを理解しよう！

# はじめに

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

https://cryptogames.co.jp/

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

https://cryptospells.jp/

今回は、クロスチェーン取引実行システムのためのインターフェースを提案している**ERC7683**についてまとめていきます！

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

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

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

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

# 概要

この規格では、クロスチェーン取引実行のための標準APIの実装を提案しています。
この標準は、汎用的な`CrossChainOrder`構造体と`ISettlementContract`インターフェイスが提案されています。

:::note info
インテントとは、「**ユーザーが実現したい具体的な処理を自動で行い実行する**」というざっくりな理解をしています。
例えば、「**トークンをいくらで売りたい**」や「**トークンA→トークンB→トークンCに変換したい**」時に、その命令を手動で実行せずにボタンをクリックするだけで実行してくれるようなイメージです。
これにより、複雑な処理でもユーザーが簡単に実行できるようになります。
正直、現状仮想通貨をあれやこれやするのは慣れていないユーザー（Web2ユーザーなど）にとっては難しすぎます。
インテントはこの課題を解決してくれます。
「**インテント**」は「**意図**」という意味である、その名の通り「**ユーザーの意図を実現**」してくれます。

より詳しくは以下の記事などを参考にしてください。
:::

https://diveintocrypto.xyz/p/web3-intent-based-architecture

https://www.coindeskjapan.com/208693/


# 動機

インテントベースのシステムは、トークンやNFTなどのブリッジの複雑さや時間的制約（トランザクション実行時間や複数のステップを踏む必要があるなど）を取り除き、エンドユーザーが複数のブロックチェーン間でやり取りする最良の手段となっています。
しかし、クロスチェーンのインテントシステムにおいては、十分な流動性を確保し、複数のチェーンにわたるアクティブなフィラー（注文を実行してくれるユーザーやシステム）のネットワークを維持することが大きな課題となります。
この問題は、対応チェーンの数が増えるにつれて悪化する可能性があります。

結果として、ユーザーは高いコストや長い待ち時間、高い失敗率などから体験が悪くなります。

この問題を解決するために、標準化を実装することで、クロスチェーンのインテントシステムが互いに連携し、注文の送信システム（ユーザーが発行したトランザクションやインテントを適切なフィラーに送るシステム）やフィラー（ユーザーからの注文を実査に処理するシスタムや個人）ネットワークなどのインフラを共有できるようになります。
これにより、ユーザーのインテントを実現するための競争が増加してユーザー体験が向上します。

:::note info
注文を出すユーザーからすると、安く・速く・しっかり注文をこなしてくれることが嬉しいです。
そのため、注文を実行するフィラー間で「**迅速な処理**」、「**コストの削減**」、「**処理をちゃんと実行**」という競争が生まれます。
ユーザーはその中で常に一番良いと思うフィラーを選択すればよくなり、ユーザー体験が向上します。
:::

# 仕様

## ResolvedCrossChainOrder

この規格に準拠したクロスチェーンの注文タイプは、以下の`CrossChainOrder`構造体を実装する必要があります。

```js
/// @title CrossChainOrder type
/// @notice Standard order struct to be signed by swappers, disseminated to fillers, and submitted to settlement contracts
struct CrossChainOrder {
	/// @dev The contract address that the order is meant to be settled by.
	/// Fillers send this order to this contract address on the origin chain
	address settlementContract;
	/// @dev The address of the user who is initiating the swap,
	/// whose input tokens will be taken and escrowed
	address swapper;
	/// @dev Nonce to be used as replay protection for the order
	uint256 nonce;
	/// @dev The chainId of the origin chain
	uint32 originChainId;
	/// @dev The timestamp by which the order must be initiated
	uint32 initiateDeadline;
	/// @dev The timestamp by which the order must be filled on the destination chain
	uint32 fillDeadline;
	/// @dev Arbitrary implementation-specific data
	/// Can be used to define tokens, amounts, destination chains, fees, settlement parameters,
	/// or any other order-type specific information
	bytes orderData;
}
```

- `settlementContract`
    - この注文を決済するためのコントラクトアドレス。
    - フィラーはこのコントラクトアドレスに注文を送信します。
    - これは実行元のチェーン上に存在します。
- `swapper`
    - スワップを開始するユーザーのアドレス。
    - ユーザーのトークンが取り出され、エスクローされます。
- `nonce`
    - リプレイ攻撃を防止するための一意の番号。
    - 各注文が一意であることを保証します。
- `originChainId`
    - 実行元のチェーンのchainId。
    - 注文がどのチェーンから開始されたかを示します。
- `initiateDeadline`
    - 注文が開始されるべき最終期限のタイムスタンプ。
    - この期限までに注文が開始されなければなりません。
- `fillDeadline`
    - 注文が目的のチェーンで満たされるべき最終期限のタイムスタンプ。
    - この期限までに注文が満たされなければなりません。
- `orderData`
    - 実装固有のデータを含む任意のバイトデータ。
    - トークン、金額、目的のチェーン、手数料、決済パラメータなど、注文タイプ固有の情報を定義するために使用されます。

クロスチェーン実行システムは、`orderData`フィールドから解析可能なカスタムサブタイプに変換する必要があります。
このサブタイプには以下の含まれます。

- **スワップでやり取りするトークン情報**
    - トークンのアドレスや数量。
- **目的のチェーンID**
    - 注文が履行されるチェーンのID。
- **履行の制約**
    - 注文が履行されるための条件や制約。
- **決済オラクル**
    - 注文に関する情報を提供するオラクルのアドレス。
    - 注文が正しく履行されたかを検証する。

## ResolvedCrossChainOrder

この規格に準拠したクロスチェーンの注文タイプは、以下の`ResolvedCrossChainOrder`構造体に変換可能である必要があります。

```js
/// @title ResolvedCrossChainOrder type
/// @notice An implementation-generic representation of an order
/// @dev Defines all requirements for filling an order by unbundling the implementation-specific orderData.
/// @dev Intended to improve integration generalization by allowing fillers to compute the exact input and output information of any order
struct ResolvedCrossChainOrder {
	/// @dev The contract address that the order is meant to be settled by.
	address settlementContract;
	/// @dev The address of the user who is initiating the swap
	address swapper;
	/// @dev Nonce to be used as replay protection for the order
	uint256 nonce;
	/// @dev The chainId of the origin chain
	uint32 originChainId;
	/// @dev The timestamp by which the order must be initiated
	uint32 initiateDeadline;
	/// @dev The timestamp by which the order must be filled on the destination chain(s)
	uint32 fillDeadline;

	/// @dev The inputs to be taken from the swapper as part of order initiation
	Input[] swapperInputs;
	/// @dev The outputs to be given to the swapper as part of order fulfillment
	Output[] swapperOutputs;
	/// @dev The outputs to be given to the filler as part of order settlement
	Output[] fillerOutputs;
}

/// @notice Tokens sent by the swapper as inputs to the order
struct Input {
	/// @dev The address of the ERC20 token on the origin chain
	address token;
	/// @dev The amount of the token to be sent
	uint256 amount;
}

/// @notice Tokens that must be receive for a valid order fulfillment
struct Output {
	/// @dev The address of the ERC20 token on the destination chain
	/// @dev address(0) used as a sentinel for the native token
	address token;
	/// @dev The amount of the token to be sent
	uint256 amount;
	/// @dev The address to receive the output tokens
	address recipient;
	/// @dev The destination chain for this output
	uint32 chainId;
}
```

特定のクロスチェーン注文を処理するために必要な全ての情報を持っています。
これにより、フィラーは任意の注文の入力と出力を正確に計算し、注文を適切に処理できるようになります。
`CrossChainOrder`構造体のデータを解析し、この形式（`ResolvedCrossChainOrder`）に変換することで、異なるシステム間での統合が容易になります

### `ResolvedCrossChainOrder`

- `settlementContract`
    - この注文を決済するためのコントラクトアドレス。
- `swapper`
    - スワップを開始するユーザーのアドレス。このユーザーのトークンが取り出され、エスクローされる。
- `nonce`
    - リプレイ攻撃を防止するための一意の番号。
    - 各注文が一意であることを保証します。
- `originChainId`
    - 元のチェーンの`chainId`。
    - 注文がどのチェーンから開始されたかを示します。
- `initiateDeadline`
    - 注文が開始されるべき最終期限のタイムスタンプ。
    - この期限までに注文が開始されなければなりません。
- `fillDeadline`
    - 注文が目的のチェーンで満たされるべき最終期限のタイムスタンプ。
    - この期限までに注文が満たされなければなりません。
- `swapperInputs`
    - 注文の開始時にスワッパーから取り出されるトークンの入力情報を示します。
- `swapperOutputs`
    - 注文が満たされる際にスワッパーに与えられるトークンの出力情報を示します。
- `fillerOutputs`
    - 注文の決済時にフィラーに与えられるトークンの出力情報を示します。

### Input

- `token`
    - 元のチェーンにある**ERC20**トークンのアドレス。
    - スワッパーが提供するトークンのアドレスを示します。
- `amount`
    - 送信されるトークンの金額。
    - スワッパーが提供するトークンの数量を示します。

### Output

- `token`
    - 目的のチェーンにある**ERC20**トークンのアドレス。
    - 注文が満たされる際に受け取るトークンのアドレスを示します。
    - `address(0)` はネイティブトークンを示すための特殊な値です。
- `amount`
    - 送信されるトークンの金額。
    - 受け取るトークンの数量を示します。
- `recipient`
    - 出力トークンを受け取るアドレス。
    - トークンを受け取る対象を示します。
- `chainId`
    - この出力のための目的チェーン。
    - トークンが送信されるチェーンを示します。

## ISettlementContract

```js
/// @title ISettlementContract
/// @notice Standard interface for settlement contracts
interface ISettlementContract {
	/// @notice Initiates the settlement of a cross-chain order
	/// @dev To be called by the filler
	/// @param order The CrossChainOrder definition
	/// @param signature The swapper's signature over the order
	/// @param fillerData Any filler-defined data required by the settler
	function initiate(CrossChainOrder order, bytes signature, bytes fillerData) external;

	/// @notice Resolves a specific CrossChainOrder into a generic ResolvedCrossChainOrder
	/// @dev Intended to improve standardized integration of various order types and settlement contracts
	/// @param order The CrossChainOrder definition
	/// @param fillerData Any filler-defined data required by the settler
	/// @returns ResolvedCrossChainOrder hydrated order data including the inputs and outputs of the order
	function resolve(CrossChainOrder order, bytes fillerData) external view returns (ResolvedCrossChainOrder);
}
```

クロスチェーン注文を処理するための標準インターフェースです。


#### `initiate`

クロスチェーン注文の決済を開始するための関数。
フィラーによって呼び出されて以下の引数を持ちます。
- `order`
    - `CrossChainOrder` 型の注文定義。
    - この注文が決済されます。
- `signature`
    - スワッパー（注文を発行したユーザー）の署名。
    - この署名により、注文が正当であることが確認されます。
- `fillerData`
    - フィラーが定義する必要なデータ。
    - 注文の決済に必要な追加情報を含みます。

#### `resolve`

特定の `CrossChainOrder` を汎用的な `ResolvedCrossChainOrder` に変換する関数。
フィラーや他のコントラクトによって呼び出されて以下の引数を持ちます。
- `order`
    - `CrossChainOrder` 型の注文定義。
    - この注文が解析されます。
- `fillerData`
    - フィラーが定義する必要なデータ。
    - 注文の解析に必要な追加情報を含みます。

`ResolvedCrossChainOrder`型のデータが戻り値として返ってきます。

# 補足

## 注文データ

### 標準クロスチェーンインテントのフロー

1. **スワッパーがオフチェーンメッセージに署名**
    - スワッパー（取引を行うユーザー）は、注文のパラメータを定義したメッセージに署名。
    - この署名により、注文が正当であることを証明。
2. **注文がフィラーに送信**
    - スワッパーの署名した注文が、フィラー（注文を実行する人やシステム）に送信。
3. **フィラーが指定されたチェーンで取引を開始する**
    - フィラーは、指定されたチェーン上で取引を開始。
4. **フィラーが指定されたチェーンで注文を実行**
    - フィラーは、指定されたチェーン上で注文を実行。
5. **クロスチェーン決済プロセスの実行**:
   - 注文が実行されると、クロスチェーン決済プロセスが実行されて取引が完了。

### カスタマイズ可能な動作

このフロー内で、開発者は以下のようにカスタマイズできます。

- **価格決定**
    - 例: ダッチオークション（価格が徐々に下がるオークション）やオラクルに基づく価格設定。
- **履行の制約**
    - 例: 特定の条件が満たされる必要がある注文の制約。
- **決済手続き**
    - 例: 注文の決済方法。

### `orderData`フィールド

`orderData`フィールドは、注文の詳細を設定することができます。

### `resolve`関数と`ResolvedCrossChainOrder`タイプ

- **`resolve`関数**
    - 特定の `CrossChainOrder` を `ResolvedCrossChainOrder` に変換します。
    - この関数により、フィラーは `orderData` による詳細な情報がなくても注文を評価できます。

- **`ResolvedCrossChainOrder` タイプ**
    - 解析された注文データを格納し、注文の入力と出力情報を提供します。

## Permit2の使用

Permit2は、単一の署名でトークン転送と注文の承認を行うための仕組みです。

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

https://zenn.dev/cryptogames/articles/4251878665f6e4
https://chaldene.net/erc20permit

Permit2を使用すること以下のようなメリットがあります。
- 単一の署名でトークン転送と注文の承認を行うことができます。
- トークンの転送と注文の開始を結びつけることで、セキュリティが向上します。

通常の承認モデルでは、トークン承認（**ERC2612**またはオンチェーン）とスワップ条件の承認のために2つの署名が必要です。
トークンの承認がスワップと分離しているため、バグや悪意ある決済コントラクトにより、承認されたトークンがいつでも取り出されてしまうリスクがあります。

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

https://qiita.com/cardene/items/6809173b2ac428b1ccd0

Permit2を使用する場合は以下の点に考慮する必要があります。

- **`nonce`**
    - `nonce` は一意の番号で、再利用を防ぐために使われます。
    - 注文構造体の `nonce` は Permit2 の `nonce` を使用。
    - これにより、Permit2が一意の注文を識別して再利用を防止します。
- **`initiateDeadline`**
    - `initiateDeadline` は、注文が開始されるべき最終期限のタイムスタンプです。
    - 注文構造体の `initiateDeadline` は Permit2 の `deadline` を使用します。
    - これにより、Permit2が注文の有効期限を管理して期限内に処理されることを保証します。
- **完全な注文データ**
    - `orderData` を解析して得られた詳細な注文情報を含む構造体のことです。
    - Permit2 を使用する時、スワッパー（注文を発行するユーザー）が注文許可に署名する必要があります。
    - この時、完全な注文データを署名対称データとして扱うことができます。
    - これにより、スワッパーは署名する時に注文の全容を確認でき、透明性が最大化されます。

# 引用

Mark Toda (@marktoda), Matt Rice (@mrice32), Nick Pai (@nicholaspai), "ERC-7683: Cross Chain Intents [DRAFT]," Ethereum Improvement Proposals, no. 7683, April 2024. [Online serial]. Available: https://eips.ethereum.org/EIPS/eip-7683.

# 最後に

今回は「クロスチェーン取引実行システムのためのインターフェースを提案している**ERC7683**」についてまとめてきました！
いかがだったでしょうか？

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

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

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

https://chaldene.net/

https://zenn.dev/heku

https://cardene.substack.com/

https://mirror.xyz/0xcE77b9fCd390847627c84359fC1Bc02fC78f0e58

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