55 Uniswap V3: Router交换函数中的参数 params.path 数据类型为 bytes是怎么得到的?

Uniswap V3: Router交换函数中的参数 params.path 数据类型为 bytes是怎么得到的? 在uniswap V3的智能合约 0xe592427a0aece92de3edee1f18e0157c05861564 (Uniswap V3: Router)上一个执行代币交换的函数Function: exactInput(tuple params),其中有一个参数: params.path 数据类型为 bytes,这里放的是代币路由比如tokenA-tokenB-tokenC
tokenA=0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9 tokenB=0x82aF49447D8a07e3bd95BD0d56f35241523fBab1 tokenC=0x6fD58f5a2F3468e35fEb098b5F59F04157002407

期望得到的结果为:0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb90001f482af49447d8a07e3bd95bd0d56f35241523fbab10027106fd58f5a2f3468e35feb098b5f59f04157002407

image.png

我的尝试:使用Java web3j

public static void main(String[] args) {
    List<Type> inputParameters = new LinkedList<>();

    String inputToken = "0xFd086bC7CD5C481DCC9C85ebE478A1C0b69FCbb9"; // 输入代币地址
    String middleToken = "0x82aF49447D8a07e3bd95BD0d56f35241523fBab1"; // 
    String outputToken = "0x6fD58f5a2F3468e35fEb098b5F59F04157002407"; // 输出代币地址

    inputParameters.add(new Address(inputToken));
    inputParameters.add(new Address(middleToken));
    inputParameters.add(new Address(outputToken));

        //      Address[] path = new Address[3];
        //      path[0] =  new Address(inputToken);
        //      path[1] =  new Address(middleToken);
        //      path[2] =  new Address(outputToken);
        //      inputParameters.add(new DynamicArray(path));

    inputParameters.add(new Bool(false));

    Function function = new Function(
            "encodePath",
            inputParameters,
            Arrays.asList(new TypeReference<Address>() {
            })
    );

            // 将函数编码为 bytes 类型的数据
    String encodedFunction = FunctionEncoder.encode(function);
    System.out.println(encodedFunction);
    byte[] encodedPath = Numeric.hexStringToByteArray(encodedFunction);

//输出结果  //0xdbc90761000000000000000000000000fd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb900000000000000000000000082af49447d8a07e3bd95bd0d56f35241523fbab10000000000000000000000006fd58f5a2f3468e35feb098b5f59f041570024070000000000000000000000000000000000000000000000000000000000000000
}

结论:尝试的结果与期望结果不符,请问应该怎么得到params.path 要求的参数呢,谢谢

请先 登录 后评论

最佳答案 2023-05-12 08:58

这个编码好像只能手动拼接,先整理一下你的期望结果: 0x fd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9 0001f4 82af49447d8a07e3bd95bd0d56f35241523fbab1 002710 6fd58f5a2f3468e35feb098b5f59f04157002407 然后你会发现中间多出来的0001f4和002710是对应池子的手续费, 0001f4转换成10进制是500,说明第1和第2个代币对选择的是手续费0.05%的池子 002710转换成10进制是10000,说明第2和第3个代币对选择的是手续费1%的池子

这个数字目前固定有4个,100,500,3000,10000 分别对应手续费是 0.01%,0.05%、0.3% 和 1%

理解了这个你的问题就好解决了,你现在需要找到两两配对的代币到底选择哪个手续费的池子,然后根据手续费计算出中间应该加什么代码,这里写了个函数,把手续费转换成你需要添加的编码

function intToHexString(num) {
  // 将整数转换成16进制字符串
  const hexString = num.toString(16);
  // 使用 padStart 在左侧添加0来填充字符串
  return hexString.padStart(6, '0');
}

然后手动拼接: 地址1+手续费编码+地址2+手续费编码+地址3

请先 登录 后评论

其它 0 个回答

  • 1 关注
  • 0 收藏,2389 浏览
  • 用户_15137 提出于 2023-05-05 10:29