Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call a function that returns tuple[]

I am relatively new to interacting with smart contracts in Java and I am facing a problem while trying to retrieve a tuple[] returned by the smart contract function. Here is the ABI definition of the function I want to call:

{
  "inputs":[{"internalType":"address","name":"account","type":"address"}],
  "name":"claimableRewards",
  "outputs":
    [{"components":
      [
        {"internalType":"address","name":"token","type":"address"},
        {"internalType":"uint256","name":"amount","type":"uint256"}
      ],
      "internalType":"struct MultiFeeDistribution.RewardData[]",
      "name":"rewards",
      "type":"tuple[]"
    }],
  "stateMutability":"view",
  "type":"function"
}

Here is the link to the smart contract code: https://polygonscan.com/address/0x920f22e1e5da04504b765f8110ab96a20e6408bd#code

And here is the Java code that I wrote to call the function (I have removed the errors checking to make the code easier to read):

List<Type> claimableRewardsParams = Arrays.<Type>asList(new Address(credentials.getAddress()));
List<TypeReference<?>> claimableRewardsReturnTypes = Arrays.<TypeReference<?>>asList(new TypeReference<DynamicArray<DynamicStruct>>() {});

final Function claimableRewardsFunction = new Function(
        "claimableRewards",
        claimableRewardsParams,
        claimableRewardsReturnTypes);

String claimableRewardsEncodedFunction = FunctionEncoder
        .encode(claimableRewardsFunction);          

EthCall claimableRewardsResponse = web3.ethCall(
        Transaction.createEthCallTransaction(walletAddress, adamantRewardsContractAddress, claimableRewardsEncodedFunction),
        DefaultBlockParameterName.LATEST)
        .sendAsync().get();

List<Type> claimableRewardsSomeTypes = FunctionReturnDecoder.decode(
        claimableRewardsResponse.getValue(), claimableRewardsFunction.getOutputParameters());

When I run the program I get the following exception:

Exception in thread "main" java.lang.RuntimeException: TypeReferenced struct must contain a constructor with types that extend Type

I have tried several other definitions for claimableRewardsReturnTypes, but I can't get it to work. Can someone please help me?

like image 936
Coin Lover Avatar asked Dec 05 '25 13:12

Coin Lover


1 Answers

You need to define a class that extends DynamicStruct

public class RewardData extends DynamicStruct {
    public RewardData(Address token, Uint256 amount) {
        super(new Type[]{token, amount});
    }
}

and then replace DynamicStruct with RewardData

List<TypeReference<?>> claimableRewardsReturnTypes = Arrays.<TypeReference<?>>asList(new TypeReference<DynamicArray<RewardData>>() {});
like image 143
PierreLuo Avatar answered Dec 08 '25 05:12

PierreLuo



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!