Solana交易过期后如何安全重签? 图 1
Solana交易过期后如何安全重签? · 图 1

Solana签名覆盖整条Message,其中包含recent blockhash。这个哈希既帮助防止交易无限重放,也给交易设置有效窗口。用户签名后若长时间不发送,验证者会把消息视为过期,即使签名本身完全正确。

不要用固定分钟数判断过期

getLatestBlockhash返回blockhash和lastValidBlockHeight。客户端应持续读取当前block height,与lastValidBlockHeight比较;slot可能跳过,墙钟时间也受网络状况影响,不能用“签名后90秒”替代协议字段。

安全确认状态机

已发送,未到有效高度

重复广播同一已签名交易通常不会造成两次不同交易,因为签名相同。可以向多个健康RPC重发原字节,并查询signature status。此时不要换blockhash重新签名。

RPC超时,但链上状态未知

超时只说明客户端没收到结果。继续查询签名,并检查业务状态,例如目标余额或程序事件。若立即生成新交易,原交易和新交易可能都在不同时间成功。

已超过lastValidBlockHeight

确认原签名未落链后,重新读取最新blockhash,重新构造Message并让所有签名者重新签名。新Message会产生新签名,应用要把它与原业务请求关联,同时阻止重复业务执行。

错误含义下一步
Blockhash not found节点不知道或不接受该哈希检查节点是否落后及哈希有效性
transaction expired已超过有效高度查询旧签名后再重签
signature not found可能未广播或节点视图不同换健康节点继续查
processed未confirmed已有执行迹象但稳定性不足不要重签,继续确认

节点落后会制造假象

从较新的节点取得blockhash,却向明显落后的节点发送,后者可能尚未见过该哈希;反过来,从落后节点取得的哈希可能在领导者看来已经太旧。获取、发送和确认最好使用健康且视图接近的RPC,并比较它们的slot高度。

业务层还要防重

链上blockhash只限制同一Message。应用重新构造后是另一笔交易,因此支付、铸币或订单程序应有自己的request id、nonce或幂等账户。多签与离线签名流程若预计等待很久,应考虑Durable Nonce,而不是不断刷新recent blockhash。

重签前先判断旧交易是否仍可能落地

lastValidBlockHeight用于判断recent blockhash的有效窗口,但RPC节点可能落后或位于不同分叉。客户端应使用与发送端一致且健康的节点查询当前block height和签名状态;仅因本地超时就重签,可能让旧交易与新交易都被执行。

对于转账等不可重复业务,可在程序层加入唯一业务编号、状态账户或一次性nonce,使第二次执行安全失败。Durable Nonce适合需要离线签名或更长提交窗口的场景,但必须在交易中推进nonce,并处理nonce账户权限;它不是简单延长普通blockhash。

slot与block height区别见Solana时间单位,模拟和正式发送见simulateTransaction,离线签名可参考Solana Durable Nonce