# event_decode_json

Returns decoded EVM event arguments as compact JSON; use it for already-materialized topics and data when malformed input should produce NULL.

Canonical HTML: <https://determica.com/docs/functions/event_decode_json>

- Kind: scalar function
- Category: [Contracts and ABI](/docs/category/contracts-and-abi.md)
- Tags: ABI, Logs, Inspection, RPC

Returns decoded EVM event arguments as compact JSON; use it for already-materialized topics and data when malformed input should produce NULL.

## Overload 1: event_decode_json(JSON, BYTES32\[\], BLOB)

```sql
event_decode_json(JSON, BYTES32[], BLOB)
```

Accepts a JSON ABI event fragment.

- Kind: scalar
- Execution context: Offline
- Behavior: Compact Json Event Decode
- Execution modes: Offline
- Input shape: Scalar Arguments
- Planning contract: Runtime
- Cardinality: One Per Input
- Determinism: Deterministic
- Return shape: JSON
- Schema stability: Fixed
- Stability: Stable
- Side effects: None documented

### Inputs

- `event_abi` (JSON; required; positional) — Single event ABI object with indexed flags and input types.
- `topics` (BYTES32[]; required; positional) — LIST of BYTES32 values. For non-anonymous events, the first list element is EVM topic0; anonymous events begin with the first indexed argument.
- `data` (BLOB; required; positional) — ABI-encoded non-indexed event data as BLOB.

### Returns

Decoded event JSON

Returns values keyed by ABI input name. Unnamed inputs use arg_0, arg_1, and so on; booleans and lists remain JSON, EVM BLOB-backed values are 0x strings, and other scalars are strings.

- `decoded_event` (JSON)

Decoded event JSON. Returns values keyed by ABI input name. Unnamed inputs use arg_0, arg_1, and so on; booleans and lists remain JSON, EVM BLOB-backed values are 0x strings, and other scalars are strings.

### Examples

_Local SQL · Local_

```sql
-- Decode a USDC Transfer log to JSON with a JSON event ABI
SELECT event_decode_json(
  '{"type":"event","name":"Transfer","inputs":[{"indexed":true,"name":"sender","type":"address"},{"indexed":true,"name":"recipient","type":"address"},{"indexed":false,"name":"value","type":"uint256"}]}'::JSON,
  [
    event_signature('Transfer(address,address,uint256)'),
    evm_abi_word('0xcb83ca9633ad057bd88a48a5b6e8108d97ad4472'::ADDRESS),
    evm_abi_word('0xa1db2fc9b2ceaf3cdf41fd11ffcb38404eae3906'::ADDRESS)
  ],
  evm_abi_word(615568393::UINT256)::BLOB
) AS decoded_event;
-- decoded_event.sender = 0xcb83ca9633ad057bd88a48a5b6e8108d97ad4472
```

## Overload 2: event_decode_json(VARCHAR, BYTES32\[\], BLOB)

```sql
event_decode_json(VARCHAR, BYTES32[], BLOB)
```

Accepts a JSON ABI event fragment as VARCHAR.

- Kind: scalar
- Execution context: Offline
- Behavior: Compact Json Event Decode
- Execution modes: Offline
- Input shape: Scalar Arguments
- Planning contract: Runtime
- Cardinality: One Per Input
- Determinism: Deterministic
- Return shape: JSON
- Schema stability: Fixed
- Stability: Stable
- Side effects: None documented

### Inputs

- `event_abi` (VARCHAR; required; positional) — Single JSON ABI event object supplied explicitly as VARCHAR.
- `topics` (BYTES32[]; required; positional) — LIST of BYTES32 values. For non-anonymous events, the first list element is EVM topic0; anonymous events begin with the first indexed argument.
- `data` (BLOB; required; positional) — ABI-encoded non-indexed event data as BLOB.

### Returns

Decoded event JSON

Returns values keyed by ABI input name. Unnamed inputs use arg_0, arg_1, and so on; booleans and lists remain JSON, EVM BLOB-backed values are 0x strings, and other scalars are strings.

- `decoded_event` (JSON)

Decoded event JSON. Returns values keyed by ABI input name. Unnamed inputs use arg_0, arg_1, and so on; booleans and lists remain JSON, EVM BLOB-backed values are 0x strings, and other scalars are strings.

### Examples

_Local SQL · Local_

```sql
-- Decode a USDC Transfer log to JSON from VARCHAR
SELECT event_decode_json(
  '{"type":"event","name":"Transfer","inputs":[{"indexed":true,"name":"sender","type":"address"},{"indexed":true,"name":"recipient","type":"address"},{"indexed":false,"name":"value","type":"uint256"}]}'::VARCHAR,
  [
    event_signature('Transfer(address,address,uint256)'),
    evm_abi_word('0xcb83ca9633ad057bd88a48a5b6e8108d97ad4472'::ADDRESS),
    evm_abi_word('0xa1db2fc9b2ceaf3cdf41fd11ffcb38404eae3906'::ADDRESS)
  ],
  evm_abi_word(615568393::UINT256)::BLOB
) AS decoded_event;
-- decoded_event.sender = 0xcb83ca9633ad057bd88a48a5b6e8108d97ad4472
```

## Guidance

### Decode logs offline

Use event_decode_json when topics and data are already available from get_logs, get_transaction_logs, or a fixture. The ABI event fragment controls how indexed topics and data words are decoded.

- For a non-anonymous event, the first topic should be event_signature('EventName(types...)'). Anonymous events omit topic0 and begin with their first indexed parameter.
- The canonical sample reconstructs USDC transaction 0x5cbf...3dde, log index 97, at Ethereum block 20,000,000 without an RPC call.
- Indexed addresses are stored as left-padded BYTES32 topics.
- Indexed dynamic values are represented by their indexed topic hash.
- Non-indexed values are decoded from the data BLOB. A mismatched non-anonymous topic0 is currently not rejected.
- Malformed ABI, topics, or data return NULL instead of raising a decode error.

## Related functions

- [get_logs](/docs/functions/get_logs.md) — Usually After
- [get_transaction_logs](/docs/functions/get_transaction_logs.md) — Usually After
- [event_decode](/docs/functions/event_decode.md) — Alternative
- [log_decode_json](/docs/functions/log_decode_json.md) — Alternative
