はじめに
『DApps開発入門』という本や色々記事を書いているかるでねです。
今回は、EIP5792のwallet_sendCallsを拡張し、dAppsがウォレット呼び出しに必要なトークン残高や承認などの前提条件を指定できるようにする仕組みを提案しているERC7795についてまとめていきます!
以下にまとめられているものを翻訳・要約・補足しながらまとめていきます。
他にも様々なEIP・BIP・SLIP・CAIP・ENSIP・RFC・ACPについてまとめています。
概要
ERC7795とは、EIP5792のwallet_sendCallsメソッドを拡張し、dAppsがウォレットに対してトークンに関する前提条件を指定できるようにする仕組みのことです。
EIP5792は、dAppsがウォレットに対して複数の呼び出しをバッチで送信できるようにするwallet_sendCallsメソッドを定義した規格です。
ERC7795では、ERC20トークンの残高・承認要件を指定できます。
ERC20については以下の記事を参考にしてください。
また、ERC721(NFT)の所有権・承認要件も指定できます。
ERC721については以下の記事を参考にしてください。
さらに、ERC1155トークンの残高・承認要件も指定可能です。
ERC1155については以下の記事を参考にしてください。
これらの機能はwallet_sendCallsとwallet_getCapabilitiesRPCメソッドを通じて実装されます。
この規格の特徴は、ウォレットが前提条件を自動的に処理できる点にあります。
dAppsがトークン要件を指定すると、ウォレットはその要件を満たすために必要なトランザクション(承認やスワップなど)を自動的に先頭に追加します。
ERC7795では、ERC20の残高・承認、ERC721の所有権・承認、ERC1155の残高・承認に対応する6種類のケーパビリティを定義しています。
これらはEIP5792の既存のケーパビリティ発見メカニズム(wallet_getCapabilities)を活用するため、ウォレットは対応可能な要件のみを選択的に実装できます。
また、複数のケーパビリティを組み合わせて使用することも可能で、将来的に新しい要件タイプを段階的に追加できる拡張性も備えています。
動機
この提案が生まれた背景には以下のような課題がありました。
単一ネットワーク依存による流動性の縮小
dAppsが1つのネットワーク上にのみ存在することはよくありますが、これによりdAppsがアクセスできる直接的な流動性が縮小します。
ほとんどのユーザーは限られた数のネットワークにのみ資金を持っており、ネットワーク数が増えるほど、dAppsが選択したネットワークとユーザーの資金があるネットワークが一致する可能性は低くなります。
「最終意図」を伝える手段の欠如
dAppsにはウォレットに対して「最終意図(final intent)」を伝える方法がないため、ユーザーに実行してほしい最後のアクション(トランザクションリクエスト)しか伝えることができません。
そのため、最終アクションの前提条件を満たすために必要な事前アクション(資金の統合やアセットの交換など)をユーザー自身が推測しなければなりません。
この推測プロセスはユーザーにとって煩雑で、UXの大幅な低下につながっています。
この提案による解決策
ERC7795は、dAppsがwallet_sendCallsのケーパビリティとしてトークン前提条件を指定できるようにします。
ウォレットはこれらの前提条件を解釈し、必要に応じてトランザクション(ブリッジ、スワップ、承認など)を自動的に先頭に追加することで、シームレスなユーザー体験を提供できます。
仕様
ケーパビリティ一覧
ERC7795では、以下の6つのケーパビリティを定義しています。
| ケーパビリティ | 対象トークン | 説明 |
|---|---|---|
erc20MinBalance |
ERC20 | 最小残高要件 |
erc20MinAllowance |
ERC20 | 最小承認額要件 |
erc721Ownership |
ERC721 | NFT所有権要件 |
erc721Approval |
ERC721 | NFT承認要件 |
erc1155MinBalance |
ERC1155 | 最小残高要件 |
erc1155MinAllowance |
ERC1155 | 最小承認要件 |
ERC20
ERC20トークンに関するケーパビリティとして、最小残高要件と最小承認額要件の2つが定義されています。
erc20MinBalance
ERC20トークンの最小残高要件を指定するケーパビリティです。
dAppsはこのケーパビリティを使用して、呼び出しを実行する前にアカウントが特定のERC20トークンの最小残高を持っている必要があることをウォレットに通知します。
ウォレットはこの要件を満たすために、ブリッジやスワップなどのトランザクションを先頭に追加する場合があります。
パラメータ
| フィールド | 型 | 説明 |
|---|---|---|
version |
string |
ケーパビリティのバージョン |
chainId |
0x${string} |
チェーンID(16進数) |
owner |
0x${string} |
残高を確認するアドレス |
token |
0x${string} |
ERC20トークンのコントラクトアドレス |
minAmount |
0x${string} |
必要な最小残高(16進数) |
使用例
{
"capabilities": {
"erc20MinBalance": {
"version": "1.0",
"chainId": "0x01",
"owner": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
"token": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"minAmount": "0x0f4240" // 1,000,000 = 1 USDC (6 decimals)
}
}
}
erc20MinAllowance
ERC20トークンの最小承認額要件を指定するケーパビリティです。
dAppsはこのケーパビリティを使用して、呼び出しを実行する前に特定のアドレスに対するERC20トークンの最小承認額が必要であることをウォレットに通知します。
ウォレットはこの要件を満たすために、approveトランザクションを先頭に追加する場合があります。
パラメータ
| フィールド | 型 | 説明 |
|---|---|---|
version |
string |
ケーパビリティのバージョン |
chainId |
0x${string} |
チェーンID(16進数) |
owner |
0x${string} |
承認元のアドレス |
operator |
0x${string} |
承認先のオペレーターアドレス |
token |
0x${string} |
ERC20トークンのコントラクトアドレス |
minAmount |
0x${string} |
必要な最小承認額(16進数) |
このケーパビリティはオーナーがトークンの残高を持っていることを意味しません。承認額が指定した量以上であることのみを要求します。
使用例
{
"capabilities": {
"erc20MinAllowance": {
"version": "1.0",
"chainId": "0x01",
"owner": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
"token": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"operator": "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D",
"minAmount": "0x0f4240" // Uniswap Router に USDC を承認
}
}
}
ERC721
ERC721トークン(NFT)に関するケーパビリティとして、所有権要件と承認要件の2つが定義されています。
erc721Ownership
ERC721トークン(NFT)の所有権要件を指定するケーパビリティです。
dAppsはこのケーパビリティを使用して、呼び出しを実行する前にアカウントが特定のNFTを所有している必要があることをウォレットに通知します。
ウォレットはこの要件を満たすために、NFTの購入などのトランザクションを先頭に追加する場合があります。
パラメータ
| フィールド | 型 | 説明 |
|---|---|---|
version |
string |
ケーパビリティのバージョン |
chainId |
0x${string} |
チェーンID(16進数) |
owner |
0x${string} |
所有者のアドレス |
token |
0x${string} |
ERC721トークンのコントラクトアドレス |
tokenId |
0x${string} |
必要なトークンID(16進数) |
使用例
{
"capabilities": {
"erc721Ownership": {
"version": "1.0",
"chainId": "0x01",
"owner": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
"token": "0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d",
"tokenId": "0x10" // BAYC #16 の所有権が必要
}
}
}
erc721Approval
ERC721トークン(NFT)の承認要件を指定するケーパビリティです。
dAppsはこのケーパビリティを使用して、呼び出しを実行する前に特定のオペレーターに対するNFTの承認が必要であることをウォレットに通知します。
このケーパビリティはオーナーがトークンを所有していることを意味しません。承認が設定されていることのみを要求します。
パラメータ
| フィールド | 型 | 説明 |
|---|---|---|
version |
string |
ケーパビリティのバージョン |
chainId |
0x${string} |
チェーンID(16進数) |
owner |
0x${string} |
承認元のアドレス |
operator |
0x${string} |
承認先のオペレーターアドレス |
token |
0x${string} |
ERC721トークンのコントラクトアドレス |
tokenId |
0x${string} |
承認が必要なトークンID(16進数) |
使用例
{
"capabilities": {
"erc721Approval": {
"version": "1.0",
"chainId": "0x01",
"owner": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
"operator": "0x00000000006c3852cbEf3e08E8dF289169EdE581",
"token": "0xbc4ca0eda7647a8ab7c2061c2e118a18a936f13d",
"tokenId": "0x10" // OpenSea Seaport に BAYC #16 を承認
}
}
}
ERC1155
ERC1155トークンに関するケーパビリティとして、最小残高要件と最小承認要件の2つが定義されています。
erc1155MinBalance
ERC1155トークンの最小残高要件を指定するケーパビリティです。
dAppsはこのケーパビリティを使用して、呼び出しを実行する前にアカウントが特定のERC1155トークンの最小残高を持っている必要があることをウォレットに通知します。
パラメータ
| フィールド | 型 | 説明 |
|---|---|---|
version |
string |
ケーパビリティのバージョン |
chainId |
0x${string} |
チェーンID(16進数) |
owner |
0x${string} |
残高を確認するアドレス |
token |
0x${string} |
ERC1155トークンのコントラクトアドレス |
tokenId |
0x${string} |
トークンID(16進数) |
minAmount |
0x${string} |
必要な最小残高(16進数) |
使用例
{
"capabilities": {
"erc1155MinBalance": {
"version": "1.0",
"chainId": "0x01",
"owner": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
"token": "0x631998e91476da5b870d741192fc5cbc55f5a52e",
"tokenId": "0x10",
"minAmount": "0x0f4240" // Token ID 16 の残高が指定量以上必要
}
}
}
erc1155MinAllowance
ERC1155トークンの最小承認要件を指定するケーパビリティです。
dAppsはこのケーパビリティを使用して、呼び出しを実行する前に特定のアドレスに対するERC1155トークンの承認が必要であることをウォレットに通知します。
このケーパビリティはオーナーがトークンの残高を持っていることを意味しません。承認額が指定した量以上であることのみを要求します。
パラメータ
| フィールド | 型 | 説明 |
|---|---|---|
version |
string |
ケーパビリティのバージョン |
chainId |
0x${string} |
チェーンID(16進数) |
owner |
0x${string} |
承認元のアドレス |
operator |
0x${string} |
承認先のオペレーターアドレス |
token |
0x${string} |
ERC1155トークンのコントラクトアドレス |
tokenId |
0x${string} |
トークンID(16進数) |
minAmount |
0x${string} |
必要な最小承認額(16進数) |
使用例
{
"capabilities": {
"erc1155MinAllowance": {
"version": "1.0",
"chainId": "0x01",
"owner": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
"operator": "0x00000000006c3852cbEf3e08E8dF289169EdE581",
"token": "0x631998e91476da5b870d741192fc5cbc55f5a52e",
"tokenId": "0x10",
"minAmount": "0x0f4240" // OpenSea Seaport に承認
}
}
}
補足
完全な使用例
以下は、複数のケーパビリティを組み合わせたwallet_sendCallsの完全な使用例です。
{
"method": "wallet_sendCalls",
"params": [{
"version": "1.0",
"from": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
"calls": [
{
"to": "0xDeFiProtocol",
"data": "0x...",
"value": "0x0",
"chainId": "0x01"
}
],
"capabilities": {
"erc20MinBalance": {
"version": "1.0",
"chainId": "0x01",
"owner": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
"token": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"minAmount": "0x5F5E100"
},
"erc20MinAllowance": {
"version": "1.0",
"chainId": "0x01",
"owner": "0xd46e8dd67c5d32be8058bb8eb970870f07244567",
"token": "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"operator": "0xDeFiProtocol",
"minAmount": "0x5F5E100"
}
}
}]
}
この例では、以下の前提条件を指定しています。
- USDCの残高が100以上であること
- DeFiプロトコルに対してUSDCの承認が100以上であること
ウォレットの動作
ウォレットは指定されたケーパビリティに基づいて、以下のように動作します。
この図は、dAppsがwallet_sendCallsでケーパビリティを指定した場合のウォレットの処理フローを示しています。
- dAppsがケーパビリティ付きの
wallet_sendCallsをウォレットに送信します。 - ウォレットは指定された前提条件(残高要件、承認要件など)を確認します。
- 前提条件が満たされていない場合、ウォレットは必要なトランザクション(スワップ、ブリッジ、approve呼び出しなど)を自動的に生成します。
- 前提条件を満たすトランザクションを先に実行し、その後に元のcallsを実行します。
- すべてのトランザクションが完了したら、結果をdAppsに返します。
この仕組みにより、dAppsは複雑なトランザクション順序を自分で管理する必要がなくなり、ウォレットが最適な方法で前提条件を処理できます。
ケーパビリティのサポート確認
ウォレットがこれらのケーパビリティをサポートしているかどうかは、wallet_getCapabilitiesメソッドで確認できます。
{
"method": "wallet_getCapabilities",
"params": ["0xUserAddress"]
}
レスポンス例を以下に示します。
{
"0x1": {
"erc20MinBalance": { "supported": true, "versions": ["1.0"] },
"erc20MinAllowance": { "supported": true, "versions": ["1.0"] },
"erc721Ownership": { "supported": true, "versions": ["1.0"] },
"erc721Approval": { "supported": true, "versions": ["1.0"] },
"erc1155MinBalance": { "supported": true, "versions": ["1.0"] },
"erc1155MinAllowance": { "supported": true, "versions": ["1.0"] }
}
}
互換性
EIP5792との関係
ERC7795は以下の規格と関係があります。
| 規格 | 関係性 | 備考 |
|---|---|---|
| EIP5792 | 拡張 |
wallet_sendCallsのケーパビリティとして実装 |
| ERC20 | 対象 | 残高・承認要件を指定可能 |
| ERC721 | 対象 | 所有権・承認要件を指定可能 |
| ERC1155 | 対象 | 残高・承認要件を指定可能 |
ユースケース
以下の2つの具体的なユースケースが紹介されています。
EOAウォレットでのブリッジを使ったマーケットプレイス購入
ユーザーがチェーンA上でERC721トークンを購入したいが、資金はチェーンBにしかない場合を考えます。
dAppsはwallet_sendCallsを使い、マーケットプレイスのトランザクションとともにチェーンA上の資金要件をケーパビリティとして指定します。
EOAウォレットは、前提条件を満たすために必要なトランザクション(ブリッジなど)への署名をユーザーに促し、メインのトランザクションを実行する前にそれらが完了していることを保証します。
スマートコントラクトウォレットでのブリッジ・スワップ・支払い
dAppsがユーザーに対してチェーンB上のトークンZでの支払いを要求するが、ユーザーはチェーンA上にトークンYしか持っていない場合を考えます。
dAppsは支払いトランザクションとともにチェーンB上のトークンZ残高要件をケーパビリティとして指定します。
スマートコントラクトウォレットは、必要なすべてのトランザクション(ブリッジ・スワップ・支払い)に一度に署名することをユーザーに求め、適切な順序で実行します。
署名済みトランザクションはバンドラーに同時に送信でき、ウォレットが切断されても操作が完了できます。
後方互換性
ERC7795はEIP5792のケーパビリティシステムを使用しているため、このケーパビリティをサポートしていないウォレットでも、単純にケーパビリティを無視して通常のwallet_sendCallsとして処理することができます。
セキュリティ
セキュリティに関する考慮事項として、以下の点に注意が必要です。
過度な承認
dAppsが必要以上の承認額を要求する可能性があります。
ウォレットは要求された承認額をユーザーに明示し、必要に応じて調整できるようにすべきです。
また、無制限承認(type(uint256).max)の要求には特に注意が必要です。
悪意のあるdApps
悪意のあるdAppsがユーザーの資産を狙った前提条件を設定する可能性があります。
ウォレットは前提条件を満たすために実行するトランザクションの詳細をユーザーに表示し、明示的な承認を得るべきです。
トランザクション順序の操作
前提条件を満たすトランザクションと元のcallsの間でフロントランニング攻撃が発生する可能性があります。
ウォレットは可能な限りアトミックな実行(バッチトランザクション)を使用すべきです。
ウォレット開発者は、前提条件を満たすために自動的に実行するトランザクションについて、ユーザーに明確な同意を求める必要があります。
引用
最後に
今回は「ERC7795によるdAppsがウォレットにトークン前提条件を指定できる仕組み」についてまとめてきました!
いかがだったでしょうか?
質問などがある方は以下のTwitterのDMなどからお気軽に質問してください!
他の媒体でも情報発信しているのでぜひ他も見ていってください!
