You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何确保web3py发起的以太坊交易完成?代码问题排查

以太坊全余额转账代码问题分析与修复

核心问题点

  • 无限循环引发nonce冲突
    while True会持续发起交易,但如果前一笔交易还未上链,get_transaction_count会返回同一个nonce,重复提交同nonce的交易会被节点直接拒绝。
  • Gas参数设置严重不合理
    普通ETH转账的固定gasLimit仅需21000,你设置的2000000会导致手续费计算值过高,大概率让balance - gasLimit*gasPrice变为负数,以太坊不允许转账金额为负,直接导致交易失败。
  • 未处理余额边界情况
    当账户余额不足以支付手续费时,计算出的转账金额会是负数,必须先做余额校验再发起交易。
  • 缺少错误处理与终止逻辑
    代码没有异常捕获后的处理,也没有交易成功后的退出逻辑,要么死循环要么直接报错终止。

修复后的代码

import time

while True:
    balance = w3.eth.get_balance(pubadd)
    gas_price = w3.to_wei('55', 'gwei')
    gas_limit = 21000  # 普通转账固定gasLimit
    tx_fee = gas_limit * gas_price

    # 余额不足以支付手续费时终止循环
    if balance <= tx_fee:
        print("余额不足以支付手续费,终止转账")
        break

    nonce = w3.eth.get_transaction_count(pubadd)
    tx = {
        'nonce': nonce,
        'to': add,
        'value': balance - tx_fee,
        'gas': gas_limit,    
        'gasPrice': gas_price,
        'chainId': w3.eth.chain_id  # 必须指定链ID,防止跨链重放攻击
    }

    try:
        signed_tx = w3.eth.account.sign_transaction(tx, privkey)
        tx_hash = w3.eth.send_raw_transaction(signed_tx.rawTransaction)
        print(f"交易已提交,哈希: {tx_hash.hex()}")
        # 等待交易确认,避免重复提交
        receipt = w3.eth.wait_for_transaction_receipt(tx_hash, timeout=300)
        print(f"交易已确认,区块号: {receipt.blockNumber}")
        break  # 全余额转账完成后退出循环
    except Exception as e:
        print(f"交易失败: {str(e)}")
        time.sleep(10)  # 异常后等待重试
        continue

关键修复说明

  1. 修正gasLimit为普通转账的标准值21000,避免不必要的手续费扣除
  2. 增加余额校验,防止出现负金额转账
  3. 添加chainId参数,符合以太坊交易规范
  4. 加入交易确认等待逻辑,确保交易上链后再结束流程
  5. 增加异常捕获与重试机制,提升鲁棒性

内容的提问来源于stack exchange,提问作者areza

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 20:13:21