コンテンツへスキップ
0%

User operationsとは?

2023年6月26日 公開読了時間 1 分

ユーザーオペレーションとは、送信者のスマートコントラクトアカウントの代わりに実行されるトランザクションの詳細を含むオブジェクトです。ユーザーオペレーションは疑似トランザクションオブジェクトであり、ERC-4337をサポートするEthereumおよびレイヤー2ブロックチェーンにコンセンサスレイヤーの変更を要求することなくAccount Abstractionを機能させます。

スマートコントラクトウォレット(SCW)を開発する、あるいは分散型アプリケーションをSCWに対応させるためには、ユーザーオペレーションを定義するパラメータ、ユーザーオペレーション構築プロセス中にユーザーオペレーションのフィールドがどのように設定されるか、ユーザーオペレーションがBundlerによってどのようにバンドルされるか、そしてペイマスターによってどのように検証・実行されるかを理解しておくと役立ちます。

Embedded AccountsとAccount Abstractionインフラストラクチャを使用して、新規ユーザー向けに埋め込み型のメールアドレスとパスキーのウォレットを作成できるようにしましょう!

動画で見る: Solidityでユーザーオペレーションを構築・実行する

ユーザーオペレーションに含まれるフィールドとは?

ユーザーオペレーション(UO)には、通常のトランザクションと同様のフィールド(例:sender、to、calldata、maxFeePerGas、maxPriorityFee、signature、nonce)が含まれますが、それに加えてユーザーオペレーション構造体に特有の新しいフィールド(callGasLimit、verificationGasLimit、preVerificationGas、paymasterAndData)も持っています。

UOフィールドの定義はERC-4337の公式仕様に記載されています。ここではその概要をまとめます。

  • callGasLimit - メインの実行呼び出しで使用されるガス
  • verificationGasLimit - 検証ステップを完了するために使用されるガス
  • preVerificationGas - 検証前の実行およびcalldataコストをカバーするためにBundlerへ支払うガス
  • paymasterAndData - スポンサーとなるペイマスターのアドレスと、ペイマスターへ送信するデータ

ユーザーオペレーションの設計とアーキテクチャについての解説は、AlchemyのAAインフラチームのエンジニアであるDavid Philipsonが執筆した「You Could Invented Account Abstraction」シリーズのパート1で読むことができます。

次に、ユーザーオペレーション内のフィールドを正しく設定するための標準的なワークフローを見ていきましょう。

ユーザーオペレーションの送信の流れとは?

Bundlerへユーザーオペレーション(ユーザーオペ)を送信する典型的な流れは、複数のステップで構成されます。

  1. sender、nonce、initCode、callDataを入力した部分的なユーザーオペを構築する
  2. eth_estimateUserOperationGasを介してBundlerのRPCに対し、部分的なユーザーオペのガスを見積もる
  3. preVerificationGas、verificationGasLimit、callGasLimitを設定する
  4. ERC20ペイマスターのような、ユーザーオペの内容に依存しないペイマスターを使用する場合、ここでpaymasterAndDataを設定できます。
  5. このオペレーションに必要なガス料金を見積もり、maxFeePerGasおよびmaxPriorityFeePerGasを設定する
  6. (任意) スポンサーとなるペイマスターにユーザーオペを送信して署名を得て、paymasterAndDataを設定する
  7. ペイマスターの署名には上記すべてのフィールドが設定されている必要があるため、このステップで実施する必要があります。
  8. ユーザーオペに署名し、signatureを設定して、eth_sendUserOperationを介してBundlerへユーザーオペを送信する

開発者はネイティブのethers.jsを使用して各ユーザーオペレーションフィールドの値を取得できますが、UO構築を容易にするいくつかのweb3開発者ツールもあります。

開発者はユーザーオペレーションの構築にどのツールを使用できますか?

AlchemyのオープンソースAA SDKのようなユーザーオペレーション構築ツールを使うと、ネイティブのethers.jsでユーザーオペを作成するよりも簡単にユーザーオペレーションを構築できます。

AlchemyのAA SDK

AlchemyのAA SDKはviemを使って構築されており、開発者に軽量なバンドルを提供します。GitHub上のaa-sdkは、aa-ethersライブラリを通じてethers.jsのsignerおよびproviderもサポートしています。

aa-sdkを使用してユーザーオペレーションを構築する主な利点の一つは、2つのユーティリティメソッドです。

  1. sendUserOperation - ガス見積もり、paymasterAndDataのリクエスト、署名などを処理する
  2. sendTransaction - トランザクションオブジェクトデータ(from、to、data、value)をユーザーオペレーションに変換する

ユーザーオペレーションを構築するための処理の順序は複雑ですが、AlchemyのAA-SDKは、getDummyPaymasterData、estimateGasによるガス見積もり、続いてgetFeeData、最後にgetPaymasterAndDataという一連の処理を実行することでUO構築を単純化します。

ユーザーオペのフィールドの値を取得した後、target、callData、そして任意のvalueを使用してユーザーオペレーションを構築・署名します。その後、ユーザーオペをBundlerに送信し、ユーザーオペのハッシュを受け取ります。

Alchemyのペイマスター、別のペイマスターを使用したい場合、あるいは独自のSmartAccountsのサポートを追加する予定がある場合は、AlchemyのAA SDKドキュメントでUOを簡単に作成する方法の詳しい説明をお読みください。

ユーザーオペレーションはどのようにユーザーオペMempoolへ追加されますか?

ユーザーオペがMempoolに追加される前に、ERC-4337の仕様に定められた期待される動作に従っているかを確認するための一連のチェックに合格する必要があります。ユーザーオペはまた、(送信者のウォレットまたはペイマスターのスポンサーシップポリシーを通じて)ガス代を支払うことができる有効なものであることを確認する検証シミュレーションチェックにも合格する必要があります。

1. ユーザーオペの有効性がチェックされる

最初の一連のチェックは、ERC-4337仕様の「Client behavior upon receiving a UserOperation」セクションで説明されており、以下にその要約を示します。

  • 送信者が既存のコントラクトであるか、(コントラクト作成に使用される)initCodeが空でないか(ただし両方であってはならない)
  • (ユーザーオペがアカウントを作成するため)initCodeが空でない場合、ファクトリーがステークされているかどうかを判定する
  • verificationGasLimitが十分に低い(MAX_VERIFICATION_GAS以下である)
  • preVerificationGasがcalldataのガスおよびオーバーヘッドのガス料金を支払うのに十分高い
  • paymasterAndDataが空であるか、ペイマスターのアドレスで始まっている
  • ペイマスターが存在する場合、それはオンチェーンに空でないコードを持ち、ユーザーオペを支払う資金を持ち、禁止されていない
  • callgasが非ゼロの値を持つCALLのコスト以上である
  • maxFeePerGasおよびmaxPriorityFeePerGasが、クライアントが受け入れる最小値を上回っている
  • 送信者がプール内に他のユーザーオペを持っていない(または、そのユーザーオペが既存のエントリを置き換えるために構築されている)

これらのチェックに影響を与えうるルールは多数あり、詳細は仕様の中で説明されています。

このユーザーオペレーションの入門記事では、ユーザーオペの有効性を判定するために行われる高レベルなチェックについて伝えることのみを目的としています。

2. ユーザーオペレーションがシミュレートされる

ユーザーオペがこれらの基本的なチェックに合格すると、クライアントはユーザーオペレーションをシミュレートして、そのユーザーオペが自身の資金を使うか、あるいはペイマスターを使うかして、実行のための支払いが可能であることを検証する必要があります。

ユーザーオペをシミュレートするために、BundlerはsimulateValidation()メソッドを呼び出します。これにより、送信者のアカウントのvalidateUserOp関数、または、ガス代のスポンサーとしてペイマスターが使用される場合はペイマスターのコントラクトアカウントのvalidatePaymasterUserOpが呼び出されます。

**simulateValidation()**メソッドが呼び出された後、ValidationResultレスポンスとともにリバートします。この関数がリバートすることが意図された動作であり、これは成功した結果と見なされます。

ValidationResultが異なるエラーでリバートした場合、そのユーザーオペは検証シミュレーションに合格しなかったことになり、Mempoolには追加されません。ユーザーオペはsigFailを返す場合はMempoolから除外され、またvalidUntilのレスポンスが期限切れになった場合もUOがMempoolから除外されることがあります。

注記: ユーザーオペにinitCodeが存在する場合、アカウントファクトリーによってアカウントが作成され、その後、新しく作成されたアカウントを使ってシミュレーションプロセスが進められます。

ユーザーオペレーションが構築、チェック、シミュレートされ、Mempoolに追加された今、それを検証と実行のためにエントリーポイントコントラクトへ送信できます!

ユーザーオペレーションはどのように検証・実行されますか?

ユーザーオペレーション内のトランザクションの詳細がオンチェーンで公開されるためには、エントリーポイントコントラクトがそのユーザーオペレーションを検証する必要があり、UOが検証に合格した場合、エントリーポイントコントラクトはそのトランザクションを実行し、その後Bundlerにガス代を払い戻します。

ユーザーオペの検証と実行の基本的なステップは以下の通りです。

  1. Bundlerが、handleOps()メソッドを介して単一のエントリーポイントコントラクトにユーザーオペを送信する
  2. 各オペに対して、エントリーポイントはそのオペの送信者ウォレットでvalidateOpを呼び出す*
  3. いずれかのオペが検証ステップに失敗した場合、それらは破棄される
  4. 次に、各オペの送信者ウォレットに対してexecuteOpを呼び出し、使用されたガスの量を記録する
  5. 送信者のウォレットまたはペイマスターから、各オペの実行に使用されたガス代を支払うためにETHをBundlerへ送金する

*すべての検証が実行され、その後で初めて検証済みのユーザーオペに対するすべての実行が実行されます。

以下は、送信者のスマートコントラクトウォレットに代わって、エントリーポイントコントラクトによってユーザーオペレーションがどのように検証・実行されるかを示す図です。

User Operationがどのように検証・実行されるか

ユーザーオペレーションは、スマートコントラクトウォレットがEthereumおよび同等のL2上でユーザーのプライマリウォレットとして機能することを可能にする疑似トランザクションオブジェクトです。スマートコントラクトウォレットは、ブロックチェーンをよりアクセスしやすくするweb3 UXの利点をもたらしますが、それを可能にしているのはEthereumおよび L2上のAAインフラストラクチャプロバイダーです。

もしあなたのweb3プロダクトがスマートコントラクトウォレットをサポートしているなら、Ethereum、Polygon、Arbitrum、OptimismおよびSepoliaのような人気のテストネット向けのGas Manager APIやBundler APIを含む、AlchemyのAAインフラストラクチャをぜひご覧ください!

Background gradient

ブロックチェーンで魔法を生み出す

Alchemyは、最も強力なweb3開発者向けプロダクトとツールを、豊富なリソース、コミュニティ、そして卓越したサポートと組み合わせて提供します。