はじめに

初めまして。 『DApps開発入門』という本や色々記事を書いているかるでねです。

以下でも情報発信しているので、興味ある記事があればぜひ読んでみてください!

今回は、スマートアカウントのアクセスを安全に復旧するための共通インターフェースを提案している「ERC7947」についてまとめていきます。

以下にまとめられているものを解説しながらまとめていきます。

秘密鍵を紛失してもアカウントを復旧できるように、複数のリカバリプロバイダを組み合わせて使える標準的なインターフェースです。

概要

ERC7947は、Account Abstraction Recovery Interface(AARI)と呼ばれるスマートアカウント向けのリカバリインターフェースです。

スマートアカウントが秘密鍵を失った時に、あらかじめ登録しておいたリカバリプロバイダを通じてアクセスを復旧できる仕組みを提供します。 recoverAccess(subject, provider, proof) という関数を中心に、リカバリプロバイダの追加・削除・検証を行う共通インターフェースを定義しています。 どのAccount Abstraction標準(EIP4337やEIP7702等)とも組み合わせられる設計になっており、スマートアカウントの種類を問わず利用できます。

recovery-overview.png

EIP4337については以下の記事を参考にしてください。

EIP7702については以下の記事を参考にしてください。

動機

Account Abstraction(アカウント抽象化)によりスマートアカウントが普及すると、ユーザーは秘密鍵を直接管理しなくてもよい体験が実現します。 しかし、秘密鍵を紛失した場合のアクセス復旧方法が標準化されていないという課題がありました。

秘密鍵紛失の課題

EOA(Externally Owned Account)では秘密鍵を失うとアカウントのすべてにアクセスできなくなります。 スマートアカウントでも同様のリスクがあり、何らかのリカバリ手段が必要です。 しかし、現在のスマートアカウントは各プロジェクトが独自のリカバリ方法を実装しており、互換性がありません。

ZKAIとZK2FAの可能性

Zero-Knowledge Artificial Intelligence(ZKAI)やZero-Knowledge Two Factor Authentication(ZK2FA)といった技術が登場しています。 これらの技術を活用すれば、秘密鍵以外の方法で本人であることを証明し、アカウントへのアクセスを復旧できます。

ZKAIとZK2FA

ZKAIはゼロ知識証明とAIを組み合わせた技術で、例えば生体認証データをプライバシーを保護したまま検証できます。 ZK2FAはゼロ知識証明による二要素認証で、秘密の情報(パスワードやワンタイムコード等)を直接公開せずにその知識を証明できます。 これらはリカバリプロバイダとして実装でき、秘密鍵に代わる復旧手段を提供します。

リカバリプロバイダマーケットプレイス

ERC7947では、スマートアカウントが複数のリカバリプロバイダを登録できる「リカバリプロバイダアグリゲータ」として機能します。 ユーザーは複数のリカバリ手段を組み合わせられるため、中央集権的なサービスやプロジェクトに依存する必要がなくなります。 共通インターフェースが標準化されることで、リカバリプロバイダのマーケットプレイスが生まれる可能性もあります。

仕様

IAccountRecoveryインターフェース

スマートアカウントが実装するインターフェースです。 リカバリプロバイダの管理とアクセス復旧の機能を提供します。

javascript
interface IAccountRecovery {
    event AccessRecovered(bytes subject);
    event RecoveryProviderAdded(address indexed provider);
    event RecoveryProviderRemoved(address indexed provider);

    function addRecoveryProvider(address provider, bytes memory recoveryData) external payable;
    function removeRecoveryProvider(address provider) external payable;
    function recoveryProviderAdded(address provider) external view returns (bool);
    function recoverAccess(
        bytes memory subject,
        address provider,
        bytes memory proof
    ) external returns (bool);
}
addRecoveryProvider

リカバリプロバイダを追加する関数です。

  • 引数
    • provider 追加するリカバリプロバイダのアドレス。
    • recoveryData リカバリプロバイダに渡すカスタムデータ(コミットメント)。
  • アクセス制御されるべきです。
  • providerがaddress(0)でないことを確認しなければなりません。
  • providerのsubscribe関数を呼び出し、recoveryDataを渡さなければなりません。
removeRecoveryProvider

登録済みのリカバリプロバイダを削除する関数です。

  • 引数
    • provider 削除するリカバリプロバイダのアドレス。
  • アクセス制御されるべきです。
  • providerのunsubscribe関数を呼び出さなければなりません。
recoveryProviderAdded

リカバリプロバイダが登録済みかどうかを確認するview関数です。

  • 引数
    • provider 確認するプロバイダのアドレス。
  • 戻り値
    • 登録済みならtrue、未登録ならfalse。
recoverAccess

アカウントのアクセスを復旧する関数です。

  • 引数
    • subject 復旧対象(エンコードされたオーナーアドレス、アクセス制御ロール等)。
    • provider 使用するリカバリプロバイダのアドレス。
    • proof リカバリの証明(ZKP/ZKAI、署名等)。
  • 戻り値
    • 復旧成功ならtrue、失敗ならfalseまたはリバート。
  • providerがアカウントに登録されていることを確認しなければなりません。
  • providerのrecover関数を呼び出さなければなりません。
  • 証明の検証に成功した場合、subjectに従ってアカウントのアクセスを更新しなければなりません。

リカバリフロー

アカウント復旧は以下の流れで行われます。

  1. ユーザーは事前にaddRecoveryProviderでリカバリプロバイダを登録しておきます。この時、リカバリプロバイダに「コミットメント」(秘密のハッシュ値等)を渡します。
  2. 秘密鍵を紛失した場合、ユーザーはrecoverAccessを呼び出します。
  3. recoverAccessはリカバリプロバイダのrecover関数を呼び出し、ユーザーが提出した証明(proof)を検証・実行します(nonceを更新して再利用を防止します)。
  4. 証明が正しければ、スマートアカウントのアクセス権がsubjectに基づいて更新されます。
sequenceDiagram
    participant U as ユーザー
    participant SA as スマートアカウント
    participant RP as リカバリプロバイダ

    Note over U,RP: 事前登録フェーズ
    U->>SA: addRecoveryProvider(provider, recoveryData)
    SA->>RP: subscribe(recoveryData)
    RP-->>SA: コミットメントを保存

    Note over U,RP: 復旧フェーズ
    U->>SA: recoverAccess(subject, provider, proof)
    SA->>RP: recover(object, proof)
    RP-->>SA: 証明を検証
    SA-->>U: アクセス権を更新

interface-structure.png

IRecoveryProviderインターフェース

リカバリプロバイダが実装するインターフェースです。 スマートアカウントからのサブスクリプション管理とリカバリ証明の検証を行います。

javascript
interface IRecoveryProvider {
    event AccountSubscribed(address indexed account);
    event AccountUnsubscribed(address indexed account);

    function subscribe(bytes memory recoveryData) external payable;
    function unsubscribe() external payable;
    function getRecoveryData(address account) external view returns (bytes memory);
    function recover(bytes memory object, bytes memory proof) external;
}
subscribe

スマートアカウント(msg.sender)をリカバリプロバイダに登録する関数です。 recoveryDataをmsg.senderに紐づけて保存し、後のrecover関数での証明検証に使われるコミットメントとして管理します。

  • 引数
    • recoveryData リカバリのコミットメント(ハッシュ値やZKP公開出力等)。
unsubscribe

スマートアカウントのサブスクリプションを取り消す関数です。

  • msg.senderに関連するすべてのリカバリデータを削除しなければなりません。
getRecoveryData

アカウントのリカバリデータ(コミットメント)を取得するview関数です。

  • 引数
    • account リカバリデータを取得するアカウントのアドレス。
  • 戻り値
    • 関連するリカバリデータ。
recover

msg.sender(スマートアカウント)のリカバリを実行する関数です。 msg.senderのrecoveryDataを使ってproofの妥当性を確認し、証明の再利用を防ぐためにnonceなどを更新しなければなりません。 証明が無効な場合はリバートします。

  • 引数
    • object 新しいオブジェクト(subjectとは異なる場合がある)。
    • proof リカバリの証明。

subscribe/recoverの流れ

リカバリプロバイダとスマートアカウントの関係は「サブスクリプションモデル」になっています。

subscribeでは、スマートアカウントがリカバリプロバイダに「コミットメント」を渡して登録します。 このコミットメントは、秘密の情報のハッシュ値やZKPの公開出力のようなもので、秘密そのものは渡しません。

recoverでは、ユーザーが提出したproofがコミットメントと整合するかを検証します。 例えばZKP(ゼロ知識証明)を使えば、秘密の情報を明かさずに「自分がその秘密を知っている」ことを証明できます。 証明の再利用を防ぐためにnonceの更新が求められており、リプレイ攻撃(同じ証明を使い回す攻撃)が防止されます。

補足

設計の背景

ERC7947はいくつかの設計判断に基づいています。

任意のAA標準との互換性

この提案は特定のAccount Abstraction標準に依存しません。 EIP4337でもEIP7702でも、スマートアカウントがIAccountRecoveryインターフェースを実装するだけでリカバリ機能を利用できます。 これにより、アカウントリカバリの市場が特定のAA標準に縛られずに成長できます。

subjectとobjectがbytesである理由

recoverAccessのsubjectパラメータとrecoverのobjectパラメータは、アドレスではなくbytes型です。 スマートアカウントの中にはオーナーアドレスを持たないものもあり、ロールベースのアクセス制御を採用しているケースもあります。 bytes型にすることで、エンコードされたオーナーアドレス、アクセス制御ロール、その他のカスタムデータなど、柔軟な復旧対象を指定できます。

再コミットの方法

セキュリティ上の理由でコミットメントを更新したい場合は、unsubscribeとsubscribeをマルチコールで連続実行します。 これにより、古いコミットメントを削除してから新しいコミットメントを登録できます。

後方互換性

ERC7947は既存のスマートアカウントの仕様に影響を与えません。 IAccountRecoveryインターフェースを実装しない既存のコントラクトはそのまま動作し続けます。

セキュリティ

アカウントリカバリには重要なセキュリティ上の考慮事項があります。

アクセス制御の重要性

addRecoveryProviderとremoveRecoveryProvider関数は適切にアクセス制御されなければなりません。 これらの関数が誰でも呼び出せる状態だと、攻撃者が悪意のあるリカバリプロバイダを追加してアカウントを乗っ取る可能性があります。

フィッシング攻撃のリスク

ユーザーが騙されて悪意のあるリカバリプロバイダを追加してしまうリスクがあります。 悪意のあるリカバリプロバイダは偽のリカバリ証明を受け入れることで、アカウントの完全な制御権を得る可能性があります。 リカバリプロバイダの追加時にはプロバイダの信頼性を十分に確認することが重要です。

引用

最後に

今回は「ERC7947(Account Abstraction Recovery Interface)」についてまとめてきました。

スマートアカウントの秘密鍵を紛失した時に、あらかじめ登録しておいたリカバリプロバイダを通じてアクセスを復旧できる共通インターフェースを定義した提案です。 ZKPやZKAIを活用したリカバリプロバイダのマーケットプレイスが生まれる可能性もあり、Account Abstractionのユーザー体験をさらに向上させる重要な仕組みです。

他でも色々記事を書いているのでぜひよろしければ読んでいってください!