Method Id is not calculated correctly if a parameter is a DynamicArray within a DynamicStruct
Method Id is not calculated correctly if a parameter is a DynamicArray within a DynamicStruct
In Solidity it is possible to define an array within a struct and use it as method parameter:
struct StructWithArray {
uint256[] numbers;
}
function functionName(StructWithArray calldata _parameter) external;
If such a construct is used, web3j does not calculate the method id correctly. If a transaction is sent to the smart contract, it will fail, because the method id is wrong and therfore unknown to the contract.
Steps To Reproduce
Define a function which has as parameter a DynamicArray within a DynamicStruct. Calculate the method id with FunctionEncoder.buildMethodSignature. I have prepared a test to reproduce this:
git clone https://github.com/daniellehrner/web3j.git
git checkout method_id_array_in_struct
./gradlew abi:test --tests "org.web3j.abi.DefaultFunctionEncoderTest.testArrayWithinStructEncode"
Expected behavior
The created test should be successful
Actual behavior
The created test fails
@Ferparishuertas
@daniellehrner Thanks for reporting this I will look into it.
same question
I'm seeing a similar problem with arrays of Structs:
struct Foo {
address a;
uint64 b;
}
function doStuff(Foo[] calldata aFoos, Foo[] calldata bFoos) external {
...
}
Turns out my issue is due to empty array parameters as per the source code comment in https://github.com/web3j/web3j/blob/master/abi/src/main/java/org/web3j/abi/datatypes/DynamicArray.java:
public String getTypeAsString() {
String type;
// Handle dynamic array of zero length. This will fail if the dynamic array
// is an array of structs.
if (value.isEmpty()) {
type = AbiTypes.getTypeAString(getComponentType());
} else {
if (StructType.class.isAssignableFrom(value.get(0).getClass())) {
type = value.get(0).getTypeAsString();
} else {
type = AbiTypes.getTypeAString(getComponentType());
}
}
return type + "[]";
}
Guess I'll just have to pass in some zero values as a workaround
this was fixed with the PR mentioned in #1742