BSC节点快速交易发送咨询:交易成功率低问题求解
BSC高时效性交易发送优化方案
针对你在BSC网络发送高时效性交易成功率低的问题,可通过以下几个方向优化:
1. 采用EIP-1559动态Gas策略,提升打包优先级
BSC网络拥堵时固定gasPrice极易被挤掉,改用EIP-1559的maxFeePerGas和maxPriorityFeePerGas参数,能更灵活适配网络状态:
- 实时获取当前区块基准Gas价格,在此基础上添加10%-30%的溢价作为
maxFeePerGas - 设置固定的
maxPriorityFeePerGas(BSC网络常用5gwei左右,可根据拥堵程度调整)
示例代码:
const baseGasPrice = await provider.getGasPrice(); const maxFeePerGas = baseGasPrice.mul(13).div(10); // 溢价30% const maxPriorityFeePerGas = ethers.utils.parseUnits("5", "gwei"); await wallet.sendTransaction({ to: to, value: value, data: data, maxFeePerGas: maxFeePerGas, maxPriorityFeePerGas: maxPriorityFeePerGas, gasLimit: gasLimit });
2. 预计算并缓存Gas Limit,减少发送延迟
每次发送前实时估算Gas Limit会消耗节点资源且易出现误差,建议提前预计算并缓存,发送时直接使用,还可额外增加少量缓冲值避免估算不足:
// 提前缓存Gas Limit const cachedGasLimit = await provider.estimateGas({ to: to, value: value, data: data }); // 发送时使用缓存值+缓冲 await wallet.sendTransaction({ to: to, value: value, data: data, maxFeePerGas: maxFeePerGas, maxPriorityFeePerGas: maxPriorityFeePerGas, gasLimit: cachedGasLimit.add(ethers.utils.parseUnits("10000", "wei")) });
3. 提前离线签名,到点直接广播
如果交易触发时间固定,可提前离线完成交易签名,到时间点直接将签名好的交易广播到节点,跳过签名时的节点交互步骤,大幅缩短发送耗时:
// 提前构造并签名交易 const txConfig = { to: to, value: value, data: data, maxFeePerGas: maxFeePerGas, maxPriorityFeePerGas: maxPriorityFeePerGas, gasLimit: cachedGasLimit, chainId: 56 // BSC主网链ID }; const signedTx = await wallet.signTransaction(txConfig); // 到指定时间直接广播 await provider.sendTransaction(signedTx);
4. 多节点并行广播,降低单点故障风险
单一节点可能出现延迟或故障,同时连接多个BSC公共节点,发送交易时并行广播,提高交易被打包的概率。可借助FallbackProvider实现多节点容错:
const providers = [ new ethers.providers.JsonRpcProvider("https://bsc-dataseed.binance.org/"), new ethers.providers.JsonRpcProvider("https://bsc-dataseed1.defibit.io/"), new ethers.providers.JsonRpcProvider("https://bsc-dataseed1.ninicoin.io/") ]; const fallbackProvider = new ethers.providers.FallbackProvider(providers); const wallet = new ethers.Wallet(privateKey, fallbackProvider); // 使用该钱包发送交易,自动切换可用节点
5. 监控交易状态,超时自动替换
若交易超过设定时间(如10秒)未被打包,立即发送带有相同nonce但更高Gas价格的替换交易,强制提高优先级:
async function sendAndReplaceTx(wallet, txConfig, retryTimes = 3) { let nonce = await wallet.getTransactionCount(); txConfig.nonce = nonce; let tx = await wallet.sendTransaction(txConfig); for (let i = 0; i < retryTimes; i++) { await new Promise(resolve => setTimeout(resolve, 10000)); try { const receipt = await tx.wait(1); if (receipt) return receipt; } catch (e) { // 交易未上链,继续替换 } // 提高20%Gas价格替换交易 txConfig.maxFeePerGas = txConfig.maxFeePerGas.mul(12).div(10); tx = await wallet.sendTransaction(txConfig); } throw new Error("交易多次替换仍未上链"); }
内容的提问来源于stack exchange,提问作者Achilles
相关产品推荐
相关产品推荐

