Python中Solana交易的正确确认方法及区块高度异常问题咨询
Python中Solana交易的正确确认方法及区块高度异常问题咨询
看起来你在Solana交易确认的逻辑上踩了个关键小坑,这大概率就是导致等待超过90秒的核心原因。先帮你梳理问题所在,再给出调整后的可靠方案:
核心问题分析
你当前获取last_valid_block_height的方式完全错误:
- 你把
get_latest_blockhash返回结果里context的slot(当前区块槽位)当成了last_valid_block_height,但这两个值完全不是一回事! get_latest_blockhash的正确返回结果中,last_valid_block_height是该区块哈希的有效截止槽位,是单独的字段,和context.slot没有关联。用错这个值会导致交易确认时判断的是错误的截止条件,自然会出现无意义的长时间等待。
另外,手动管理确认逻辑容易出错,推荐用Solana SDK提供的更自动化的确认方法。下面是修正后的完整代码片段:
# Step 4: Decode and sign the transaction app.logger.info("Decoding and signing the transaction...") raw_transaction = VersionedTransaction.from_bytes(base64.b64decode(swap_transaction)) signature = private_key.sign_message(to_bytes_versioned(raw_transaction.message)) # Sign the serialized message signed_txn = VersionedTransaction.populate(raw_transaction.message, [signature]) # Populate the transaction app.logger.info("Transaction signed successfully.") # 正确获取区块哈希与有效截止高度 latest_blockhash_response = client.get_latest_blockhash("processed") blockhash = latest_blockhash_response.value.blockhash last_valid_block_height = latest_blockhash_response.value.last_valid_block_height app.logger.info(f"Blockhash: {blockhash}, Last valid block height: {last_valid_block_height}") # Step 5: Send the signed transaction app.logger.info("Sending signed transaction to Solana network") opts = TxOpts(skip_preflight=False, preflight_commitment=Processed) result = client.send_raw_transaction(txn=bytes(signed_txn), opts=opts) app.logger.info(f"Transaction sent successfully. Response: {result.to_json()}") # Step 6: Extract the transaction ID transaction_id = json.loads(result.to_json())['result'] app.logger.info(f"Transaction ID: {transaction_id}") # Step 7: 更可靠的交易确认逻辑 app.logger.info("Checking transaction confirmation status...") try: # 使用wait_for_transaction_confirmation自动轮询确认,无需手动管理高度 confirmation = client.wait_for_transaction_confirmation( signature=transaction_id, commitment="confirmed", # 可选"finalized"(最终不可逆转确认)或"confirmed"(已确认) timeout=30 # 设置合理超时,比如30秒避免无限等待 ) if confirmation.value.err is not None: raise RuntimeError(f"Transaction failed with error: {confirmation.value.err}") app.logger.info(f"Transaction confirmed successfully! View on explorer: https://explorer.solana.com/tx/{transaction_id}") except TimeoutError: app.logger.warning(f"Transaction confirmation timed out after 30 seconds.") raise RuntimeError("Transaction confirmation timeout")
关键调整点说明
- 正确提取有效截止高度:
直接从get_latest_blockhash返回的value对象中获取last_valid_block_height,而非错误地从context.slot取值。 - 替换为自动化确认方法:
用wait_for_transaction_confirmation替代手动调用confirm_transaction,该方法会自动轮询直到交易被确认或超时,无需手动处理高度判断逻辑。 - 合理设置确认级别:
processed仅表示交易被节点接收,未被网络确认;confirmed表示交易已被网络多数节点确认(多数场景足够);finalized表示交易已被最终确认(不可逆转,适合高安全性需求)。
- 主动添加超时控制:
明确设置超时时间,避免程序陷入无限等待的状态。
备注:内容来源于stack exchange,提问作者Steven Patrick




