Description
org.fisco.bcos.sdk.v3.codec.ContractCodec.decodeIndexedEvent(log, abiDefinition) does not correctly handle non-dynamic indexed event parameters (the common case, e.g. event Transfer(address indexed from, address indexed to, uint256 value)): the non-dynamic indexed topics throw / are dropped when decoding by interface.
Cause
For a non-dynamic indexed object, it routes a single value-type ABIObject through the JSON struct decoder:
} else {
List<String> objects =
contractCodecJsonWrapper.decode(
indexedObject, Hex.decode(log.getTopics().get(i)), isWasm);
if (!objects.isEmpty()) {
topics.add(objects.get(0));
}
}
ContractCodecJsonWrapper.decode on a single bare VALUE-type object treats it as a struct (its getStructFields() is null), which throws NullPointerException / produces no value, so non-dynamic indexed params cannot be decoded via the by-interface path. (Dynamic indexed params take the if (indexedObject.isDynamic()) branch and are fine.)
Impact
decodeEventByInterface / decodeIndexedEvent fail for events whose indexed parameters are value types (address indexed, uintN indexed, bytesN indexed, …) — a very common ABI shape.
Suggested fix
For non-dynamic indexed params, decode the 32-byte topic with the ABI TypeDecoder directly (as the static-bytes/value path elsewhere does) instead of ContractCodecJsonWrapper.decode.
Found via
Event encode→decode-by-interface tests during #947.
Description
org.fisco.bcos.sdk.v3.codec.ContractCodec.decodeIndexedEvent(log, abiDefinition)does not correctly handle non-dynamic indexed event parameters (the common case, e.g.event Transfer(address indexed from, address indexed to, uint256 value)): the non-dynamic indexed topics throw / are dropped when decoding by interface.Cause
For a non-dynamic indexed object, it routes a single value-type
ABIObjectthrough the JSON struct decoder:ContractCodecJsonWrapper.decodeon a single bare VALUE-type object treats it as a struct (itsgetStructFields()is null), which throwsNullPointerException/ produces no value, so non-dynamic indexed params cannot be decoded via the by-interface path. (Dynamic indexed params take theif (indexedObject.isDynamic())branch and are fine.)Impact
decodeEventByInterface/decodeIndexedEventfail for events whose indexed parameters are value types (address indexed,uintN indexed,bytesN indexed, …) — a very common ABI shape.Suggested fix
For non-dynamic indexed params, decode the 32-byte topic with the ABI
TypeDecoderdirectly (as the static-bytes/value path elsewhere does) instead ofContractCodecJsonWrapper.decode.Found via
Event encode→decode-by-interface tests during #947.