理解 Solana RPC
什么是 RPC
RPC(Remote Procedure Call)是客户端与 Solana 节点通信的接口。无论是查询账户余额、发送交易还是订阅事件,都需要通过 RPC 进行。Solana 提供了 HTTP 和 WebSocket 两种 RPC 接口。
作为开发者,你会频繁使用 RPC 来部署程序、测试功能、查询链上状态。理解 RPC 的工作方式,是高效开发的基础。
承诺级别(Commitment)
Solana 使用承诺级别来描述数据的确定性程度。这是一个关键概念——你读取的数据可能还没有最终确认,存在被回滚的风险。
三种承诺级别从高到低排列:
-
finalized (最终确认):
- 区块已被集群超级多数(2/3+)确认并达到最大锁定状态。
- 特点:不可能被回滚。
- 场景:大额资金转账确认、交易所充值入账。
-
confirmed (已确认):
- 区块已被集群超级多数投票确认,但尚未达到最大锁定。
- 特点:回滚概率极低但理论上存在。
- 场景:大多数应用场景,在速度和安全性之间取得平衡。
-
processed (已处理):
- 当前连接的节点已处理该区块,但可能还未被集群投票。
- 特点:速度最快(几百毫秒),但风险最高(如果分叉被丢弃,数据会回滚)。
- 场景:对最新数据有强需求且能容忍偶发回滚的场景(如即时通讯、游戏状态更新)。
如果不指定承诺级别,默认通常使用 finalized。对于需要连续处理多个相互依赖交易的场景(例如发送交易后立即查询状态),建议使用 confirmed。
RPC 响应结构
大多数 RPC 方法返回的响应包含两部分:
- context:包含一个
slot字段,表示数据是在哪个区块高度查询的。 - value:实际返回的数据。
这种设计让你知道数据的「新鲜度」。在高频更新的场景下,你可以根据 slot 判断数据是否过时。
json{ "context": { "slot": 123456789 }, "value": { "data": ["...", "base64"], "executable": false, "lamports": 1000000, "owner": "11111111111111111111111111111111", "rentEpoch": 290 } }
数据编码与解析
账户数据默认以 Base64 编码返回。
如果你请求 encoding: "jsonParsed",节点会尝试将数据解析为 JSON 格式。目前支持解析的程序包括:SPL Token、SPL Token 2022、Stake、Vote 等系统程序。
对于自定义程序的数据,你需要自己实现解析逻辑。通常的做法是定义数据结构 (Struct),然后使用 Borsh 等序列化库在客户端进行二进制解码。
过滤条件 (Filters)
查询账户列表 (getProgramAccounts) 时,如果不加限制,可能会拉取数百万个账户,导致超时或内存溢出。
使用过滤条件缩小范围:
- memcmp (Memory Compare):在账户数据的指定偏移量处匹配字节序列。常用于查找特定类型的账户(如“查找所有 owner 是 Alice 的 Token 账户”)。
- dataSize:匹配指定长度的账户数据。常用于筛选特定结构的账户。
示例:查找所有 USDC 的 Token 账户
- dataSize: 165 (Token 账户固定大小)
- memcmp: offset = 0, bytes = USDC_MINT_ADDRESS
合理使用过滤条件可以显著减少网络传输量和处理时间。