getProgramAccounts RPC メソッドは、Solana ブロックチェーンのクエリを行うための強力なツールです。特定のオンチェーンプログラムが所有するすべてのアカウントを取得できます。これは、特定のトークンミントのユーザー関連のすべてのトークンアカウントを見つけたり、分散型アプリケーションのすべてのユーザー固有データアカウントを発見したりするなど、多様なアプリケーションに不可欠です。
プログラムが所有する可能性のあるアカウントの数が非常に多いため、getProgramAccounts は検索を絞り込み、効率的に必要なデータのみを取得するための強力なフィルタリング機能を提供します。
非常に多くのプログラムアカウントをクエリする必要があるアプリケーションでは、getProgramAccountsV2 の使用を検討してください。この方法はカーソルベースのページネーションをサポートし、1 リクエストあたり最大 10,000 アカウントのページサイズを構成可能です。
一般的な使用例
- ミントのすべてのトークンアカウントを見つける: 特定のSPLトークンのすべての保有者を発見します。
- ユーザー固有データの取得: 特定のユーザーのためにプログラムが作成したすべてのアカウントを取得します(例:DeFiプロトコルのユーザーのポジション、Play-to-Earnゲームのゲーム状態)。
- カスタムアカウントタイプのすべてのインスタンスのリスト: プログラムが特定のアカウント構造を定義している場合、
getProgramAccountsはその構造のすべてのインスタンスを見つけることができます。 - プログラムステートの監視: プログラムに関連するすべてのアカウントを観察して、プログラムの全体的な状態や活動を追跡します。
- エクスプローラーや分析ツールの構築: プログラムとその関連アカウントに関するデータを集約します。
リクエストパラメータ
-
programId(string, 必須):- 取得したいアカウントが所属するプログラムのbase-58エンコードされた公開鍵です。
- 例:
"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"(SPLトークンプログラムの場合)。
-
options(object, 任意): 次のフィールドを含む構成オブジェクト:commitment(string): コミットメントレベル を指定します(例:"finalized","confirmed")。encoding(string): 各返されたアカウント内のdataフィールドのエンコーディング。デフォルトは"base64"です。"base58": バイナリデータの遅い代替。"base64": 標準のbase64エンコーディング。"base64+zstd": base64エンコードされたzstd圧縮バイナリデータ。"jsonParsed": RPCノードにプログラムのアカウントタイプのパーサーがある場合、dataフィールドは構造化されたJSONオブジェクトとなります。可読性と使いやすさのためにお勧めします。
filters(array): 適用するフィルタオブジェクトの配列。パフォーマンスと関連性のために重要です。最大4つのフィルタを使用できます。一般的なフィルタには次のものがあります:dataSize(object):dataSize(u64): アカウントをそのデータのバイト長でフィルタします。例:{ "dataSize": 165 }(SPLトークンアカウントの場合)。
memcmp(object): メモリ比較。アカウントのデータのスライスと指定されたバイトを比較します。offset(usize): アカウントデータ内の比較を開始するバイトオフセット。bytes(string): 照合するバイトのbase-58エンコードされた文字列。バイト文字列は129バイト未満でなければなりません。- 例: 特定のミントのトークンアカウントを見つけるには、
memcmpを使用し、offset: 0(トークンアカウントにミントアドレスが格納されている場所)と、ミントの公開鍵に設定されたbytesを使用します。
dataSlice(object): 各アカウントのデータの特定のスライスのみを返します。大きなアカウントで部分データのみが必要な場合に便利です。offset(usize): スライスを開始するオフセットバイト。length(usize): 返すバイト数。- 注意:
dataSliceは主にバイナリエンコーディング用であり、jsonParsedには適用されません。
withContext(boolean):trueである場合、応答はRpcResponseオブジェクトに含まれるcontext(slot付き)とvalue(アカウントの配列)になります。falseまたは省略された場合、通常はアカウントの配列だけを返します。動作はRPCプロバイダによってわずかに異なることがあります。minContextSlot(u64): リクエストを評価できる最低スロット。
応答構造
応答はオブジェクトの配列で、それぞれのオブジェクトは発見されたアカウントを表し、次の内容が含まれます:pubkey(string): アカウントのbase-58エンコードされた公開鍵。account(object):lamports(u64): アカウントのラメポートでの残高。owner(string): このアカウントを所有するプログラムのbase-58エンコードされた公開鍵(クエリしたprogramIdです)。data(string,array, またはobject):encodingパラメータに従って書式設定されたアカウントのデータ。jsonParsedの場合: デシリアライズされたアカウント状態を表すJSONオブジェクト。base64の場合: 配列["encoded_string", "base64"]。
executable(boolean): アカウントが実行可能かどうか(すなわちプログラムそのもの)を示します。rentEpoch(u64): 次にこのアカウントが賃貸料を負うエポック。space(u64, 任意): アカウントのデータ長(バイト単位)。データがバッファの場合、または解析された構造の一部である場合はdata.lengthとも呼ばれます。
withContext: trueを使用する場合、この配列はvalue フィールド内の RpcResponse オブジェクトにネストされます。
例
1. 特定のミント(USDC)のすべてのトークンアカウントを見つける
この例ではUSDCを保持するすべてのSPLトークンアカウントを見つけます。dataSize を使用してトークンアカウント(165バイト)をフィルタし、memcmp を使用してオフセット0のUSDCミントアドレスに一致させます。
2. 特定のウォレットが所有するすべてのトークンアカウントを見つける
この例では特定のウォレットアドレスが所有するすべてのSPLトークンアカウントを見つけます。dataSize(165バイト)と、トークンアカウントにオーナーパブキーが格納されているオフセット32でmemcmpを使用します。
高度なフィルタリング
フィルタを使用してクエリを最適化し、応答サイズを削減し、パフォーマンスを向上させます。API Reference
getProgramAccounts
フィルタータイプ
memcmp: 特定のオフセットで特定のパターンに一致するアカウントをフィルタしますdataSize: データサイズが正確に一致するアカウントをフィルタします- 複数のフィルタ: すべての条件を満たさなければなりません(論理AND)
開発者向けのヒント
- パフォーマンス:
getProgramAccountsは、特にフィルタなしまたは多くのアカウントを持つプログラムでは、RPCノードでリソースを多く消費することがあります。可能な限りフィルタ(dataSize,memcmp)およびdataSliceを使用してクエリの範囲と応答サイズを削減してください。 - 大規模な結果セット: 多くの結果を返すクエリの場合、応答が切り捨てられたりタイムアウトすることがあります。範囲を削減するためにフィルタリングを使用するか、ページネーションサポートのある
getProgramAccountsV2を検討してください。 - レート制限: RPCプロバイダのレート制限に注意してください。頻繁または大規模な
getProgramAccounts呼び出しはこれらの制限に達する可能性があります。 - データレイアウトの知識:
memcmpの効果的な使用は、クエリしているアカウントデータのバイトレイアウトを理解することが必要です。 jsonParsedの利用可能性:jsonParsedエンコーディングは、特定のプログラムのアカウントタイプのためのパーサーを持つRPCノードに依存します。SPLトークンのような一般的なプログラムには広くサポートされています。
getProgramAccounts は、プログラムによって所有されるアカウントのセットをクエリして対話する必要がある開発者にとって不可欠なメソッドです。そのフィルタリングオプションの習熟が効率的で堅牢なSolanaアプリケーションの構築の鍵です。
大規模データセットのページネーション
多数のアカウントを所有するプログラムを扱うアプリケーションでは、getProgramAccountsV2を使用してください。これは次のことを提供します:
- カーソルベースのページネーション:
limit(1-10,000) を設定し、結果をナビゲートするためにpaginationKeyを使用します - インクリメンタルアップデート: 特定のスロット以降に変更されたアカウントのみを取得するために
changedSinceSlotを使用します - より良いパフォーマンス: タイムアウトを防ぎ、メモリ使用量を削減します
- ページネーションの動作: ページネーション終了はアカウントが返されなかった場合にのみ示されます。フィルタリングにより制限未満のアカウントが返される場合があるので、
paginationKeyがnullになるまでページネーションを続けてください。
関連メソッド
getProgramAccountsV2
大規模データセットのためのカーソルベースナビゲーションを用いたページネーション版