Skip to content

ContractCodec.decodeIndexedEvent fails for non-dynamic indexed event params (address/uintN indexed) #950

@kyonRay

Description

@kyonRay

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.

Metadata

Metadata

Labels

bugSomething isn't working

Type

No type
No fields configured for issues without a type.

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions