ethers5.6.9调用V2Router.getAmountsOut报missing revert data异常
环境信息
- 开发语言:TypeScript
- 依赖版本:
ethers@5.6.9
问题表现
调用V2Router的getAmountsOut方法时抛出异常,错误信息:
missing revert data in call exception; Transaction reverted without a reason string
运行日志输出:
[WARN] error - 获取价格出错: missing revert data in call exception; Transaction reverted without a reason string
复现代码:
... import * as UniswapV2Router from "../../../abis/UniswapV2Router02.json"; ... export const getPriceOnUniV2 = async ( tokenIn: string, tokenOut: string, amountIn: BigNumber, routerAddress: string ): Promise<BigNumber> => { const V2Router = new ethers.Contract( routerAddress, UniswapV2Router.abi, maticProvider ); const amountsOut = await V2Router.getAmountsOut(1000, [tokenIn, tokenOut]); if (!amountsOut || amountsOut.length !== 2) { return getBigNumber(0); } return amountsOut[1]; };
根因分析
- 参数类型与传值错误:函数定义了入参
amountIn为BigNumber类型,但实际调用getAmountsOut时硬编码传入了JS基础类型的数字1000,不符合合约方法要求的uint256类型入参规范;且数值未按对应代币的精度转换为链上最小单位值,会直接导致合约执行逻辑异常回滚。 - 兑换路径无效:传入的
tokenIn、tokenOut在对应路由协议下不存在可连通的流动池,合约无法查询到代币储备量计算汇率时,会直接触发无原因字符串的回滚。 - 网络与合约地址不匹配:使用的Polygon节点provider与传入的
routerAddress所属网络不对应,或路由地址、代币地址格式错误(非校验和地址、零地址),会导致合约调用失败。
修复方案
- 修正传参逻辑:删除硬编码的数字传值,使用符合精度要求的BigNumber类型值作为第一个入参,禁止直接传入JS number类型值作为合约uint256参数。修正后的调用示例:
// 错误写法:直接传number类型的1000 // const amountsOut = await V2Router.getAmountsOut(1000, [tokenIn, tokenOut]); // 正确写法:传入转换为对应代币精度的BigNumber值 // 若要测试1000单位的输入代币,按代币精度转换,比如18位精度代币用parseUnits转 // const fixedAmount = ethers.utils.parseUnits("1000", 18); const amountsOut = await V2Router.getAmountsOut(amountIn, [tokenIn, tokenOut]);
- 调用前做前置校验:
- 确认
maticProvider连接的网络与routerAddress所属网络一致,路由地址为当前链上V2类交易所的合法路由合约地址 - 校验
tokenIn、tokenOut为合法的校验和格式地址,且两个代币在对应交易所存在直接流动池 - 校验传入的
amountIn为大于0的有效BigNumber值,提前拦截非法入参
- 确认
内容的提问来源于stack exchange,提问作者Julio Sarda
相关产品推荐
相关产品推荐

