Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Solidity multidimensional array as return #2038

Open
ismoli opened this issue Apr 14, 2024 · 3 comments
Open

Solidity multidimensional array as return #2038

ismoli opened this issue Apr 14, 2024 · 3 comments
Labels
bug A bug in behaviour or functionality

Comments

@ismoli
Copy link

ismoli commented Apr 14, 2024

Bug_title

Impossible to call Solidity function that returns 2d array from contract

Steps To Reproduce

Simple solidity function:
function get() view external returns (uint128[][] memory) {...}
Generate wrapper, or construct ethCall manually.

Expected behavior

Function should be called successfully and return result

Actual behavior

Exception occurred

java.lang.UnsupportedOperationException: Unable to access parameterized type org.web3j.abi.datatypes.DynamicArray<org.web3j.abi.datatypes.DynamicArray<org.web3j.abi.datatypes.generated.Uint128>>

	at org.web3j.abi.TypeDecoder.decodeArrayElements(TypeDecoder.java:694)
	at org.web3j.abi.TypeDecoder.decodeDynamicArray(TypeDecoder.java:442)
	at org.web3j.abi.DefaultFunctionReturnDecoder.build(DefaultFunctionReturnDecoder.java:100)
	at org.web3j.abi.DefaultFunctionReturnDecoder.decodeFunctionResult(DefaultFunctionReturnDecoder.java:52)
	at org.web3j.abi.FunctionReturnDecoder.decode(FunctionReturnDecoder.java:57)
	at org.web3j.tx.Contract.executeCall(Contract.java:313)
	at org.web3j.tx.Contract.executeCallMultipleValueReturn(Contract.java:357)

Environment

Web3j version 4.9.8

Additional context

So generated code is using
new TypeReference<DynamicArray<DynamicArray<Uint128>>>() {} as output value which seems like not really working.

Is there any workaround? When constructing a call manually (as opposed to generating wrapper), what should I set for Types to 'Output parameters' to make it work?

@ismoli ismoli added the bug A bug in behaviour or functionality label Apr 14, 2024
@alexdupre
Copy link
Contributor

I've just encountered another issue with multi-dimensional arrays as return value, but with the opposite generated code.

For a function defined as

function getStateOfRewards(address _rewardOwner) external view returns (RewardState[][] memory rewardStates);

the generated wrapper was:

final Function function = new Function(FUNC_GETSTATEOFREWARDS, 
                Arrays.<Type>asList(new org.web3j.abi.datatypes.Address(160, _rewardOwner)), 
                Arrays.<TypeReference<?>>asList(new TypeReference<DynamicArray<RewardState>>() {}));

that didn't work because of the missing nested array. Changing it to:

final Function function = new Function(FUNC_GETSTATEOFREWARDS, 
                Arrays.<Type>asList(new org.web3j.abi.datatypes.Address(160, _rewardOwner)), 
                Arrays.<TypeReference<?>>asList(new TypeReference<DynamicArray<DynamicArray<RewardState>>>() {}));

made it working.

Tested with today 4.12.0-SNAPSHOT.

@kxl4126
Copy link

kxl4126 commented Aug 2, 2024

The current getTypeAsString for DynamicArray only supports DynamicStruct as a nested type. I just created another class extending DynamicArray and overrode it so it also supported DynamicArray as a nested type, which worked for me.

override fun getTypeAsString(): String {
        val type = if (value.isEmpty()) {
            if (StructType::class.java.isAssignableFrom(this.componentType)) {
                Utils.getStructType(this.componentType)
            } else {
                AbiTypes.getTypeAString(this.componentType)
            }
        } else if (StructType::class.java.isAssignableFrom((value[0] as Type<*>).javaClass) || (DynamicArray::class.java.isAssignableFrom((value[0] as Type<*>).javaClass))) {
            (value[0] as Type<*>).typeAsString
        } else {
            AbiTypes.getTypeAString(this.componentType)
        }

        return "$type[]"
    }

@ApereLieZ
Copy link

@kxl4126
Could you please provide a complete example of the implementation of DynamicArray and an example of its usage?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A bug in behaviour or functionality
Projects
None yet
Development

No branches or pull requests

4 participants