You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Python中Solana交易的正确确认方法及区块高度异常问题咨询

Python中Solana交易的正确确认方法及区块高度异常问题咨询

看起来你在Solana交易确认的逻辑上踩了个关键小坑,这大概率就是导致等待超过90秒的核心原因。先帮你梳理问题所在,再给出调整后的可靠方案:

核心问题分析

你当前获取last_valid_block_height的方式完全错误:

  • 你把get_latest_blockhash返回结果里contextslot(当前区块槽位)当成了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")

关键调整点说明

  1. 正确提取有效截止高度
    直接从get_latest_blockhash返回的value对象中获取last_valid_block_height,而非错误地从context.slot取值。
  2. 替换为自动化确认方法
    wait_for_transaction_confirmation替代手动调用confirm_transaction,该方法会自动轮询直到交易被确认或超时,无需手动处理高度判断逻辑。
  3. 合理设置确认级别
    • processed仅表示交易被节点接收,未被网络确认;
    • confirmed表示交易已被网络多数节点确认(多数场景足够);
    • finalized表示交易已被最终确认(不可逆转,适合高安全性需求)。
  4. 主动添加超时控制
    明确设置超时时间,避免程序陷入无限等待的状态。

备注:内容来源于stack exchange,提问作者Steven Patrick

火山引擎 最新活动