簡體   English   中英

在 web3j 中,如何為運行時發現的數組類型創建 TypeReference?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM