You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解码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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 10:20:54