1

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 ?

Thanks in advance.

1 Answer 1

0

Dealing with web3j internal types is not the best starting point.

What you can do is generate the Java contract wrappers for your ABI. The wrappers are Java classes that abstract the internal Web3j logic and provide you with functions you can use to interact with your contract using native Java types.

You can do that, for example, using the web3j-cli and use the following:

$ web3j generate solidity -a <abi_file> -o <output_dir> -p <package_name> 

Another easier way is to use the web3j-gradle-plugin or web3j-maven-plugin to generate the wrappers from your projects via the provided generateContractWrappers and use the wrappers from there.

2
  • I've created java wrapper class but when i call a function it returns a transaction receipt instead of function value. Commented Aug 25, 2022 at 15:03
  • That is a current limitation of the Web3J library. If the function changes state and at the same time returns a value. The value cannot be retrieved currently and only the transaction receipt will be returned. There has been some work on supporting this, but I don't think it is ready. Commented Aug 25, 2022 at 19:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.