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

原文作者:PaperMoon团队

基于 Polkadot SDK 构建的区块链,其所有数据本质上都存储在链上的 Key-Value 数据库(键值数据库) 中。
任何外部应用(前端、后端服务、数据分析程序、机器人等)都可以通过 RPC 接口读取这些链上数据。

所谓 On-Chain State(链上状态),指的是运行时(Runtime)所管理的所有状态数据,包括:
    •    账户余额(Account Balance)
    •    资产信息(Assets Metadata)
    •    治理提案(Governance Proposals)
    •    质押与验证人信息(Staking State)
    •    以及 Runtime 维护的任意业务数据

本文将基于官方示例,讲解如何通过 SDK 查询这些数据,并提供可直接运行的完整代码。

支持的链上查询 SDK

Polkadot 生态提供多种语言 SDK 来访问链上存储:

SDK

语言

特点

PAPI (Polkadot API)

TypeScript

最新、类型安全、官方推荐

Polkadot.js API

JavaScript

最常用,但已进入维护模式

Dedot

TypeScript

轻量、高性能

Python Substrate Interface

Python

适合数据分析与脚本

Subxt

Rust

编译期类型安全、性能最佳

⚠️ 注意
Polkadot.js API 已不再主动开发,新项目建议使用 PAPI 或 Dedot。

链上数据查询原理

链上状态查询架构图

本地程序
   ↓
SDK (Polkadot.js / PAPI)
   ↓
WebSocket RPC
   ↓
Polkadot 节点
   ↓
Runtime Storage (Key-Value)

核心流程:
    1.    本地程序连接节点 RPC
    2.    SDK 构造存储查询
    3.    节点读取 Runtime Storage
    4.    返回 SCALE 编码数据
    5.    SDK 解码并输出

环境准备(Prerequisites)

请先安装:
    •    Node.js v18 或更高
    •    npm / pnpm / yarn

创建项目

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

安装依赖

npm install @polkadot/api

查询账户余额(Query Account Balance)

我们将读取 Runtime 存储中的:

System.Account

这是 Substrate 最基础的账户状态存储。

1)创建脚本

创建文件:

query-balance.js

并写入代码:

import { ApiPromise, WsProvider } from '@polkadot/api';

const ASSET_HUB_RPC = 'INSERT_WS_ENDPOINT';

// 示例地址(Polkadot Hub 地址)
const ADDRESS = 'INSERT_ADDRESS';

async function main() {
  // 创建 WebSocket Provider
  const wsProvider = new WsProvider(ASSET_HUB_RPC);

  // 初始化 API
  const api = await ApiPromise.create({ provider: wsProvider });

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

  // 查询 system.account 存储
  const accountInfo = await api.query.system.account(ADDRESS);

  // 解构余额信息
  const { nonce, data } = accountInfo;
  const { free, reserved, frozen } = data;

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

  // 断开连接
  await api.disconnect();
}

main().catch(console.error);

2)配置 RPC 节点

将:

INSERT_WS_ENDPOINT

替换为:

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

将:

INSERT_ADDRESS

替换为你要查询的钱包地址。

3)运行脚本

node query-balance.js

4)示例输出

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)

现在我们读取 Assets Pallet 的存储,查询:

Polkadot Hub 上的 USDT(资产 ID:1984)

1)创建脚本

创建:

query-asset.js

代码:

import { ApiPromise, WsProvider } from '@polkadot/api';

const ASSET_HUB_RPC = 'INSERT_WS_ENDPOINT';

// USDT 资产 ID
const USDT_ASSET_ID = 1984;

// 查询地址
const ADDRESS = 'INSERT_ADDRESS';

async function main() {
  const wsProvider = new WsProvider(ASSET_HUB_RPC);
  const api = await ApiPromise.create({ provider: wsProvider });

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

  // 查询资产元数据
  const assetMetadata = await api.query.assets.metadata(USDT_ASSET_ID);

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

  // 查询资产详情
  const assetDetails = await api.query.assets.asset(USDT_ASSET_ID);

  if (assetDetails.isSome) {
    const details = assetDetails.unwrap();
    console.log('\nAsset Details:');
    console.log(`  Owner: ${details.owner.toString()}`);
    console.log(`  Supply: ${details.supply.toString()}`);
    console.log(`  Accounts: ${details.accounts.toString()}`);
    console.log(`  Min Balance: ${details.minBalance.toString()}`);
    console.log(`  Status: ${details.status.type}`);
  }

  // 查询账户资产余额
  console.log(`\nQuerying asset balance for: ${ADDRESS}`);
  const assetAccount = await api.query.assets.account(USDT_ASSET_ID, ADDRESS);

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

  await api.disconnect();
}

main().catch(console.error);

2)运行

node query-asset.js

3)示例输出

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

字段

含义

metadata

资产名称、符号、小数位

owner

资产管理员

supply

总发行量

accounts

持币地址数

minBalance

最小持仓

status

是否启用

account.balance

地址持仓

重要补充理解

你刚才做的,其实就是直接读取区块链的 Runtime Storage,而不是调用合约。

这与 EVM 世界差异非常大:

Ethereum

Polkadot

大多数数据在合约

大多数数据在 Runtime Storage

必须调用合约

可直接读取链存储

RPC 主要用于交易

RPC 同时用于数据查询

因此,Polkadot 是“可查询型链”,不是纯交易型链。

这也是为什么区块浏览器(Subscan、Polkadot.js Apps)能实时展示几乎所有链上数据 —— 本质上它们就是在做同样的存储查询。

下一步你可以做的:
    •    做一个余额查询网页
    •    写一个链上数据机器人
    •    做资产监控报警服务
    •    构建 DeFi 数据面板

这一步,其实就是 Web3 后端开发的真正起点。

阅读原文:https://docs.polkadot.com/chain-interactions/query-data/query-sdks/#__tabbed_1_2

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值