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

如何使用web3.py替换待处理交易 提高Gas优先转出钱包资产

高Gas抢跑转出资产交易广播不稳定修复

现有代码核心问题

  • Pending交易过滤器依赖单节点连接,遇到节点同步延迟、连接闪断会直接漏抓黑客发起的交易,且没有异常重连逻辑,连接断开后脚本直接崩溃退出
  • 单位换算、余额计算存在逻辑错误:Gas成本计算重复做单位换算,导致算出的最大转账额经常超过账户实际可用余额,交易被节点以「余额不足」为由直接丢弃,不会进入交易池
  • Gas溢价计算逻辑存在精度偏差,实际设置的Gas价格经常达不到比黑客交易高20%的预期,无法实现抢跑
  • 仅向单个节点发送一次交易,没有冗余广播、重试机制:遇到单个节点交易池满、本地校验规则拦截时,交易根本不会传播到全网
  • 固定20秒的运行窗口过短,且没有交易上链状态校验,要么提前退出错过交易时机,要么发送一次失败后没有后续动作

修复后可稳定运行的代码

import time
from decimal import Decimal
from web3 import Web3, exceptions

# -------------------------- 配置项 --------------------------
# 多节点RPC列表,建议混合搭配自有节点、不同服务商的节点,提升广播覆盖率
RPC_LIST = [
    "你的RPC节点地址1",
    "你的RPC节点地址2",
    "你的RPC节点地址3"
]
w3_list = [Web3(Web3.HTTPProvider(rpc)) for rpc in RPC_LIST]
# 默认用第一个节点做链上数据查询
w3 = w3_list[0]

address_from = "存在被盗风险的钱包地址"
recipient = "资产接收地址".replace(' ', '')
private_key = "风险钱包私钥"
chain_id = 1 # 对应链ID,以太坊主网为1,BSC为56,根据实际链修改
GAS_PREMIUM = 1.2  # Gas比黑客交易高20%,可根据需要调高到1.5/2提升抢跑成功率
GAS_LIMIT = 21000
# -----------------------------------------------------------

def broadcast_transaction(signed_tx):
    """多节点冗余广播交易"""
    for node_w3 in w3_list:
        try:
            node_w3.eth.sendRawTransaction(signed_tx.rawTransaction)
        except Exception as e:
            # 忽略不影响广播的已知错误
            if "already known" not in str(e) and "nonce too low" not in str(e):
                continue

def get_confirmed_nonce():
    """获取当前地址已上链确认的最新nonce"""
    return w3.eth.getTransactionCount(address_from, "latest")

if __name__ == "__main__":
    current_nonce = get_confirmed_nonce()
    print(f"当前已确认nonce: {current_nonce}, 监控异常交易中...")
    target_nonce = None
    last_send_time = 0
    signed_tx = None

    while True:
        # 自动重建pending过滤器,避免连接断开后过滤器失效
        try:
            pending_filter = w3.eth.filter("pending")
            while True:
                # 已捕获黑客交易后,持续检测交易上链状态+重发抢跑交易
                if target_nonce is not None:
                    onchain_nonce = get_confirmed_nonce()
                    if onchain_nonce > target_nonce:
                        print(f"nonce {target_nonce} 已上链,资产转出完成")
                        exit(0)
                    # 每隔100ms重发一次交易,提升被矿工打包的概率
                    if time.time() - last_send_time > 0.1:
                        broadcast_transaction(signed_tx)
                        last_send_time = time.time()

                # 拉取最新pending交易
                try:
                    pending_tx_hashes = pending_filter.get_new_entries()
                except exceptions.ConnectionError:
                    # 连接断开时跳出内层循环,重建过滤器
                    break

                for tx_hash in pending_tx_hashes:
                    try:
                        pending_tx = w3.eth.getTransaction(tx_hash)
                    except Exception:
                        continue
                    # 检测到黑客从目标地址发起的、非我方接收地址的交易
                    if pending_tx.get("from") == address_from and pending_tx.get("to") != recipient:
                        print(f"检测到黑客可疑交易: {w3.toHex(tx_hash)}")
                        target_nonce = pending_tx.get("nonce")
                        hacker_gas_price = pending_tx.get("gasPrice")
                        # 修正Gas计算:直接在黑客Gas基础上加溢价,单位保留wei避免换算误差
                        target_gas_price = int(hacker_gas_price * GAS_PREMIUM)
                        # 修正余额计算:全链路用wei单位计算,避免精度丢失
                        balance_wei = w3.eth.getBalance(address_from)
                        gas_cost_wei = target_gas_price * GAS_LIMIT
                        # 留1000wei余量,避免因精度问题触发余额不足报错
                        transfer_value_wei = balance_wei - gas_cost_wei - 1000
                        if transfer_value_wei <=0:
                            print("余额不足以覆盖Gas,转出失败")
                            exit(1)
                        # 构造抢跑交易
                        tx = {
                            "chainId": chain_id,
                            "nonce": target_nonce,
                            "to": recipient,
                            "value": transfer_value_wei,
                            "gas": GAS_LIMIT,
                            "gasPrice": target_gas_price,
                        }
                        signed_tx = w3.eth.account.signTransaction(tx, private_key)
                        print(f"开始广播抢跑交易, nonce: {target_nonce}, GasPrice: {w3.fromWei(target_gas_price, 'gwei')} gwei")
                        broadcast_transaction(signed_tx)
                        last_send_time = time.time()
                time.sleep(0.05)
        except Exception as e:
            print(f"过滤器连接异常,1秒后重连: {str(e)}")
            time.sleep(1)
            continue

额外优化建议

  • 节点尽量选择和矿池直连的低延迟节点,比公共节点能更早收到pending交易,广播的交易也能更快进入矿池
  • 如果目标链支持EIP1559,可以把Gas费设置改成maxFeePerGas和maxPriorityFeePerGas模式,抢跑成功率更高
  • 私钥不要硬编码在脚本里,运行前临时输入即可,避免私钥泄露

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 13:33:23