新消息:Helius 收购 Light Protocol
Solana 拥堵:如何以最佳方式发送 Solana 交易
博客/基础知识

Solana 拥堵:如何以最佳方式发送 Solana 交易

集成工程师X 上的 Het DagliLinkedIn 上的 Het Dagli
阅读需 5 分钟

简介

“交易模拟失败:找不到区块哈希。”“交易发送失败。”这些错误消息已经屡见不鲜。网络拥堵让最基本的交易也变成了碰运气。但你不必再承受这些问题。

本指南将介绍一些简单策略,帮助你有效应对高流量时段,确保交易成功上链。我们将全面讲解如何处理网络拥堵,包括优先费、计算单元优化,以及 Helius 确保交易始终上链的独家秘诀。

本指南将介绍:

  • 使用序列化交易设置优先费
  • 使用账户密钥设置优先费
  • 高级优先费策略
  • 交易优化技术
  • 利用质押端点保证送达

优先费

优先费是一种竞价机制,可让你向验证者表明交易的重要性。这些费用以每个计算单元对应的 micro-lamports 计价,并由交易交互的具体账户决定,从而为每个账户形成独立的费用市场。根据账户的拥堵情况合理设置费用,可以显著提高交易被纳入下一个区块的概率。

接下来,我们将介绍如何通过不同方式使用 Helius 的 Priority Fee API 正确设置优先费:

序列化交易

设置优先费最直接的方法是使用序列化交易。序列化交易是交易的二进制表示形式,它会被转换为可通过网络传输的线路格式缓冲区。

  1. 序列化交易并将其传给 API:
代码
const serializedTx = transaction.serialize();

const response = await fetch(heliusEndpoint, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: 'helius-example',
    method: 'getPriorityFeeEstimate',
    params: [{
      transaction: serializedTx,
      options: { recommended: true }
    }]
  }),
});

const { result } = await response.json();
const priorityFee = result.priorityFeeEstimate;
  1. 将建议费用添加到交易中——指令顺序不影响结果:
代码
transaction.add(
  ComputeBudgetProgram.setComputeUnitPrice({
    microLamports: priorityFee
  })
);

账户密钥

另一种方法是向 Priority Fee API 提供交易涉及的账户密钥列表:‍

  1. 从交易中提取账户密钥:
代码
const transaction = new Transaction();

// Add your instructions to the transaction

// Extract all account keys from the transaction
const accountKeys = transaction.compileMessage().accountKeys;

// Convert PublicKeys to base58 strings
const publicKeys = accountKeys.map(key => key.toBase58());
  1. 将账户密钥传给 Priority Fee API:
代码
const response = await fetch(heliusEndpoint, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: 'helius-example',
    method: 'getPriorityFeeEstimate',
    params: [{
      accountKeys: publicKeys,
      options: { recommended: true }
    }]
  }),
});

const { result } = await response.json();
const priorityFee = result.priorityFeeEstimate;
  1. 将建议费用添加到交易中:
代码
transaction.add(
  ComputeBudgetProgram.setComputeUnitPrice({
    microLamports: priorityFee
  })
);

虽然两种方法都有效,但更推荐使用序列化交易。使用账户密钥时,需要手动跟踪并加入所有相关账户。如果遗漏任何账户,就可能导致费用估算不准确。 

序列化交易方法会自动加入所有必要账户,并根据完整的交易上下文提供更准确的费用估算,从而消除这种风险。

高级优先费策略

在大多数场景中,使用序列化交易并设置建议的优先费就足够了。但如果需要更精细的控制,Priority Fee API 还允许你请求不同优先级别的估算,并启用空槽位评估。

优先级别

以下示例展示了如何请求所有优先费级别:

代码
const response = await fetch(heliusEndpoint, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: 'helius-example',
    method: 'getPriorityFeeEstimate',
    params: [{
      transaction: serializedTx,
      options: {
        includeAllPriorityFeeLevels: true
      }
    }]
  }),
});

const { result } = await response.json();
console.log(result.priorityFeeLevels);

这将返回一个包含不同优先级别的对象:

代码
{
  "priorityFeeLevels": {
    "min": 10000.0,
    "low": 10000.0,
    "medium": 10000.0,
    "high": 100000.0,
    "veryHigh": 5483924.800000011,
    "unsafeMax": 8698904817.0
  }
}

这些优先级别对应近期交易费用的不同百分位数:

  • min:第 0 百分位
  • low:第 25 百分位
  • medium:第 50 百分位
  • high:第 75 百分位
  • veryHigh:第 95 百分位
  • unsafeMax:第 100 百分位(请谨慎使用)

要进一步提高交易上链率,可以考虑使用 high 或 very high 优先级别。不过,使用更高优先级别时要格外谨慎,尤其是 veryHigh 和 unsafeMax,因为它们可能会显著增加交易成本。‍

空槽位评估

Priority Fee API 最近的一项更新可通过考虑空槽位,更智能地估算费用。当区块中没有与特定账户相关的交易时,你可以配置 API,将这些槽位视为费用为零,从而在网络活动较少时提供更准确的估算:

代码
const response = await fetch(heliusEndpoint, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: 'helius-example',
    method: 'getPriorityFeeEstimate',
    params: [{
      transaction: serializedTx,
      options: {
        recommended: true,
        evaluateEmptySlotAsZero: true
      }
    }]
  }),
});

启用 evaluateEmptySlotAsZero 后,API 会:

  • 识别不包含你的账户相关交易的区块
  • 将这些空槽位计为零费用
  • 在拥堵程度较低时下调估算费用
  • 避免在网络活动较少时支付过高费用

交易优化策略

除了优先费之外,交易优化还涉及多个关键部分。它们共同发挥作用,可以提高交易上链率:

计算单元管理

  1. 使用 Helius SDK 获取交易的最佳计算单元数:‍
代码
const response = await helius.rpc.getComputeUnits({
  transaction: serializedTransaction
});

const computeUnits = response.computeUnits;
  1. 将计算单元限制添加到交易中:
代码
transaction.add(
  ComputeBudgetProgram.setComputeUnitLimit({
    units: computeUnits
  })
);

承诺级别

‍对于大多数应用,使用 processed 承诺级别可以实现最佳平衡。它能够:

  • 提供最快的确认时间
  • 为大多数使用场景提供足够的安全性
  • 降低区块哈希过期的风险
  • 最大限度减少拥堵期间被丢弃的交易

发送和确认交易时,请始终使用相同的承诺级别,确保应用行为一致。

RPC 配置

将 maxRetries 设为 0,并实现自己的重试逻辑,以便更好地控制交易重新提交。使用 skipPreflight: true 可降低延迟。这在严重拥堵期间尤其有用:

代码
const signature = await connection.sendTransaction(transaction, {
  maxRetries: 0,
  skipPreflight: true
});

使用质押端点

Helius 质押端点可直接提供有保证的质押连接访问,无需手动优化优先费:

代码
const connection = new Connection(
  'https://staked.helius-rpc.com?api-key=YOUR_API_KEY'
);

// Transaction will be processed with optimal priority
const signature = await connection.sendTransaction(transaction);

质押端点能够:

  • 提供有保证的质押带宽
  • 减少拥堵期间的交易失败
  • 通过专用基础设施更快地传播交易

总结

要让交易在 Solana 上成功上链,合理使用优先费至关重要,网络拥堵期间尤其如此。借助 Helius Priority Fee API 并实施本文介绍的策略,你可以在平衡成本的同时显著提高交易成功率。持续关注网络动态并及时调整策略,才能获得最佳效果。

感谢你阅读到这里!希望本指南能帮助你了解如何优化 Solana 交易。欢迎订阅我们的新闻简报,这样你就不会错过 Solana 的任何最新动态。 

准备好深入探索了吗?

立即阅读 Helius 博客上的最新文章,继续你的 Solana 之旅。

订阅 Helius

及时了解 Solana 开发的最新动态,并在我们发布新内容时收到更新

放大图片