Polkadot 链上状态查询实战教程:使用 PAPI 查询账户余额与 USDT 资产信息(Polkadot Hub 完整示例)

原文作者:PaperMoon团队

基于 Polkadot SDK 构建的区块链,其链上数据存储于 键值数据库(Key-Value Database) 中。外部应用程序可以通过 RPC 与 SDK 查询这些链上状态(On-Chain State)。

链上状态包括但不限于:
    •    账户余额(Account Balances)
    •    资产信息(Assets Metadata & Details)
    •    治理提案(Governance Proposals)
    •    Runtime 管理的任意存储数据

本文将以 Polkadot Hub(Asset Hub) 为例,演示如何使用主流 SDK 查询链上存储数据,并提供完整可运行示例。

支持的 SDK 列表

本文涵盖以下五种主流 SDK:

SDK

语言

特点

Polkadot API (PAPI)

TypeScript

现代、类型安全 API

Polkadot.js API

JavaScript

功能全面(维护模式)

Dedot

TypeScript

轻量、高性能

Python Substrate Interface

Python

适合后端与数据处理

Subxt

Rust

编译期类型安全

⚠️ 本文示例使用 Polkadot API(PAPI) 进行完整演示。

环境准备(Prerequisites)

1. Node.js
    •    版本:v18 或更高

2. 包管理工具
    •    npm
    •    pnpm
    •    yarn

项目初始化(Environment Setup)

1. 创建并初始化项目

mkdir papi-query-example && cd papi-query-example && \
npm init -y && npm pkg set type=module

2. 安装依赖

npm install polkadot-api && \
npm install --save-dev @types/node tsx typescript

3. 生成 Polkadot Hub 类型定义

npx papi add pah -n polkadot_asset_hub

说明:
    •    pah 是 Polkadot Asset Hub 的 descriptor
    •    该步骤生成强类型 API 访问接口

查询账户余额(Query Account Balance)

【代码示例】

import { createClient } from 'polkadot-api';
import { getWsProvider } from 'polkadot-api/ws-provider/node';
import { withPolkadotSdkCompat } from 'polkadot-api/polkadot-sdk-compat';
import { pah } from '@polkadot-api/descriptors';

const ASSET_HUB_RPC = 'INSERT_WS_ENDPOINT';

// Example address to query (Polkadot Hub address)
const ADDRESS = 'INSERT_ADDRESS';

async function main() {
  // Create the client connection
  const client = createClient(
    withPolkadotSdkCompat(getWsProvider(ASSET_HUB_RPC))
  );

  // Get the typed API for Polkadot Hub
  const api = client.getTypedApi(pah);

  console.log('Connected to Polkadot Hub');
  console.log(`Querying balance for: ${ADDRESS}\n`);

  // Query the System.Account storage
  const accountInfo = await api.query.System.Account.getValue(ADDRESS);

  // Extract balance information
  const { data, nonce } = accountInfo;
  const { free, reserved, frozen } = data;

  console.log('Account Information:');
  console.log(`  Nonce: ${nonce}`);
  console.log(`  Free Balance: ${free}`);
  console.log(`  Reserved: ${reserved}`);
  console.log(`  Frozen: ${frozen}`);

  // Disconnect the client
  client.destroy();
}

main().catch(console.error);

⚠️ 参数替换说明

请替换以下参数:
    •    INSERT_WS_ENDPOINT
例如:

wss://polkadot-asset-hub-rpc.polkadot.io

    •    INSERT_ADDRESS
替换为你需要查询的账户地址。

运行脚本

npx tsx query-balance.ts

示例输出

Connected to Polkadot Hub
Querying balance for: 14E5nqKAp3oAJcmzgZhUD2RcptBeUBScxKHgJKU4HPNcKVf3
Account Information:
 Nonce: 0
 Free Balance: 0
 Reserved: 0
 Frozen: 0

📘 字段说明

字段

说明

nonce

账户交易计数

free

可用余额

reserved

保留余额

frozen

冻结余额

查询资产信息(Query Asset Information)

本示例查询:
    •    USDT 资产元数据
    •    资产详情
    •    指定账户的 USDT 余额

USDT 在 Polkadot Hub 的资产 ID 为:1984

示例文件:query-asset.ts

import { createClient } from 'polkadot-api';
import { getWsProvider } from 'polkadot-api/ws-provider/node';
import { withPolkadotSdkCompat } from 'polkadot-api/polkadot-sdk-compat';
import { pah } from '@polkadot-api/descriptors';

const ASSET_HUB_RPC = 'INSERT_WS_ENDPOINT';

// USDT on Polkadot Hub
const USDT_ASSET_ID = 1984;

// Example address to query asset balance
const ADDRESS = 'INSERT_ADDRESS';

async function main() {
  // Create the client connection
  const client = createClient(
    withPolkadotSdkCompat(getWsProvider(ASSET_HUB_RPC))
  );

  // Get the typed API for Polkadot Hub
  const api = client.getTypedApi(pah);

  console.log('Connected to Polkadot Hub');
  console.log(`Querying asset ID: ${USDT_ASSET_ID}\n`);

  // Query asset metadata
  const assetMetadata = await api.query.Assets.Metadata.getValue(USDT_ASSET_ID);

  if (assetMetadata) {
    console.log('Asset Metadata:');
    console.log(`  Name: ${assetMetadata.name.asText()}`);
    console.log(`  Symbol: ${assetMetadata.symbol.asText()}`);
    console.log(`  Decimals: ${assetMetadata.decimals}`);
  }

  // Query asset details
  const assetDetails = await api.query.Assets.Asset.getValue(USDT_ASSET_ID);

  if (assetDetails) {
    console.log('\nAsset Details:');
    console.log(`  Owner: ${assetDetails.owner}`);
    console.log(`  Supply: ${assetDetails.supply}`);
    console.log(`  Accounts: ${assetDetails.accounts}`);
    console.log(`  Min Balance: ${assetDetails.min_balance}`);
    console.log(`  Status: ${assetDetails.status.type}`);
  }

  // Query account's asset balance
  console.log(`\nQuerying asset balance for: ${ADDRESS}`);
  const assetAccount = await api.query.Assets.Account.getValue(
    USDT_ASSET_ID,
    ADDRESS
  );

  if (assetAccount) {
    console.log('\nAsset Account:');
    console.log(`  Balance: ${assetAccount.balance}`);
    console.log(`  Status: ${assetAccount.status.type}`);
  } else {
    console.log('\nNo asset balance found for this account');
  }

  // Disconnect the client
  client.destroy();
}

main().catch(console.error);

运行脚本

npx tsx query-asset.ts

示例输出

Connected to Polkadot Hub
Querying asset ID: 1984
Asset Metadata:
 Name: Tether USD
 Symbol: USDT
 Decimals: 6
Asset Details:
 Owner: 15uPcYeUE2XaMiMJuR6W7QGW2LsLdKXX7F3PxKG8gcizPh3X
 Supply: 77998622834581
 Accounts: 13544
 Min Balance: 10000
 Status: Live
Querying asset balance for: 14E5nqKAp3oAJcmzgZhUD2RcptBeUBScxKHgJKU4HPNcKVf3
No asset balance found for this account

查询逻辑结构图

应用程序
   ↓
PAPI Client
   ↓
WebSocket RPC
   ↓
Polkadot Hub
   ↓
Runtime Storage (Key-Value DB)

技术补充说明

System.Account 存储结构

AccountInfo {
  nonce,
  data: {
    free,
    reserved,
    frozen
  }
}

Assets Pallet 查询结构
    •    Assets.Metadata
    •    Assets.Asset
    •    Assets.Account

均为链上 Storage 项。

为什么使用 Typed API?

PAPI 提供:
    •    编译期类型安全
    •    自动 Metadata 解析
    •    避免编码错误
    •    更好的 IDE 自动补全支持

原文链接:https://docs.polkadot.com/chain-interactions/query-data/query-sdks/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值