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
我的尝试:使用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 要求的参数呢,谢谢
这个编码好像只能手动拼接,先整理一下你的期望结果: 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