使用web3.py与Infura发送以太坊交易未上链求助
以太坊交易返回TxID但未上链的问题排查与修复
从你的代码和描述来看,最核心的问题出在nonce的设置上——你用int(time.time())作为nonce,这完全不符合以太坊nonce的规则,这也是交易无法上链的主要原因。
问题解析
以太坊账户的nonce是一个递增的整数,代表该账户已发送的交易数量,每发送一笔新交易,nonce需要比上一笔大1。用时间戳当nonce会导致:
- 节点可能直接拒绝广播这个无效的交易(即使返回了TxID,这个ID只是签名后的哈希,并不代表交易被网络接收)
- 即使交易被广播,矿工也会因为nonce不合法而拒绝打包,最终交易永远不会上链
修复步骤与代码调整
- 获取正确的nonce:使用
web3.eth.getTransactionCount()获取账户的下一个可用nonce,参数传pending可以包含正在等待的交易(避免重复发送) - 确认其他参数的正确性
- 排查其他潜在问题
修正后的代码如下:
import web3 w = web3.Web3(web3.HTTPProvider('https://mainnet.infura.io/12345678')) # 先确认节点连接正常 if not w.isConnected(): print("Failed to connect to Infura node!") exit() gas_limit = 250000 # 推荐使用当前网络的gas价格,也可以手动设置(比如60gwei就是60 * 10**9) gas_price = w.eth.gas_price # 获取正确的nonce:pending参数包含未确认的交易,避免重复发送 nonce = w.eth.getTransactionCount(from_addr, 'pending') transaction = { 'to': to_addr, 'from': from_addr, 'value': int(eth_amount * (10**18)), 'gas': gas_limit, 'gasPrice': gas_price, 'chainId': 1, 'nonce': nonce } # 签名并发送交易 signed_transaction = w.eth.account.signTransaction(transaction, key) transaction_hash = w.eth.sendRawTransaction(signed_transaction.rawTransaction) tx_hash_hex = transaction_hash.hex() print(f'\n交易哈希:{tx_hash_hex}')
额外排查点
- 账户余额检查:确保你的账户余额足够支付转账金额 + gas费用(gas_limit * gasPrice),余额不足的话交易无法被打包
- 私钥正确性:确认你使用的私钥对应
from_addr,私钥错误会导致签名无效,交易无法被网络验证 - Gas参数合理性:虽然你设置了高额Gas,但如果gas_price远低于当前网络的最低打包要求,交易也会一直处于pending状态甚至被丢弃
- 节点状态:偶尔Infura节点会出现临时故障,可以尝试更换API密钥或者切换到其他以太坊节点服务
内容的提问来源于stack exchange,提问作者aste123
相关产品推荐
相关产品推荐

