新着:HeliusがLight Protocolを買収
新登場:より高速な getProgramAccounts(gPA)呼び出し
ブログ/更新情報

新登場:より高速な getProgramAccounts(gPA)呼び出し

Developer Experience EngineerXの0xIchigoLinkedInの0xIchigoGitHubの0xIchigo
読了時間:3分

getProgramAccounts(gPA)呼び出しには、問題が多いことで知られています。この RPC メソッドは、指定された公開鍵が所有するすべてのアカウントを取得するためにノードへクエリを実行する、コストが高く非効率な処理です。呼び出しに時間がかかるうえ、厳しいレート制限も課されます。結果がキャッシュされていない場合、呼び出し自体が完全に禁止されることもあります(例:Serum のプログラムに対する gPA 呼び出し)。こうした問題により、開発者は効率が劣る手間のかかる代替手段を探さざるを得ませんでした。 

その状況が、今日から変わります。

Helius は、すべての Solana 開発者に向けて、より高速な getProgramAccounts 呼び出しを提供します。 

主なアップデートは次のとおりです:

  • アカウントのインデックス作成を大幅に改善しました
  • gPA 呼び出しは従来より2〜10倍高速になります。特に、大規模なプログラムにフィルターを使用する場合に効果的です
  • どの開発者からでも1回呼び出されると、そのプログラムを自動的にインデックス化するため、すべてのユーザーのパフォーマンスが向上します

はじめに

まず、Helius Developer Dashboardに登録し、「API Keys」セクションで API キーを取得します。 

getProgramAccounts の例

JavaScript を使用して、Ore V2 プログラムが所有するすべてのアカウントをクエリしてみましょう:

コード
const url = `https://mainnet.helius-rpc.com/?api-key=<API_KEY>`;

const getProgramAccounts = async () => {
  try {
    const response = await fetch(url, {
      method: "POST",
      headers: {
        "Content-Type": "application/json"
      },
      body: JSON.stringify({
        jsonrpc: "2.0",
        id: "test",
        method: "getProgramAccounts",
        params: [
          "oreV2ZymfyeXgNgBdqMkumTqqAprVqgBWQfoYkrtKWQ",
          {
            "encoding": "base64",
          },

        ],

      })
    });

    const data = await response.json();

    console.log(`All Accounts Owned By The Ore v2 Program: ${JSON.stringify(data, null, 2)}`);
  } catch (error) {
    console.error(error);
  }
};

getProgramAccounts();

このコードの仕組みを詳しく見ていきます:

  1. URL の設定:Helius RPC エンドポイントを指定する URL を作成し、API キーを渡します
  2. RPC リクエストの構造
    • method: “getProgramAccounts” は、プログラムが所有するアカウントをクエリすることを指定します
    • params は2つの要素を含む配列です。クエリ対象のプログラム ID(ここでは Ore の V2 プログラム)と、クエリ用の設定オブジェクトが含まれます
  3. エンコーディング:アカウントデータを base64 エンコーディングでリクエストします
  4. エラー処理:発生したエラーを try/catch ブロックで処理します

このコードを実行すると、Ore の V2 プログラムが所有するすべてのアカウントがコンソールに出力されます。 

ただし、これは基本的な例です。通常はフィルターを使用して結果を絞り込み、パフォーマンスを向上させます。

フィルターを使用した getProgramAccounts の例

フィルターを使用して、特定のアドレスが所有するすべてのトークンアカウントをクエリする、より実践的な例を見てみましょう:

コード
const url = `https://mainnet.helius-rpc.com/?api-key=<API_KEY>`;

const getTokenAccounts = async () => {
  try {
    const response = await fetch(url, {
      method: "POST",
      headers: {
        "Content-Type": "application/json"
      },
      body: JSON.stringify({
        jsonrpc: "2.0",
        id: "token-accounts",
        method: "getProgramAccounts",
        params: [
          "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",  // Token Program address
          {
            "encoding": "jsonParsed",  // Get parsed token data
            "filters": [
              {
                "dataSize": 165,  // Size of token account data
              },
              {
                "memcmp": {
                  "offset": 32,  // Location of owner address in the token account
                  "bytes": "YOUR_WALLET_ADDRESS"
                }
              }
            ]
          }
        ]
      })
    });
    const data = await response.json();

    data.result.forEach((account, i) => {
      const parsed = account.account.data.parsed.info;

      console.log(`-- Token Account ${i + 1}: ${account.pubkey} --`);
      console.log(`Mint: ${parsed.mint}`);
      console.log(`Amount: ${parsed.tokenAmount.uiAmount}`);
    });
  } catch (error) {
    console.error("Error fetching token accounts:", error);
  }
};

getTokenAccounts();

この例は基本的な例を発展させ、dataSize フィルターと memcmp フィルターを使用する、2つの重要なフィルタリング手法を示しています。

dataSize

dataSize フィルターは、指定されたアカウントの正確なデータサイズを確認します。ここでは、165バイトのトークンアカウントを対象としています。これにより、指定されたウォレットが所有するアカウントのうち、トークンアカウントではないものが即座に除外されます。

memcmp フィルター(メモリ比較)

memcmp フィルター(メモリ比較フィルター)を使用すると、メモリ内の特定の位置に保存されたデータを比較できます。データの比較を開始する位置は、オフセットで指定します。 

この例では、所有者アドレスのみを対象とするため、オフセットに32を指定し、メモリの先頭32バイトに保存されているミントアドレスをスキップします。このフィルターは、指定されたウォレットアドレスが所有するアカウントのみを返します。

このコードを実行すると、指定されたウォレットアドレスに属するすべてのトークンアカウントと、その残高の一覧がコンソールに出力されます。Helius の改良されたインデックス機能により、こうしたフィルター付きクエリは、従来の他の RPC プロバイダーよりも大幅に高速です。

さらにサポートが必要な場合

面倒を減らし、getProgramAccounts 呼び出しを高速化しませんか? 

Helius Developer Dashboardに登録して、今すぐ優れたパフォーマンスで開発を始めましょう。サポートが必要ですか?ご質問やサポートについては、Helius Discordをご利用ください!

ここまでお読みいただき、ありがとうございます!以下にメールアドレスを入力すると、Solana の最新情報を見逃すことはありません。さらに学びたいですか?ブログで最新記事を読み、Solana の探求を加速させましょう。

Heliusを購読

Solana開発の最新情報や新しい記事の公開通知を受け取れます