使用DynamicStruct
solidity中的代码为

struct ExactInputParams {
bytes path;
address recipient;
uint256 amountIn;
uint256 amountOutMinimum;
}
function exactInput(ExactInputParams calldata params) external payable returns (uint256 amountOut)
使用java web3j对该函数进行编码:
我的尝试:

//拼装路径;tokenA fee tokenB fee tokenC;
String path = "0x55d398326f99059ff775485246999027b3197955000064e9e7cea3dedca5984780bafc599bd69add087d560000649840652dc04fb9db2c43853633f0f62be6f00f98";
//exactInput((bytes,address,uint256,uint256))方法编码
List<Type> inputParameters1 = new LinkedList<>();
byte[] bytesParam = Numeric.hexStringToByteArray(path);
DynamicBytes bytesParam1 = new DynamicBytes(bytesParam);
inputParameters1.add(bytesParam1);
inputParameters1.add(new Address("0x71836e418915B34D05bE74995c1eC77EEB246E22"));
inputParameters1.add(new Uint256(new BigInteger("11137595489375510586")));
inputParameters1.add(new Uint256(new BigInteger("112745856625915642687")));
Function function = new Function(
"exactInput",
inputParameters1,
Arrays.asList(new TypeReference<Type>() {
})
);
String swapCode = FunctionEncoder.encode(function);
System.out.println(swapCode);
得到的结果:
0x11b69c46000000000000000000000000000000000000000000000000000000000000008000000000000000000000000071836e418915b34d05be74995c1ec77eeb246e220000000000000000000000000000000000000000000000009a90b0168c38603a0000000000000000000000000000000000000000000000061ca9bf3f84d2c33f000000000000000000000000000000000000000000000000000000000000004255d398326f99059ff775485246999027b3197955000064e9e7cea3dedca5984780bafc599bd69add087d560000649840652dc04fb9db2c43853633f0f62be6f00f98000000000000000000000000000000000000000000000000000000000000
期望的结果:
0xb858183f0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000008000000000000000000000000071836e418915b34d05be74995c1ec77eeb246e220000000000000000000000000000000000000000000000009a90b0168c38603a0000000000000000000000000000000000000000000000061ca9bf3f84d2c33f000000000000000000000000000000000000000000000000000000000000004255d398326f99059ff775485246999027b3197955000064e9e7cea3dedca5984780bafc599bd69add087d560000649840652dc04fb9db2c43853633f0f62be6f00f98000000000000000000000000000000000000000000000000000000000000
验证:
结构体包含string类型(bytes类型、动态数组类型),在Java声明为动态结构体 DynamicStruct。(https://github.com/EthanOK/LearnSolidity/blob/main/utils/EncodeStructAndDynamicArray.md)
或者使用 Web3j 将 Solidity 代码转换为 Java 代码
https://github.com/web3j/web3j-maven-plugin

public static class ExactInputParams extends DynamicStruct {
public byte[] path;
public String recipient;
public BigInteger amountIn;
public BigInteger amountOutMinimum;
public ExactInputParams(byte[] path, String recipient, BigInteger amountIn, BigInteger amountOutMinimum) {
super(new org.web3j.abi.datatypes.DynamicBytes(path),
new org.web3j.abi.datatypes.Address(160, recipient),
new org.web3j.abi.datatypes.generated.Uint256(amountIn),
new org.web3j.abi.datatypes.generated.Uint256(amountOutMinimum));
this.path = path;
this.recipient = recipient;
this.amountIn = amountIn;
this.amountOutMinimum = amountOutMinimum;
}
public ExactInputParams(DynamicBytes path, Address recipient, Uint256 amountIn, Uint256 amountOutMinimum) {
super(path, recipient, amountIn, amountOutMinimum);
this.path = path.getValue();
this.recipient = recipient.getValue();
this.amountIn = amountIn.getValue();
this.amountOutMinimum = amountOutMinimum.getValue();
}
}