大多数机器人的成本估算从基础手续费开始、也在那里结束,指出它很小,然后就没有然后了。接着钱包流失的速度,比交易结果能解释的快得多。
★基础手续费很少是最大的一项,却是大多数人唯一做了预算的一项。★
完整的图景
| 成本 | 什么时候发生 | 能否收回 |
|---|---|---|
| 基础手续费 | ★每一笔落块的交易★ | 不能 |
| 优先费 | 你附带了才有 | 不能 |
| 租金 | 创建账户时 | ★能,关闭时收回★ |
| ★失败的尝试★ | ★落块但 revert★ | ★不能★ |
| RPC / 基础设施 | 持续发生 | 不能 |
| 滑点与价格冲击 | 每一次成交 | 不能 |
★团队漏掉的那一行是"失败的尝试"。★ 一笔落块并 revert 的交易,消耗了基础手续费和你附带的优先费。它在链上什么都没改变,而它照样花了钱。
对一个在新盘上竞争的狙击机器人来说,revert 可能占所有尝试的很大一部分。这些失败的成本是一项真实的运营开支,不是异常情况。
把成本归因到结果
让其它一切变得可读的那个测量:
// ★每一次尝试都把成本记在结果上。★
costs.record({
outcome, // success | reverted | expired
baseFeeLamports: 5000,
priorityFeeLamports,
rentLamports: accountsCreated * rentExempt,
strategy,
});
由此得到三个"光看手续费总额给不了你"的数字:
每笔成功交易的成本。 总开销除以成功数,不是除以尝试数。★如果三次尝试成功一次,你真实的每笔成本大约是单笔手续费的三倍。★
浪费掉的开销。 所有花在 revert 上的钱。它在绝对值上升而成功数不动,说明上游有什么东西变了。
成本占利润的比例。 唯一能说明这个策略行不行的数字。
如果你的手续费开销上升是因为交易落不了块,免费领个 BoltTx key 改一行就能测测提交路径。
优先费是钱漏掉的地方
基础手续费是固定且很小的。优先费是你自己选的,而策略要么在那里帮你省钱,要么在那里让你花钱。
写死的手续费在两个方向上都错。 平静时定得太高,意味着在每一笔例行交易上多付;拥堵时定得太低,意味着输掉那些"重要到会被人争抢"的交易。
// ★争用是按账户的,不是全局的。★
const fees = await connection.getRecentPrioritizationFees({
lockedWritableAccounts: writableAccounts,
});
const sorted = fees.map((f) => f.prioritizationFee).sort((a, b) => a - b);
const median = sorted[Math.floor(sorted.length / 2)] ?? 0;
const fee = Math.min(
Math.max(median * 2, FLOOR),
CEILING, // ★设上界★
);
★这个上限不是可选的。★ 手续费尖峰期,没有上界的策略就是没有上界的开销 —— 而尖峰恰恰是你的机器人最活跃的时候。撞到上限应该是一次告警,不是一次默默的付款。
按这笔交易值多少钱来缩放费用。 给一个大机会和一次例行再平衡付同样的优先费,意味着在一边多付、在另一边少付。
计算上限也是一个手续费决策
这一条在你专门去找它之前是看不见的。
优先费的计费方式是 compute unit price × compute unit limit。而这个 limit 是你请求的量,不是你用掉的量。
// ★留着默认值,意味着按一个远高于真实用量的数字被计费。★
const sim = await connection.simulateTransaction(tx, {
replaceRecentBlockhash: true, sigVerify: false,
});
const limit = Math.ceil((sim.value.unitsConsumed ?? 200_000) * 1.2);
instructions.unshift(
ComputeBudgetProgram.setComputeUnitLimit({ units: limit }),
);
★一笔请求了远超所需计算量的交易,会为同样的结果按比例多付优先费。★ 按 simulateTransaction 报告的 unitsConsumed 设置 setComputeUnitLimit,是少数几个"降低成本但不降低竞争力"的改动之一 —— 而且它在手续费尖峰时最有用,因为那时候乘数最大。
租金是资产,不是费用
租金豁免的 lamport 是被锁住了,不是被花掉了。★账户关闭时它们会回来。★
这让"关闭账户"成为一个真实的回收机制:
// ★空的代币账户是可回收的资本。★
const accounts = await connection.getParsedTokenAccountsByOwner(
wallet.publicKey, { programId: TOKEN_PROGRAM_ID },
);
const empty = accounts.value.filter(
(a) => a.account.data.parsed.info.tokenAmount.uiAmount === 0,
);
// 对每一个调 createCloseAccountInstruction,批量执行。
一个交易很多代币的机器人会持续累积空的代币账户。每一个都锁着什么都不干的租金。 一个用 getParsedTokenAccountsByOwner 加 createCloseAccountInstruction 的定期任务能把它收回来,而且关闭账户可以便宜地批量做,因为每个只需要一条指令。
★在你的账里,把"锁住的租金"和"花掉的手续费"分开记。★ 把租金当成费用会低估你的资本,并掩盖掉其中一部分随时可以收回这件事。
基础设施对手续费
这两类成本的行为不同,把它们混在一起会导致糟糕的决策。
固定成本 —— 服务器、RPC 订阅、数据源 —— 不管你交易一次还是一万次,都是一样的。
可变成本 —— 手续费、租金、滑点 —— 随活动量增长。
★值得问的问题是:一笔固定成本在可变项上买到了什么。★ 一个更贵的、能提高你落块率的端点,减少的是浪费在 revert 和过期上的开销。 它划不划算是一道算术题 —— 而这道题大多数团队从没算过,因为这两类成本记在不同的地方。
每月固定成本
对比
(改之前浪费的开销) − (改之后浪费的开销)
+ 那些现在能落块的交易的价值
改前改后都要测,并且在同样的条件下测。 拿一个清闲的星期和一个繁忙的星期比,什么都说明不了。
规模化之后才出现的成本
那些在低量时可以忽略、高量时变得实质性的东西:
失败尝试的累积。 一天几笔时,revert 是噪音。几千笔时,它是一个预算科目。
账户创建。 每一个新代币都意味着一个代币账户。一个交易大量新代币的机器人在不停地创建账户。
RPC 超量。 按请求计费会随轮询频率增长,而确认轮询通常是最大的消耗方。
数据传输。 在繁忙程序上的流式订阅会搬运可观的流量,尤其是不加过滤的那些。
★这些全都要从真实样本估算,不要在表格里算。★ 让机器人跑一天,把所有东西都测一遍,然后外推 —— 意外出现在样本里,不会出现在估算里。
上链应该是什么水平
我们投递节点上的真实交易:中位确认 336 毫秒 —— 不到一个 slot。
★上链的可靠性是一个成本变量,不只是性能变量。★ 过期的交易必须重建并重发,而每一次重试都是又一次为"你本来就想要的结果"付费的机会。
BoltTx 在这里的位置
我们负责提交。不管你的手续费策略,不管你的策略。
提交走我们自建的四区域投递节点,带 SWQoS 路由,不暴露公共 mempool —— 交易在落块之前、传输途中观察不到。
你在本地签名。我们不托管资金、不代签、不修改交易内容。tip 带在交易里、从你自己的钱包链上支付,交易失败时跟着一起 revert —— 这是 Solana 原子交易的机制决定的。没有月费,只有到达链上的交易才计费 —— 这把我们的成本放在你模型里的可变项那一侧,而不是固定项那一侧。
const connection = new Connection("https://la.bolttx.io/?api-key=YOUR_KEY");
常见问题
跑一个 Solana 交易机器人要花多少钱? 基础手续费,加优先费,加租金,加失败的尝试,加基础设施。基础手续费很小,也是所有人唯一做了预算的一项,而失败的尝试和优先费通常才是大头。
Solana 上失败的交易要花钱吗? 如果它落块并 revert 了,要 —— 你为一次什么都没改变的执行付了基础手续费和优先费。如果它根本没落块,不产生手续费,但机会照样丢了。
Solana 机器人最大的成本是什么? 通常是优先费和失败的尝试,不是基础手续费。对创建大量代币账户的机器人来说租金能和它们相当,不过租金可以收回,手续费不能。
怎么降低 Solana 的优先费开销? 从你要写入的账户的近期活动推导费用而不是写死,按模拟结果设置计算上限,并给费用设上限、撞到时告警。
计算上限会影响我付多少钱吗? 会。优先费是"价格 × 上限",而上限是你请求的量、不是你用掉的量。 一个请求过高的上限,会为同样的结果按比例多付。
租金是费用还是资产? 资产。租金豁免的 lamport 是被锁住、并在账户关闭时归还的,所以要和花掉的手续费分开记,并跑一个清理任务从空账户里把它收回来。
每笔成功交易的成本怎么算? 包含 revert 和过期在内的总开销,除以成功数而不是尝试数。如果三次成功一次,你真实的每笔成本大约是单笔手续费的三倍。
该关闭空的代币账户吗? 该,定期关。每一个都锁着什么都不干的租金,而关闭每个账户只要一条指令,批量做很便宜。交易很多代币的机器人会持续累积这些账户。
怎么判断付费 RPC 值不值? 把固定成本和"浪费开销的减少 + 现在能落块的那些交易的价值"作比较,并在同样条件下测量。大多数团队从没算过,因为这两类成本记在不同的地方。
哪些成本只在规模化之后才出现? 失败尝试的累积、新代币带来的账户创建、确认轮询造成的 RPC 请求超量,以及流式订阅的数据传输。这些在低量时都可以忽略。
跑起来之前怎么估算机器人成本? 让它跑一天,对每一次尝试都把成本记在结果上,然后外推。表格估算会漏掉 revert 和账户创建 —— 而那通常正是意外所在。
上链可靠性会影响成本吗? 会。过期的交易必须重建并重发,而每一次重试都是又一次为你本来就想要的结果付费的机会。可靠性直接减少浪费的开销。
优先费该随交易规模缩放吗? 一般该。给一个大机会和一次例行再平衡付同样的费用,意味着在一边多付、在另一边少付 —— 而少付的那一边通常才是重要的那笔。
手续费上限设多少合理? 从你正在争抢的那些交易的价值推导出来,不是一个整数。撞到它应该触发告警,这样你知道行情极端,而不是在尖峰里默默付过去。
怎么按策略追踪成本? 给每一条成本记录打上产生它的策略标签。汇总数字会掩盖"某一个策略吃掉了大部分手续费预算、却只贡献了很少利润"。
滑点算成本吗? 该算。它不出现在手续费账里,但它降低每一次成交的实得价值 —— 对一个容忍度设得很宽的机器人来说,它可以轻松超过手续费。