web3j icon indicating copy to clipboard operation
web3j copied to clipboard

When call a function with a parameter of two-dimensional array, it goes wrong

Open cylonggit opened this issue 1 year ago • 2 comments

When call a function with a parameter of two-dimensional array, it goes wrong

A clear and concise description of what the issue is.

Steps To Reproduce

the solidity code: function testParas(string[][] calldata array1 ) public view returns (string memory){ return (array1[1][1]); }

use web3j-maven-plugin 4.9.8 to get the java wrapper like the following: public RemoteFunctionCall<String> testParas(List<List<String>> array1) { final org.web3j.abi.datatypes.Function function = new org.web3j.abi.datatypes.Function(FUNC_TESTPARAS3, Arrays.<Type>asList(new org.web3j.abi.datatypes.DynamicArray<org.web3j.abi.datatypes.DynamicArray>( org.web3j.abi.datatypes.DynamicArray.class, org.web3j.abi.Utils.typeMap(array1, org.web3j.abi.datatypes.DynamicArray.class, org.web3j.abi.datatypes.Utf8String.class))), Arrays.<TypeReference<?>>asList(new TypeReference<Utf8String>() {})); return executeRemoteCallSingleValueReturn(function, String.class); }

the java code: List<String> u_0=new ArrayList<>(); u_0.add("7300"); u_0.add("7400"); List<String> u_1=new ArrayList<>(); u_1.add("7200"); u_1.add("mark");

List<List<String>> uAll = new ArrayList<>(); uAll.add(u_0); uAll.add(u_1);

String r=EthService.myContract_sp.testParas(uAll).send();

then it will go with an error: org.web3j.tx.exceptions.ContractCallException: Contract Call has been reverted by the EVM with the reason: 'execution reverted'.

But I can call this function in Remix, and it's all ok.

Environment

Describe the environment in which the issue occurs

  • Web3j version : 4.9.8
  • Web3j-maven-plugin version: 4.9.8
  • Java or Android version: 1.8
  • go-ethereum version: 1.9
  • Operating System: mac 13.1
  • Solidity version: 0.8.7

cylonggit avatar May 06 '23 07:05 cylonggit

I have the same problem.

Can you help me get java code?

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract TestArray {
    struct Order {
        address from;
        address to;
    }

    function setOrder(Order calldata) external {}

    function setOrders(Order[] calldata) external {}

    function setOrderss(Order[][] calldata) external {}

    // function get(uint256[][] calldata) external {}
}

EthanOK avatar Jun 06 '23 02:06 EthanOK

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[]"
    }

kxl4126 avatar Aug 02 '24 19:08 kxl4126