Solana JSON-RPC 方法参考:每个做什么、什么时候用

Solana JSON-RPC 方法速查:getAccountInfo、getTokenAccountBalance、getSignaturesForAddress 等各返回什么、哪些是只读、以及各自的限流开销。

BoltTx Team··9 min read
solanajson-rpcrpc-methodsapi参考

Solana JSON-RPC API 有几十个方法。大多数文档全列、不分主次。实践里,~10 个方法覆盖 95% 生产代码做的事。知道用哪个、怎么用好,比记完整面更有用。

这是你实际会用的 JSON-RPC 方法参考、每个带生产模式。

高频方法

生产代码反复调用的方法。

getAccountInfo

读单个账户状态。

const account = await connection.getAccountInfo(pubkey, "confirmed");

什么时候用:你需要一个账户的数据。

性能提示:

getMultipleAccountsInfo

一次调用读多个账户。

const accounts = await connection.getMultipleAccountsInfo(
  [key1, key2, key3],
  "confirmed"
);

什么时候用:要 2 个以上账户。永远偏好这个、不要循环 getAccountInfo

限制:每次调用 ~100 账户。批量更大集合。

getProgramAccounts

读程序拥有的所有账户。

const accounts = await connection.getProgramAccounts(programId, {
  filters: [
    { dataSize: 165 },
    { memcmp: { offset: 0, bytes: ownerKey.toBase58() } },
  ],
});

什么时候用:枚举匹配具体条件的账户。

永远用 filter。 不带 filter 会拉几 MB 数据。

一些 RPC 服务商出于成本理由限 getProgramAccounts。查你服务商策略。

getLatestBlockhash

拿最近 blockhash 给交易签名用。

const { blockhash, lastValidBlockHeight } = await connection.getLatestBlockhash("confirmed");

什么时候用:你要构建签名交易。

大多数情况用 "confirmed" commitment。别缓存;每笔交易拿新的。

sendTransaction / sendRawTransaction

提交签名交易。

const signature = await connection.sendTransaction(tx, signers, {
  skipPreflight: true,
  maxRetries: 0,
});

// 或预序列化:
const signature = await connection.sendRawTransaction(tx.serialize(), {
  skipPreflight: true,
  maxRetries: 0,
});

什么时候用:提交交易给打包。

生产模式:skipPreflight: true, maxRetries: 0。看 sendTransaction 最佳实践

confirmTransaction

等交易上链。

const result = await connection.confirmTransaction(
  { signature, blockhash, lastValidBlockHeight },
  "confirmed"
);

if (result.value.err) {
  // 交易执行期间失败
}

什么时候用:发送后,你要知道是不是上链了。

新的"签名带 blockhash"形式比老的"只签名"形式更可靠。

simulateTransaction

不提交跑一遍交易。

const sim = await connection.simulateTransaction(tx);
console.log("用 CU:", sim.value.unitsConsumed);
console.log("日志:", sim.value.logs);

什么时候用:开发期测试、profile CU 用量、debug。

生产里偏好 skipPreflight: true 跳模拟。模拟只给诊断。

getBalance

拿钱包 SOL 余额。

const balance = await connection.getBalance(pubkey, "confirmed");
console.log(balance);  // Lamports

什么时候用:检查钱包资金、给用户显示余额。

getTokenAccountBalance

拿 SPL 代币账户余额。

const balance = await connection.getTokenAccountBalance(tokenAccountKey, "confirmed");
console.log(balance.value.uiAmount);

什么时候用:检查代币持仓。

要查钱包持有的所有代币,用 getTokenAccountsByOwner

getSignaturesForAddress

拿地址最近的交易签名。

const sigs = await connection.getSignaturesForAddress(pubkey, { limit: 100 });

什么时候用:搭交易历史视图、监控活动。

生产级索引,专门索引方案比这方法好。

getTransaction

取具体交易详情。

const tx = await connection.getTransaction(signature, {
  commitment: "confirmed",
  maxSupportedTransactionVersion: 0,
});

什么时候用:查具体交易结果、debug。

maxSupportedTransactionVersion: 0 给版本化交易(大多数现代交易)需要。

订阅方法(WebSocket)

要实时更新而不是轮询。

onAccountChange

账户状态变化时被通知。

const subId = connection.onAccountChange(
  pubkey,
  (accountInfo, context) => {
    handleChange(accountInfo, context.slot);
  },
  "confirmed"
);

// 清理:
await connection.removeAccountChangeListener(subId);

onLogs

被通知程序日志发出。

const subId = connection.onLogs(
  programId,
  (logs, context) => {
    if (logs.err === null) {
      // 解析事件
    }
  },
  "confirmed"
);

onSignature

具体交易确认时被通知。

const subId = connection.onSignature(
  signature,
  (result, context) => {
    if (result.err === null) {
      // 已确认
    }
  },
  "confirmed"
);

反应式应用用这些替代轮询。

不那么常见但有用的方法

getRecentPrioritizationFees

拿最近 priority fee 数据,给 tip 策略用。

const fees = await connection.getRecentPrioritizationFees();
// 最近 slot 的 slot/fee 对数组

什么时候用:实现动态 priority fee 策略。

getSlot

当前 slot 号。

const slot = await connection.getSlot("processed");

什么时候用:定时决策、新鲜度检查、健康监控。

getEpochInfo

当前 epoch 状态。

const epoch = await connection.getEpochInfo("confirmed");

什么时候用:监控 epoch 边界、staking 相关逻辑。

getTokenAccountsByOwner

钱包拥有的所有代币账户。

const accounts = await connection.getTokenAccountsByOwner(
  ownerKey,
  { programId: TOKEN_PROGRAM_ID }
);

什么时候用:钱包 UI 显示所有代币、组合分析。

getInflationRate

当前通胀率。

const rate = await connection.getInflationRate();

什么时候用:staking 计算、validator 经济学。

生产里避免的方法

一些方法值得避免高频用:

不带 filter 的 getProgramAccounts 拉所有的;贵。

getBlock 返完整块数据;大响应。只在你要块级详情时用。

getConfirmedTransaction(废弃)。getTransaction 替代。

getRecentBlockhash(废弃)。getLatestBlockhash 替代。

Commitment 等级

大多数读方法接受三个 commitment 等级:

"processed" 最新可用状态。能被短分叉 reorg。最快。

"confirmed" 三分之二的 validator 已投票。实际上稳定,适合做默认。

"finalized" 完全终结。最慢但不可反驳。

大多数生产代码 "confirmed" 对。"processed" 只在延迟重要且能处理 reorg 时用。"finalized" 给高价值不可撤销决定。

常见模式

批量读: 永远用 getMultipleAccountsInfo 而不是循环 getAccountInfo

过滤查询: getProgramAccounts 永远用 filter。

订阅胜过轮询: 反应式 app,订阅在性能和新鲜度上都赢轮询。

发送后确认: 永远确认你发的交易。别信签名返回意味着上链。

缓存变化慢的数据: 代币元数据、程序所有权等。激进缓存。

这周可以做什么

审你的 RPC 用法:

  1. 数你方法调用。 你最用什么方法?
  2. 审批量读。 该用 getMultipleAccountsInfo 时用了吗?
  3. 审 filter 用法。 getProgramAccounts 调用永远带 filter?
  4. 审订阅 vs 轮询。 反应式用例,偏好订阅。
  5. 审 commitment 等级。 每个用例用对的吗?
  6. Profile 每方法延迟。 一些方法重;高频在重方法上是问题。

试一下 BoltTx

具体到 sendTransaction:

import { Connection } from "@solana/web3.js";

const connection = new Connection(
  "https://bolttx.io/?api-key=YOUR_API_KEY",
  "processed"
);

const signature = await connection.sendTransaction(tx, signers, {
  skipPreflight: true,
  maxRetries: 0,
});

免费档注册。读流量配你认为合适的任何读服务商。

常见问题

规范参考在哪? Solana 官方 JSON-RPC API 文档。这篇覆盖实际用的子集。

RPC 方法跨服务商标准化吗? 方法名和参数标准。行为和限流看服务商变。

能在一个 HTTP 请求里批多个 JSON-RPC 调用吗? JSON-RPC 2.0 协议层支持批量;服务商支持参差。大多数情况批量没显著加速。

每方法延迟成本是什么? 变化。读典型几十到几百毫秒;写有额外确认延迟。

该用废弃的方法名吗? 不。可能未来版本停工作。用当前名字。

延伸阅读

返回博客列表