-
Notifications
You must be signed in to change notification settings - Fork 7
Open
Description
Summary
When encoding a struct that contains dynamic fields (like bytes) for use as a function parameter, the current implementation is missing the necessary offset at the beginning of the encoded data. This causes decoding failures in Solidity contracts.
Decoding would need to also support the proper format
Structure in question
var DataWithIdABI = abi.MustParseStruct(`struct DataWithId { uint64 triggerId; bytes data; }`)
bz := abi.MustEncodeValue(DataWithIdABI, DataWithID{
TriggerID: trigger_id,
Data: output,
})Results
Received
triggerId: 1 (uint64)
0000000000000000000000000000000000000000000000000000000000000001
Offset to the dynamic bytes field (64 bytes from struct start)
0000000000000000000000000000000000000000000000000000000000000040
Length of bytes array: 9
0000000000000000000000000000000000000000000000000000000000000009
Content: "test-data" with padding
746573742d646174610000000000000000000000000000000000000000000000
Expected (manually generated with solidity console.logBytes())
Offset to the start of the struct (32 bytes)
0x0000000000000000000000000000000000000000000000000000000000000020
triggerId: 1 (uint64)
0000000000000000000000000000000000000000000000000000000000000001
Offset to the dynamic bytes field (64 bytes from struct start)
0000000000000000000000000000000000000000000000000000000000000040
Length of bytes array: 9
0000000000000000000000000000000000000000000000000000000000000009
Content: "test-data" with padding
746573742d646174610000000000000000000000000000000000000000000000
My current hack
Without this change I have to hack the structure like so.
bz := abi.MustEncodeValue(DataWithIdABI, DataWithID{
TriggerID: trigger_id,
Data: output,
})
offsetBytes, _ := hex.DecodeString("0000000000000000000000000000000000000000000000000000000000000020")
return append(offsetBytes, bz...)Solidity func for reference
function handleSignedData(bytes calldata _data, bytes calldata _signature) external {
// _serviceManager.validate(_data, _signature);
DataWithId memory dataWithId = abi.decode(_data, (DataWithId));
// ....
}Metadata
Metadata
Assignees
Labels
No labels