原文作者:PaperMoon团队
一、前言(Introduction)
在基于 Polkadot SDK(Substrate) 构建的区块链中,所有核心数据都保存在链上的 状态存储(On-chain State) 中。
这些状态数据以 Key-Value(键值对数据库) 的形式存在,任何外部应用程序都可以通过 RPC 接口进行查询。
链上状态通常包括:
• 账户余额(Balance)
• 资产信息(Assets)
• 治理提案(Governance Proposals)
• Runtime 管理的任意数据
也就是说:区块链不仅仅是“转账系统”,本质上是一个可被程序读取的去中心化数据库。
二、可用于查询链上状态的 SDK
Polkadot 提供了多语言 SDK 来访问链上存储。本指南涉及的 SDK 包括:
| SDK | 语言 | 特点 |
|---|---|---|
| Polkadot API (PAPI) | TypeScript | 新一代类型安全 API |
| Polkadot.js API | JavaScript | 功能最完整(维护模式) |
| Dedot | TypeScript | 轻量高性能 |
| Python Substrate Interface | Python | 最适合脚本与数据分析 |
| Subxt | Rust | 编译期类型安全 |
本文将重点使用:Python Substrate-Interface 做自动化脚本与数据抓取。
三、实验目标
我们将完成两个实际开发中最常见的链上查询:
1. 查询账户 DOT 余额(System.Account)
2. 查询 USDT 资产信息与余额(Assets Pallet)
查询目标链:Polkadot Asset Hub
四、环境准备(Prerequisites)
1)基础环境
要求:
• Python ≥ 3.8
• pip 包管理器
2)创建虚拟环境
mkdir psi-query-example && cd psi-query-example && \
python3 -m venv venv && source venv/bin/activate
说明:
• venv 是 Python 虚拟环境
• 避免污染本机 Python 依赖
• 区块链开发强烈建议使用
3)安装依赖库
pip install substrate-interface
Python 官方常用的 Substrate 链交互接口库。
五、查询账户余额(System.Account)
Polkadot Runtime 中有一个核心模块:System Pallet
它维护了每个账户的账户信息(AccountInfo),包括:
| 字段 | 含义 |
|---|---|
| nonce | 交易序号(防重放) |
| free | 可用余额 |
| reserved | 保留余额 |
| frozen | 冻结余额 |
这些信息存储在:System.Account storage
编写查询脚本
创建文件:
query_balance.py
from substrateinterface import SubstrateInterface
ASSET_HUB_RPC = "INSERT_WS_ENDPOINT"
# 要查询的账户地址
ADDRESS = "INSERT_ADDRESS"
def main():
# 连接 Polkadot Asset Hub
substrate = SubstrateInterface(url=ASSET_HUB_RPC)
print("Connected to Polkadot Hub")
print(f"Querying balance for: {ADDRESS}\n")
# 查询 System.Account 存储
account_info = substrate.query(
module="System",
storage_function="Account",
params=[ADDRESS],
)
# 解析余额信息
nonce = account_info.value["nonce"]
data = account_info.value["data"]
free = data["free"]
reserved = data["reserved"]
frozen = data["frozen"]
print("Account Information:")
print(f" Nonce: {nonce}")
print(f" Free Balance: {free}")
print(f" Reserved: {reserved}")
print(f" Frozen: {frozen}")
substrate.close()
if __name__ == "__main__":
main()
重要参数说明
| 参数 | 说明 |
|---|---|
| INSERT_WS_ENDPOINT | WebSocket RPC 节点 |
| INSERT_ADDRESS | 要查询的地址 |
可用 RPC 示例:
wss://polkadot-asset-hub-rpc.polkadot.io
运行脚本
python query_balance.py
示例输出:
Connected to Polkadot Hub
Querying balance for: 14E5...
Account Information:
Nonce: 0
Free Balance: 0
Reserved: 0
Frozen: 0
六、查询 USDT 资产信息(Assets Pallet)
在 Polkadot Asset Hub 中,USDT 不是 ERC-20,而是 Assets Pallet 管理的原生链上资产。
其存储位置:Assets pallet
USDT 的资产 ID:1984
查询内容
我们将读取三类数据:
1. 资产元数据(名称、精度、符号)
2. 资产总体信息(发行量、所有者)
3. 某账户的 USDT 余额
编写脚本
创建:
query_asset.py
from substrateinterface import SubstrateInterface
ASSET_HUB_RPC = "INSERT_WS_ENDPOINT"
# Polkadot Hub 上的 USDT
USDT_ASSET_ID = 1984
ADDRESS = "INSERT_ADDRESS"
def main():
substrate = SubstrateInterface(url=ASSET_HUB_RPC)
print("Connected to Polkadot Hub")
print(f"Querying asset ID: {USDT_ASSET_ID}\n")
# 查询资产元数据
asset_metadata = substrate.query(
module="Assets",
storage_function="Metadata",
params=[USDT_ASSET_ID],
)
if asset_metadata.value:
metadata = asset_metadata.value
print("Asset Metadata:")
print(f" Name: {metadata['name']}")
print(f" Symbol: {metadata['symbol']}")
print(f" Decimals: {metadata['decimals']}")
# 查询资产详细信息
asset_details = substrate.query(
module="Assets",
storage_function="Asset",
params=[USDT_ASSET_ID],
)
if asset_details.value:
details = asset_details.value
print("\nAsset Details:")
print(f" Owner: {details['owner']}")
print(f" Supply: {details['supply']}")
print(f" Accounts: {details['accounts']}")
print(f" Min Balance: {details['min_balance']}")
print(f" Status: {details['status']}")
# 查询账户资产余额
print(f"\nQuerying asset balance for: {ADDRESS}")
asset_account = substrate.query(
module="Assets",
storage_function="Account",
params=[USDT_ASSET_ID, ADDRESS],
)
if asset_account.value:
account = asset_account.value
print("\nAsset Account:")
print(f" Balance: {account['balance']}")
print(f" Status: {account['status']}")
else:
print("\nNo asset balance found for this account")
substrate.close()
if __name__ == "__main__":
main()
运行
python query_asset.py
Connected to Polkadot Hub
Querying asset ID: 1984
Asset Metadata:
Name: Tether USD
Symbol: USDT
Decimals: 6
Asset Details:
Owner: 5Gy6...
Supply: 77998622834581
Accounts: 13545
Min Balance: 10000
Status: Live
Querying asset balance for: 14E5...
No asset balance found for this account
七、链上查询流程图
链上状态读取流程:
1. 应用程序连接 RPC
2. SDK 构造 storage query
3. 节点读取 runtime storage
4. 返回 SCALE 编码数据
5. SDK 解码为结构化对象
6. 应用程序使用数据
你现在已经理解了 Polkadot 与以太坊的一个核心差异:
| Ethereum | Polkadot |
|---|---|
| 读取依赖合约 ABI | 直接读取 Runtime Storage |
| ERC20 存储在合约 | 资产存储在 Runtime Pallet |
| dApp 是链上入口 | Runtime 是链上系统 |
在 Polkadot 中,你可以像查询数据库一样查询区块链。
这也是 Substrate 被称为 “可编程区块链操作系统” 的原因。
阅读原文:https://docs.polkadot.com/chain-interactions/query-data/query-sdks/#__tabbed_1_4
142

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



