web3j
web3j copied to clipboard
When call a function with a parameter of two-dimensional array, it goes wrong
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
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 {}
}
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[]"
}