DefaultFunctionEncoder calculates offset incorrectly for nested structs
bladekp opened this issue · 2 comments
DefaultFunctionEncoder calculates offset incorrectly for nested structs
Steps To Reproduce
Minimal example:
- Create function which has nested structs as parameters, like:
var f = new org.web3j.abi.datatypes.Function(
"myCustomFunction",
Arrays.asList(
new StaticStruct(
new StaticStruct(
new org.web3j.abi.datatypes.Address("0x1"),
new org.web3j.abi.datatypes.Address("0x2"))),
new org.web3j.abi.datatypes.DynamicBytes(new byte[]{1,2,3})),
Collections.emptyList());
Note that first argument is StaticStruct having one property which is also StaticStruct, nested one have two Address properties, which is important in this example. Also having dynamic type as second argument is important.
- Execute
FunctionEncoder.encode(f)
. Result will be:
0x76a4d94f
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000002
0000000000000000000000000000000000000000000000000000000000000040
0000000000000000000000000000000000000000000000000000000000000003
0102030000000000000000000000000000000000000000000000000000000000
- In result, since second argument is dynamic (DynamicBytes type) offset is included.
Expected behavior
Offset value in that case should equal to 0x60
.
Actual behavior
Offset value is (as you can see above) 0x40
, this is because nested StaticStruct is calculated to have size of 1 (but 2 addresses are inside, so size should be 2).
Environment
- Web3j version 4.10.3
- Java 17
- Operating System Fedora 38 x64, kernel Linux 6.8.7-100.fc38.x86_64
Additional context
My production case, Im attaching two executions:
- first one with wrong offset (
0xe0
in my case), failure:
MethodID: 0x30f28b7a
[0]: 00000000000000000000000002567e4b14b25549331fcee2b56c647a8bab16fd
[1]: 0000000000000000000000000000000000000000000000000de0b6b3a7640000
[2]: 0000000000000000000000000000000000000000000000000000000000000006
[3]: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
[4]: 000000000000000000000000f909259faf3f052792d7d28fb25ae54c43243041
[5]: 0000000000000000000000000000000000000000000000000de0b6b3a7640000
[6]: 000000000000000000000000d1f92a7f86cc94639ed6f3acd2ed540c742602dc
[7]: 00000000000000000000000000000000000000000000000000000000000000e0
[8]: 0000000000000000000000000000000000000000000000000000000000000041
[9]: 7d117587f7976edc3e9043e2ed79be2aa61b49d4513a410bfcc915b146663854
[10]: 253ccba5465141beb4f92adafdef1ab510a5854a61cdb860a1a3ceb1ae86d971
[11]: 1c00000000000000000000000000000000000000000000000000000000000000
- second with adjusted offset (
0x100
), succeeded:
MethodID: 0x30f28b7a
[0]: 00000000000000000000000002567e4b14b25549331fcee2b56c647a8bab16fd
[1]: 0000000000000000000000000000000000000000000000000de0b6b3a7640000
[2]: 0000000000000000000000000000000000000000000000000000000000000006
[3]: ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff
[4]: 000000000000000000000000f909259faf3f052792d7d28fb25ae54c43243041
[5]: 0000000000000000000000000000000000000000000000000de0b6b3a7640000
[6]: 000000000000000000000000d1f92a7f86cc94639ed6f3acd2ed540c742602dc
[7]: 0000000000000000000000000000000000000000000000000000000000000100
[8]: 0000000000000000000000000000000000000000000000000000000000000041
[9]: 7d117587f7976edc3e9043e2ed79be2aa61b49d4513a410bfcc915b146663854
[10]: 253ccba5465141beb4f92adafdef1ab510a5854a61cdb860a1a3ceb1ae86d971
[11]: 1c00000000000000000000000000000000000000000000000000000000000000
I think the solution is to make getLength
function recursive, and change line:
https://github.com/hyperledger/web3j/blob/5173684412b4d816fc1b4b8bf6c112424a37c7ce/abi/src/main/java/org/web3j/abi/DefaultFunctionEncoder.java#L102
to count += getLength(((StaticArray) type).getValue())
Hey @bladekp , thanks for opening the issue.
If you feel to contribute by fixing it, feel free to open up a PR, we will review and merge it.
Thanks
Looks like fix was prepared by @penuel-leo in #2054 and merged, and was released in https://github.com/hyperledger/web3j/releases/tag/v4.12.0 so I think we can close this issue. Thanks.