原文作者: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/
471

被折叠的 条评论
为什么被折叠?



