如何通过交易哈希(签名)确认Solana链上交易是否执行成功
后端校验Solana交易执行状态实现方案
你当前场景下不需要依赖已弃用的confirmTransaction,也不需要调用仅支持全流程发交易的sendAndConfirmTransaction——因为你已经拿到了钱包侧返回的交易哈希(签名),直接通过Solana Web3.js提供的链上状态查询接口即可完成校验,完全适配Phantom签名后后端验签的流程。
核心实现逻辑
校验的核心是判断交易是否达到finalized承诺级别:该级别代表交易已经被集群超过2/3的验证节点确认,不存在回滚可能,属于链上最终执行完成的状态。
具体实现步骤
初始化后端Solana连接实例
初始化时直接指定默认承诺级别为finalized,避免后续重复传参:const { Connection, clusterApiUrl } = require('@solana/web3.js'); // 主网连接示例,测试网替换为clusterApiUrl('testnet')即可 const connection = new Connection(clusterApiUrl('mainnet-beta'), { commitment: 'finalized' });编写交易校验方法
用稳定APIgetSignatureStatus查询交易状态,注意开启历史检索参数避免刚上链的交易漏查,同时补充交易详情校验防止假哈希攻击:/** * 校验交易哈希对应的链上交易是否执行成功 * @param {string} signature 前端返回的交易哈希 * @param {object} expectRule 业务预期校验规则 * @returns 校验结果 */ async function verifySolanaTransaction(signature, expectRule = {}) { // 查询交易状态 const signatureStatus = await connection.getSignatureStatus(signature, { searchTransactionHistory: true }); // 状态为空代表链上未检索到该交易 if (!signatureStatus?.value) { return { passed: false, msg: '交易不存在,可能哈希无效或尚未广播到集群' }; } const statusValue = signatureStatus.value; // 交易存在但执行报错 if (statusValue.err) { return { passed: false, msg: '链上交易执行失败', err: statusValue.err }; } // 交易未达到最终确认状态 if (statusValue.confirmationStatus !== 'finalized') { return { passed: false, msg: `交易尚未最终确认,当前状态:${statusValue.confirmationStatus}` }; } // 拉取完整交易详情做业务规则校验,防止伪造交易哈希 const txDetail = await connection.getTransaction(signature, { commitment: 'finalized', maxSupportedTransactionVersion: 0 // 兼容版本化交易 }); // 此处补充自定义业务校验逻辑,常规校验项包括: // 1. 校验交易blockTime在业务允许的时间窗口内,防止历史交易重放 // 2. 校验交易交互的程序ID、转账金额、接收地址和预期一致 // 3. 校验交易指令参数和生成交易时的参数完全匹配 if (expectRule.minBlockTime && txDetail.blockTime < expectRule.minBlockTime) { return { passed: false, msg: '交易已过期' }; } return { passed: true, msg: '交易已最终确认,执行成功', slot: statusValue.slot, blockTime: txDetail.blockTime, fee: txDetail.meta.fee }; }高实时性场景可选监听模式
如果不想轮询查询状态,可以用链上订阅接口,交易达到最终状态时会自动触发回调:connection.onSignature( '你的交易哈希', (res) => { // res为交易状态更新结果,判断逻辑和上述轮询逻辑一致 console.log('交易状态更新', res); }, 'finalized' );
注意避坑
- 不要在后端调用
sendAndConfirmTransaction:该方法的逻辑是「发送原始交易字节+轮询确认」,你的场景下交易已经由Phantom签名广播完成,后端拿不到原始交易字节,调用该方法必然报错。 - 不要省略交易详情校验:仅判断交易状态成功存在风险,攻击者可以随便拿一笔链上成功的无关交易哈希伪造请求,必须校验交易的参数、交互地址、时间窗口和业务预期一致。
- 旧版
confirmTransaction弃用不影响上述逻辑:旧方法被弃用的原因是内置轮询逻辑僵化、承诺级别判断不准确,上述用到的getSignatureStatus、getTransaction、onSignature都是官方长期维护的稳定API,不存在弃用风险。
内容的提问来源于stack exchange,提问作者raghav saraf
相关产品推荐
相关产品推荐

