BSC网络使用web3发起交易提示replacement transaction underpriced错误如何解决
错误根本原因
replacement transaction underpriced是EVM兼容链(含BSC)节点的标准报错,触发规则为:节点收到某地址的交易时,发现该交易的nonce和当前节点交易池中该地址的一笔未确认交易的nonce完全相同,且新交易的gasPrice未达到节点设定的替换交易最低溢价要求(BSC公开节点默认要求溢价至少10%),就会返回该-32000错误。
你之前调整参数无效的核心诱因有两个:
- 你使用
w3.eth.getTransactionCount(MY_WALLET_ADRESS)时默认取的是已上链确认交易的最大nonce,不会包含节点内存池中的未打包交易,导致你重复使用同一个nonce发起多笔交易 - 你调整后的gasPrice未达到原pending交易gasPrice的110%阈值,达不到替换交易的最低要求
修复方案
- 替换nonce获取逻辑,获取包含pending交易的最新nonce
# 明确指定pending参数,避免重复使用nonce nonce = w3.eth.getTransactionCount(MY_WALLET_ADRESS, 'pending')
- 不要硬编码gasPrice,动态获取当前网络实时gasPrice后乘以1.1~1.2倍的溢价系数,确保满足替换或打包优先级要求
- 不要硬编码gasLimit,调用预估gas接口后增加10%~20%的冗余,避免gas不足导致交易失败
- 如果存在长时间未打包的pending交易,可以先给对应nonce发起一笔自己转自己的0BNB交易,gasPrice给到原交易的1.2倍以上,先覆盖掉旧的pending交易后再发起新的购买交易
修正后代码示例
def buy(token_id, price): # 获取包含pending交易的最新nonce nonce = w3.eth.getTransactionCount(MY_WALLET_ADRESS, 'pending') # 动态获取当前网络推荐gasPrice,乘以1.2倍保证优先级 gas_price = int(w3.eth.gas_price * 1.2) # 构造基础交易参数 base_tx_params = { 'chainId': 56, 'from': MY_WALLET_ADRESS, 'nonce': nonce, 'gasPrice': gas_price } # 生成合约调用交易 tx = bid(token_id, int(price * 10**18)).buildTransaction(base_tx_params) # 预估gas并增加20%冗余 tx['gas'] = int(w3.eth.estimate_gas(tx) * 1.2) signed_txn = w3.eth.account.sign_transaction(tx, private_key=MY_PK) tx_hash = w3.eth.send_raw_transaction(signed_txn.rawTransaction) pending_tx.append(tx_hash)
内容的提问来源于stack exchange,提问作者Raphael
相关产品推荐
相关产品推荐

