[英]In web3j, how do you create a TypeReference for array types discovered at runtime?
我正在嘗試使用 web3j 編寫一個 Java 應用程序,該應用程序可以讀取任意 abi 文件,向用戶顯示 AbiDefinitions 列表,並讓他調用他選擇的常量函數。 我如何計算下面的輸出類型?
AbiDefinition functionDef = ...; // found at runtime
List<Type> args = ...; // I know how to do this
List<NamedType> outputs = functionDef.getOutputs(); // list of output parameters
List<TypeReference<?>> outTypes = ????;
Function function = new Function(functionDef.getName(), args, outTypes);
TypeReference 類使用泛型類型的技巧,當泛型類型被硬編碼在源代碼中時,這些技巧會起作用,如下所示:
new TypeReference.StaticArrayTypeReference< StaticArray< Int256>>(2){}
這就是生成的合約包裝器會做的事情。
對於簡單類型,我可以這樣做:
Class<Type> type = (Class<Type>)AbiTypes.getType(typeName);
TypeReference<?> typeRef = TypeReference.create(type);
對於像“int256[2]”這樣的數組類型,我該怎么辦?
uniswapV2 路由器
function getAmountsOut(uint amountIn, address[] calldata path) 外部視圖返回(uint[] 內存量)
package com.test;
import org.web3j.abi.FunctionEncoder;
import org.web3j.abi.FunctionReturnDecoder;
import org.web3j.abi.TypeReference;
import org.web3j.abi.datatypes.Address;
import org.web3j.abi.datatypes.DynamicArray;
import org.web3j.abi.datatypes.Function;
import org.web3j.abi.datatypes.Type;
import org.web3j.abi.datatypes.generated.Uint256;
import org.web3j.protocol.Web3j;
import org.web3j.protocol.core.DefaultBlockParameterName;
import org.web3j.protocol.core.methods.request.Transaction;
import org.web3j.protocol.core.methods.response.EthCall;
import org.web3j.protocol.http.HttpService;
import java.io.IOException;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;
public class main {
private static String EMPTY_ADDRESS = "0x0000000000000000000000000000000000000000";
static Web3j web3j;
static String usdt = "0x55d398326f99059fF775485246999027B3197955";
static String weth = "0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c";
static String pancakeRouter = "0x10ed43c718714eb63d5aa57b78b54704e256024e";
public static void main(String[] args) throws IOException {
web3j = Web3j.build(new HttpService("https://bsc-dataseed.binance.org/"));
String s = web3j.netVersion().send().getNetVersion();
System.out.println(s);
List<BigInteger> list1 = getAmountsOut(usdt, weth);
System.out.println("result::: ");
for (BigInteger a : list1) {
System.out.println(a);
}
}
public static List<BigInteger> getAmountsOut(String tokenInAddr, String tokenOutAddr) {
String methodName = "getAmountsOut";
String fromAddr = EMPTY_ADDRESS;
List<Type> inputParameters = new ArrayList<Type>();
Uint256 inAmount = new Uint256(new BigInteger("1000000000000000000"));
Address inAddr = new Address(tokenInAddr);
Address outAddr = new Address(tokenOutAddr);
DynamicArray<Address> addrArr = new DynamicArray<Address>(inAddr, outAddr);
inputParameters.add(inAmount);
inputParameters.add(addrArr);
List<TypeReference<?>> outputParameters = new ArrayList<TypeReference<?>>();
TypeReference<DynamicArray<Uint256>> oa = new TypeReference<DynamicArray<Uint256>>() {
};
outputParameters.add(oa);
Function function = new Function(methodName, inputParameters, outputParameters);
String data = FunctionEncoder.encode(function);
Transaction transaction = Transaction.createEthCallTransaction(fromAddr, pancakeRouter, data);
EthCall ethCall;
try {
ethCall = web3j.ethCall(transaction, DefaultBlockParameterName.LATEST).sendAsync().get();
List<Type> results = FunctionReturnDecoder.decode(ethCall.getValue(), function.getOutputParameters());
System.out.println(results);
List<BigInteger> resultArr = new ArrayList<>();
if (results.size() > 0) {
for (Type tt : results) {
DynamicArray<Uint256> da = (DynamicArray<Uint256>) tt;
List<Uint256> lu = da.getValue();
if (lu.size() > 0) {
for (Uint256 n : lu) {
resultArr.add((BigInteger) n.getValue());
}
}
}
return resultArr;
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.