如何在Ethers.js中修改默认交易手续费上限?
问题解决:Ethers.js 交易手续费超过配置上限的处理方案
问题背景
在Polygon和Avalanche C-Chain网络上使用Ethers.js执行智能合约批量处理函数时,触发错误:tx fee (4.00 ether) exceeds the configured cap (1.00 ether)。此前找到的解决方案仅针对本地Geth节点,现需要调整JsonRpcProvider的默认配置,同时确认是否可通过ConnectionInfo的params参数进行修改。
核心结论
Ethers.js的JsonRpcProvider本身没有内置的交易手续费上限配置,这个限制通常来自你连接的RPC节点服务提供商(比如Alchemy、Infura或第三方节点服务商),而非Ethers.js客户端层面。ConnectionInfo的参数里没有直接支持调整这个上限的选项,但可以通过以下两种方式解决:
方案1:更换RPC节点或联系服务商调整上限
大部分第三方RPC节点会设置手续费上限来防止恶意请求,如果你需要执行高手续费的批量交易,可以:
- 切换到支持更高手续费上限的RPC节点(比如付费节点服务)
- 联系当前节点服务商申请调整手续费上限
方案2:手动指定Gas参数,避免自动估算的高额费用
如果批量操作的Gas估算过高,可以手动调整Gas参数,降低总手续费:
- 手动设置
maxFeePerGas和maxPriorityFeePerGas(不使用getFeeData()返回的默认值) - 对
gasLimit进行合理校准,避免估算值虚高
代码调整示例
以下是修改后的交易构建代码,手动控制Gas参数:
async function createTransactionData(arg: any[]) { const transferABI = ["function batchSafeMint(address toAddress, uint256[] tokenIds, string[] uris)"]; const transferInterface = new ethers.utils.Interface(transferABI); const transferData = transferInterface.encodeFunctionData( 'batchSafeMint', [arg[0], arg[1], arg[2]] ); return transferData; } // 主流程调整 const transferData = await createTransactionData(params); const provider = new ethers.providers.JsonRpcProvider(network.networkURL); const nonce = await provider.getTransactionCount(senderAddress); const chainId = (await provider.getNetwork()).chainId; // 手动指定Gas参数(根据当前网络实际情况调整) const customMaxFeePerGas = ethers.utils.parseUnits("50", "gwei"); // 示例值,按需修改 const customMaxPriorityFeePerGas = ethers.utils.parseUnits("2", "gwei"); // 示例值,按需修改 const estimatedGas = await provider.estimateGas({ to: contractHash, data: transferData, from: senderAddress }); // 给Gas Limit加10%缓冲,避免溢出 const adjustedGasLimit = estimatedGas.mul(110).div(100); const rawTxn: any = { to: contractHash, maxFeePerGas: customMaxFeePerGas, maxPriorityFeePerGas: customMaxPriorityFeePerGas, chainId: chainId, data: transferData, gasPrice: null, nonce: nonce, value: null, type: 2, gasLimit: adjustedGasLimit }; const unsignedTxn = await ethers.utils.resolveProperties(rawTxn); const keccak256Hash = await getUnsignedTxnKeccak256Hash(unsignedTxn); const signedTxn = await signer.sign(keccak256Hash); // 自定义签名实现 const signedTxnRaw = ethers.utils.serializeTransaction( // @ts-ignore <UnsignedTransaction>unsignedTxn, signedTxn ); const receipt = await provider.sendTransaction(signedTxnRaw); let result = await provider.waitForTransaction(receipt.hash);
关于ConnectionInfo的说明
根据提供的ConnectionInfo类型定义,该参数仅用于配置RPC连接的基础属性(如URL、请求头、超时、节流等),没有支持调整交易手续费上限的字段:
// Exported Types export type ConnectionInfo = { url: string, headers?: { [key: string]: string | number } user?: string, password?: string, allowInsecureAuthentication?: boolean, allowGzip?: boolean, throttleLimit?: number, throttleSlotInterval?: number; throttleCallback?: (attempt: number, url: string) => Promise<boolean>, skipFetchSetup?: boolean; errorPassThrough?: boolean; timeout?: number, };
因此无法通过ConnectionInfo来修改交易手续费上限,必须从RPC节点或Gas参数配置入手解决。
内容的提问来源于stack exchange,提问作者kshitij chaurasiya
相关产品推荐
相关产品推荐

