pump.fun 狙击机器人:为什么先发现的那个还是输了

大多数狙击机器人在优化检测,却输在提交。从上新出现到你的买单落块,slot 到底花在哪了,以及该先修什么。

BoltTx Team··14 min read
solana狙击机器人pump-fun交易上链priority-fee交易机器人

所有狙击机器人的教程都在讲检测。WebSocket 还是轮询、Geyser 流、怎么把创建事件的解析再快三毫秒。

然后你照着搭了一个,看着它把上新检测得漂漂亮亮,而成交时价格已经翻了三倍。

检测从来就不是瓶颈。

slot 到底花在哪了

一次狙击有五个阶段。只有其中一个被反复写:

① 上新出现在链上
② 你的机器人检测到       ← 所有人都在优化这一步
③ 你的机器人决定买入
④ 构造并签名
⑤ 你的交易落块           ← ★钱是在这里输掉的★

第 2 到第 4 步是你自己的代码,而且很快 —— 解析一行日志、构造一个指令,都是亚毫秒级的事。第 5 步是网络问题,而在上新的那一刻,它慢得跟其它几步不在一个量级。

★如果你把检测快了几毫秒,却仍然晚三个 slot 落块,等于什么都没省。★ 一个 slot 的时长远大于这点差距。你优化的是一个舍入误差。

检测已经跑通、想修最后这一步?免费领个 BoltTx key 改一行配置。这篇剩下的部分讲的是为什么那一步占了大头。

上新为什么是最难的场景

拥堵不是随机的,它恰好聚集在你想交易的那些事件上。

一次上新意味着所有盯着那个程序的狙击者在同一秒内提交。区块空间被抢、所有人要写的那些账户上 priority fee 飙升、上链窗口收窄。

这造成一个特定的陷阱:★你的机器人在测试时完美运行,在生产环境失败★ —— 因为测试发生在网络清闲时,那时候每条提交路径表现都一样。差别只在高负载下才显现。

决定你能不能成交的四件事

一、priority fee 要算,不要写死

一个你上个月设的常数,大部分时候是浪费、上新时是不够。通常两者兼有。

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

// 费用是按账户竞争的,不是全局的。要传你这笔交易会写入的账户 ——
// 上新时,所有人都在写同一个 bonding curve 账户。
const recent = await connection.getRecentPrioritizationFees({
  lockedWritableAccounts: [bondingCurve, yourTokenAccount],
});
const fees = recent.map((r) => r.prioritizationFee).sort((a, b) => a - b);
const median = fees[Math.floor(fees.length / 2)] ?? 0;

instructions.unshift(
  ComputeBudgetProgram.setComputeUnitPrice({
    // 上新是竞争最激烈的场景。中位数只是下限。
    microLamports: Math.max(median * 3, 10_000),
  }),
  ComputeBudgetProgram.setComputeUnitLimit({ units: 120_000 }),
);

★compute unit limit 也要设。★ 不设的话会按一个远高于实际用量的默认值计费,而这恰好浪费在费用最贵的那些时刻。

二、blockhash 要在签名时才取

blockhash 有效期约 150 个区块、大约 60 秒。听起来很宽裕 —— 直到你在启动时取了一个然后一直复用。

// 错:上新触发时,这个 blockhash 已经很旧了。
const { blockhash } = await connection.getLatestBlockhash();
watchForLaunches((mint) => buildAndSend(mint, blockhash));

// 对:后台定时刷新,始终保持一个新鲜的。
let cached = await connection.getLatestBlockhash("confirmed");
setInterval(async () => {
  cached = await connection.getLatestBlockhash("confirmed");
}, 5_000);

定时刷新而不是用时才取,还顺手从热路径上去掉了一次网络往返。★在"检测到"和"提交"之间,你付不起一次网络调用。★

三、重试到过期,不是只发一次

上新时单次提交就是掷硬币。

const raw = tx.serialize();
const sig = await connection.sendRawTransaction(raw, {
  skipPreflight: true,
  maxRetries: 0, // 重试由我们自己驱动
});

while (await connection.getBlockHeight("confirmed") <= lastValidBlockHeight) {
  const { value } = await connection.getSignatureStatuses([sig]);
  if (value[0]) break; // 已上链,看 .err 判断结果

  await connection.sendRawTransaction(raw, {
    skipPreflight: true,
    maxRetries: 0,
  });
  await new Promise((r) => setTimeout(r, 400));
}

重发相同字节是安全的 —— 签名一样,最多被收录一次。skipPreflight 在这里很关键,因为 preflight 要花一次往返,而且它模拟的是你不会落进去的那个 slot。

四、一条高负载下扛得住的提交路径

这是唯一没法在应用层代码里解决的,所以应该放在最后查 —— 先把前三个便宜的排除掉。

验证节点按转发方的质押权重来接收转发过来的交易。区块空间充裕时这完全看不见;被抢的时候,低质押路径恰好在你最不希望的时候被降级。

上链应该是什么水平

我们投递节点上的真实交易:中位确认 336 毫秒 —— 不到一个 slot。

两个 slot 是不到一秒。对一次上新来说,第 2 个 slot 的价格和第 6 个 slot 的价格,差别足以决定整笔交易。

★拥堵时那个数字会拉长★ —— 大部分交易不受影响,少数明显变慢。而狙击就活在这少数里,因为上新本身就是拥堵

该测的是什么

只看成交率会误导人。一个每次都以糟糕价格成交的机器人,看起来很健康。

log({
  mint,
  detectSlot,        // 你看到上新的 slot
  landSlot,          // 你的买单落块的 slot
  slotGap: landSlot - detectSlot,
  entryPrice,
  curvePriceAtDetect,
  gapBps: Math.round(((entryPrice - curvePriceAtDetect) / curvePriceAtDetect) * 10_000),
});

slotGap 告诉你执行是不是问题,gapBps 告诉你它的代价够不够大。★ 两个要分开看 —— 在 slotGap 很大的时候去优化检测,是把力气花在错误的阶段上。

说点实话

狙击竞争很激烈。看到这篇文章的所有人,对同样的上新拥有同样的公开信息,任何单一优化带来的优势都很小。

但有一点是真的:★大多数机器人在提交这一侧调得很差★ —— 写死的费用、只提交一次、过期的 blockhash、通用端点。把这些修好能让你领先大多数人,而这和"让你排第一"是两个不同的说法。

如果你现在的机器人稳定在检测后两个 slot 内落块、还是在亏钱,那问题在策略或选币,不在基础设施。先测,别假设。

BoltTx 在这里的位置

我们做第 5 步。不做检测,不做上新 feed,不做索引。

提交走我们自建的四区域投递节点,带 SWQoS 路由,不暴露公共 mempool —— 交易在落块之前,传输途中观察不到。你在本地签名,我们不托管资金、不代签、不修改交易内容。

tip 带在交易里,从你自己的钱包链上支付。交易 revert 的话 tip 跟着一起 revert —— 这是 Solana 原子交易的机制决定的。只有到达链上的交易才计费。

免费领 API key,没有月费:

// 选离你机器人最近的区域
const connection = new Connection("https://la.bolttx.io/?api-key=YOUR_KEY");

然后拿几次真实上新记录 slotGap,做个对比。

常见问题

我的 pump.fun 狙击机器人能检测到上新,为什么总是成交不了? 检测和执行是两个阶段。如果你能瞬间看到上新、却晚三个以上 slot 落块,损失在提交侧:priority fee、blockhash 新鲜度、重试行为、或者拥堵下的路由。

Solana 狙击机器人要多快? 快到能在检测后一两个 slot 内落块。检测速度没大多数教程说的那么重要 —— 解析日志省下的一毫秒,在你的交易多花一个 slot 落块面前毫无意义。

狙击机器人的 priority fee 该设多少?getRecentPrioritizationFees 按你会写入的账户去查,然后为竞争场景往上乘。上新是全网最激烈的时刻,所以近期中位数是下限而不是目标

为什么我的机器人测试时正常、真上新就挂? 测试时网络清闲,所有提交路径表现一样。上新造成拥堵,而拥堵时费用、重试行为、路由会同时开始起作用。

狙击该开 skipPreflight 吗? 该开。preflight 要花一次网络往返,而且模拟的是当前 slot —— 那不是你会落进去的那个。真正有用的模拟放在开发阶段,结果用 getSignatureStatuses 拿。

怎么在不增加延迟的前提下保持 blockhash 新鲜? 后台定时刷新,而不是用时才取。狙击那一刻去取会给热路径加一次往返,而启动时缓存的那个,等你要用时已经接近过期。

pump.fun 买入该设多少 compute unit limit? 开发阶段模拟一次拿到真实消耗,然后设一个略高的值。用默认值意味着按一个高得多的数字计费,而这恰好浪费在费用飙升的时刻。

反复重发同一笔狙击交易安全吗? 安全。相同的签名字节产生相同签名,Solana 对同一个签名最多收录一次。持续重发到 blockhash 过期是生产环境的标准做法。

落后几个 slot 就太晚了? 取决于曲线动得多快,但在一次活跃上新中,超过三四个 slot 通常你买到的价格已经把利润空间抹掉了。把检测时和成交时的价格都记下来,就能看出自己的阈值在哪。

狙击一定要用 Geyser 或专用流吗? 它对检测有帮助,但前提是提交那一侧已经调紧了。为最快的检测付费、却通过通用端点提交,是把钱花在错误的阶段上。

我的狙击交易为什么总报滑点错误? 报价到收录之间曲线动了。放宽容忍度只会让你成交得更差,而不是解决成因。如果这个情况反复出现,slot 差才是真正的变量

不用付费 RPC 能跑狙击机器人吗? 小规模做检测有时可以。但上新时提交,共享的公共端点是最糟的情况 —— 因为在同一时刻,它正被所有其他人挤满。

狙击和抢跑有什么区别? 狙击是对一个已经上链的上新事件行动,用的是公开信息。抢跑是在一笔待确认交易被收录之前、基于对它的知情去行动。Solana 没有公共 mempool,所以后者在这里不像别的链上那样可行。

狙击机器人需要检查曲线有没有毕业吗? 需要,而且每笔买入前都要查。曲线一旦完成,交易转到 AMM 池,bonding curve 指令会失败。只在启动时查一次的机器人,会反复发出注定失败的指令。

怎么判断问题在基础设施还是在策略? 把 slot 差和入场价差分开记录。稳定在两个 slot 内落块却还在亏钱,指向选币或策略;slot 差很大,指向执行。

延伸阅读

返回博客列表