介绍:更快的 getProgramAccounts (gPA) 调用

  • Helius
  • 发布于 2024-12-18 11:37
  • 阅读 18

本文介绍了Helius推出的新型getProgramAccounts方法,该方法显著提升了Solana开发者查询公钥持有账户的速度。文章详细说明了如何使用API进行查询,包括基本和带过滤条件的示例代码,强调了新方法的高效性和更好的性能。最后,提供了进一步的资源和支持信息。

getProgramAccounts (gPA) 调用 一直以来都存在许多问题。这个 RPC 方法是一项耗费资源且效率低下的操作,它查询一个节点以获取由给定公钥拥有的所有账户。这些调用通常很慢,并且受到严格的速率限制。有时,如果结果尚未被缓存,这些调用甚至会被完全禁止(例如,在 Serum 的程序上进行 gPA 调用)。这些问题迫使开发者寻求那些不那么高效的繁琐替代方案。

今天这一切都将改变。

在 Helius,我们为所有 Solana 开发者引入了 更快的 getProgramAccounts 调用。

以下是新功能:

  • 我们显著改善了账户索引
  • 你可以期待 gPA 调用比以前快 2-10 倍,尤其是在对大型程序使用过滤器时
  • 我们会在 任何开发者 的单次调用后自动为程序索引,从而提高整个网络的性能

入门指南

要开始使用,请在 Helius 开发者仪表板 注册并在“API 密钥”部分获取一个 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(`所有由 Ore v2 程序拥有的账户: ${JSON.stringify(data, null, 2)}`);
  } catch (error) {
    console.error(error);
  }
};

getProgramAccounts();

让我们来分解一下代码的工作方式:

  1. URL 配置: 我们创建一个指向 Helius RPC 端点并提供我们的 API 密钥的 URL
  2. RPC 请求结构
    • method: “ getProgramAccounts 指定我们想要查询程序拥有的账户
    • params 是一个包含两个元素的数组:我们想要查询的程序 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",  // 代币程序地址
          {
            "encoding": "jsonParsed",  // 获取解析后的代币数据
            "filters": [
              {
                "dataSize": 165,  // 代币账户数据的大小
              },
              {
                "memcmp": {
                  "offset": 32,  // 代币账户中拥有者地址的位置
                  "bytes": "YOUR_WALLET_ADDRESS"
                }
              }
            ]
          }
        ]
      })
    });
    const data = await response.json();

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

      console.log(`-- 代币账户 ${i + 1}: ${account.pubkey} --`);
      console.log(`铸造: ${parsed.mint}`);
      console.log(`数量: ${parsed.tokenAmount.uiAmount}`);
    });
  } catch (error) {
    console.error("获取代币账户时出错:", error);
  }
};

getTokenAccounts();

该示例在基本示例的基础上展示了两种重要的过滤技术:使用 dataSizememcmp 过滤器。

dataSize

dataSize 过滤器检查给定账户的确切数据大小。在我们这里,我们关注的代币账户的大小为 165 字节。这将立即筛选掉由提供的钱包拥有的任何其他账户,排除代币账户之外的账户。

memcmp 过滤器(内存比较)

memcmp 过滤器或内存比较过滤器,允许我们比较存储在内存特定位置的数据。我们使用一个偏移量来指定开始比较数据的位置。

在我们的示例中,我们使用 32 的偏移量跳过铸造地址,因为铸造地址存储在前 32 字节的内存中,我们只关注拥有者地址。这个过滤器将只返回由指定钱包地址拥有的账户。

运行这段代码将会在控制台记录所提供钱包地址的所有代币账户及其余额列表。通过 Helius 的改进索引,这些经过过滤的查询明显比其他传统 RPC 提供商的查询更快。

额外帮助

准备好体验更少的麻烦和更快的 getProgramAccounts 调用了吗?

如果你看到这里,谢谢你,伙计!请确保在下面输入你的电子邮件地址,这样你就可以及时收到有关 Solana 新动态的更新。如果你在学习狂欢中?浏览我们 博客 上的最新文章,加速你的 Solana 之旅。

  • 原文链接: helius.dev/blog/faster-g...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
Helius
Helius
https://www.helius.dev/