如何解码Uniswap Universal Router参数?附报错排查需求
解决Uniswap Universal Router参数解码的"invalid arrayify value"错误
错误根源
你当前的错误是因为把已经完成第一层解析的TransactionDescription对象传给了AbiCoder.decode,而AbiCoder.decode只接受原始十六进制字符串、Uint8Array这类字节数据,无法处理已解析的对象,才触发了arrayify函数的参数错误。
从报错信息看,你已经通过ethers的interface.parseTransaction或类似方法,成功解析出了Universal Router的execute函数参数(commands、inputs、deadline),不需要再对这个解析结果重复解码。你需要做的是进一步解码commands字节码对应的指令,以及inputs数组中每个元素的具体参数。
正确解码步骤
1. 明确已有的解析结果
你已经拿到的TransactionDescription里包含了核心数据:
commands: "0x0b00":每个字节对应一个Universal Router指令inputs: [bytes1, bytes2]:每个元素对应commands中同位置指令的参数编码deadline:交易截止时间的BigNumber值
2. 拆分指令并解码对应参数
Universal Router的每个指令字节对应特定操作,需要用对应的ABI结构解码inputs中的参数。以下是示例代码(基于ethers.js):
// 假设你已经通过parseTransaction得到了txDesc对象 const txDesc = ...; // 即报错信息中的value字段 // 拆分commands的每个字节 const commandBytes = ethers.utils.arrayify(txDesc.args.commands); // 遍历每个指令,解码对应input参数 commandBytes.forEach((cmdByte, index) => { const inputData = txDesc.args.inputs[index]; switch(cmdByte) { // 0x0b = V3_SWAP_EXACT_IN 指令 case 0x0b: // 定义V3精确输入兑换的参数ABI结构 const v3SwapInAbi = [ "tuple(" + "address tokenIn," + "address tokenOut," + "uint24 fee," + "address recipient," + "uint256 amountIn," + "uint256 amountOutMinimum," + "bytes path" + ")" ]; const decodedParams = ethers.utils.defaultAbiCoder.decode(v3SwapInAbi, inputData); console.log("V3精确输入兑换参数:", { tokenIn: decodedParams[0], tokenOut: decodedParams[1], feeTier: decodedParams[2], recipient: decodedParams[3], amountIn: ethers.utils.formatUnits(decodedParams[4], 18), amountOutMin: ethers.utils.formatUnits(decodedParams[5], 18), path: decodedParams[6] }); break; // 0x00 = NO_OP 空指令(无参数) case 0x00: console.log("空指令,无需处理"); break; // 其他指令可按需添加,比如0x0c=V3_SWAP_EXACT_OUT、0x02=V2_SWAP_EXACT_IN等 default: console.log("未知指令:0x" + cmdByte.toString(16).padStart(2, "0")); } });
3. 避免重复解析的错误写法
检查你的decodeUniversalRouterSwap函数,确保没有出现以下错误逻辑:
// ❌ 错误:把已解析的TransactionDescription传给decode const decoded = ethers.utils.defaultAbiCoder.decode(abi, txDesc); // ✅ 正确:仅对原始calldata(如tx.data)做第一次解析 const routerIface = new ethers.utils.Interface(UNIVERSAL_ROUTER_ABI); const txDesc = routerIface.parseTransaction({ data: tx.data, value: tx.value });
关键注意事项
- 确保使用的指令ABI与Uniswap官方定义一致,不同指令的参数结构差异很大
commands中的每个字节对应一个指令,inputs数组的索引与指令索引严格对应- 若遇到未知指令,可参考Uniswap Universal Router的合约源码或官方文档确认指令码含义
内容的提问来源于stack exchange,提问作者user22361630
相关产品推荐
相关产品推荐

