> ## Documentation Index
> Fetch the complete documentation index at: https://docs.blocklight.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Array Methods

> Working with arrays in detection rules

Array methods allow you to search, filter, and count elements in transaction data arrays. Blocklight supports two methods: `.any()` and `.count()`.

## Supported Arrays

| Array     | Description                                        | Always Available? |
| --------- | -------------------------------------------------- | ----------------- |
| `tx.logs` | Event logs with automatic parsing for known events | ✅ Yes             |

## `.any()` Method

Check if **any** element in an array matches a condition.

### Syntax

```yaml theme={null}
array.any(field operator value)
```

### Examples

```yaml theme={null}
# Detect any Transfer event (specific)
condition: tx.logs.any(event_name == "Transfer")

# Detect any Transfer category event (broader - includes all transfer variants)
condition: tx.logs.any(event_category == "Transfer")

# Detect event from specific contract
condition: tx.logs.any(address == "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48")

# Detect Transfer event to burn address (padded format)
condition: tx.logs.any(event_name == "Transfer" and to == "0x0000000000000000000000000000000000000000000000000000000000000000")

# Detect any Approval category event (includes Approval and ApprovalForAll)
condition: tx.logs.any(event_category == "Approval" and spender == "0x0000000000000000000000001234567890123456789012345678901234567890")
```

## `.count()` Method

Count how many elements match a condition, then compare the count.

### Syntax

```yaml theme={null}
array.count(field operator value) comparison number
```

### Supported Comparisons

* `>` - Greater than
* `<` - Less than
* `>=` - Greater than or equal
* `<=` - Less than or equal
* `==` - Equal to
* `!=` - Not equal to

### Examples

```yaml theme={null}
# Multiple Transfer events (specific)
condition: tx.logs.count(event_name == "Transfer") > 5

# Multiple Transfer category events (broader)
condition: tx.logs.count(event_category == "Transfer") > 5

# Exactly one Approval (specific)
condition: tx.logs.count(event_name == "Approval") == 1

# Any Approval category event (broader - includes ApprovalForAll)
condition: tx.logs.count(event_category == "Approval") > 0

# Multiple Transfer events to burn address
condition: tx.logs.count(event_name == "Transfer" and to == "0x0000000000000000000000000000000000000000000000000000000000000000") > 1

# Count Approval category events
condition: tx.logs.count(event_category == "Approval" and spender != "") > 3
```

## Combining with Other Conditions

Array methods work seamlessly with logical operators (`and`, `or`, `not`):

```yaml theme={null}
# Event AND value check
condition: tx.logs.any(event_name == "Transfer") and tx.value > 100 ether

# Multiple conditions
condition: tx.logs.count(event_name == "Transfer" and to == "0x0...") > 5 and tx.gas_used > 1000000

# NOT with array method
condition: not tx.logs.any(event_name == "Approval")
```

## Available Fields in Arrays

### `tx.logs` Fields

**Raw Fields** (always available):

| Field             | Type    | Description                              | Example                                      |
| ----------------- | ------- | ---------------------------------------- | -------------------------------------------- |
| `address`         | address | Contract that emitted the log            | `tx.logs.any(address == "0x...")`            |
| `event_signature` | string  | Event signature hash (topic\[0])         | `tx.logs.any(event_signature == "0xddf...")` |
| `event_name`      | string  | Parsed event name                        | `tx.logs.any(event_name == "Transfer")`      |
| `event_category`  | string  | Event category (group of related events) | `tx.logs.any(event_category == "Transfer")`  |
| `data`            | string  | Log data (hex string)                    | `tx.logs.any(data != "0x")`                  |
| `log_index`       | uint    | Index of the log in the transaction      | `tx.logs.any(log_index == 0)`                |
| `block_number`    | uint64  | Block number where the log was emitted   | `tx.logs.any(block_number > 18000000)`       |
| `tx_index`        | uint    | Transaction index in the block           | `tx.logs.any(tx_index == 5)`                 |
| `removed`         | bool    | Whether the log was removed              | `tx.logs.any(removed == false)`              |

**Parsed Fields** (automatically added for known events):

For **Transfer events** (`event_name == "Transfer"`):

| Field      | Type    | Description                           | Example                                                         |
| ---------- | ------- | ------------------------------------- | --------------------------------------------------------------- |
| `contract` | address | Token contract address                | `tx.logs.any(event_name == "Transfer" and contract == "0x...")` |
| `from`     | address | Source address (padded 32 bytes)      | `tx.logs.any(event_name == "Transfer" and from == "0x0000...")` |
| `to`       | address | Destination address (padded 32 bytes) | `tx.logs.any(event_name == "Transfer" and to == "0x0000...")`   |
| `amount`   | string  | Transfer amount (hex string)          | `tx.logs.any(event_name == "Transfer" and amount != "0x0")`     |

For **Approval events** (`event_name == "Approval"`):

| Field      | Type    | Description                       | Example                                                            |
| ---------- | ------- | --------------------------------- | ------------------------------------------------------------------ |
| `contract` | address | Token contract address            | `tx.logs.any(event_name == "Approval" and contract == "0x...")`    |
| `owner`    | address | Owner address (padded 32 bytes)   | `tx.logs.any(event_name == "Approval" and owner == "0x0000...")`   |
| `spender`  | address | Spender address (padded 32 bytes) | `tx.logs.any(event_name == "Approval" and spender == "0x0000...")` |
| `amount`   | string  | Approval amount (hex string)      | `tx.logs.any(event_name == "Approval" and amount == "0xffff...")`  |

<Info>
  **Automatic Parsing:** When Blocklight recognizes an event (Transfer, Approval), it automatically parses and adds the relevant fields (`from`, `to`, `amount`, etc.) to the log entry. This means you can use `tx.logs.any(event_name == "Transfer" and to == "0x...")` directly.

  **Recognized Events:** `Transfer`, `Approval`, `ApprovalForAll`, `Swap`, `Unknown`

  **Event Categories:** `Transfer`, `Approval`, `Swap` (more categories will be added as we expand event recognition)

  **When to Use `event_name` vs `event_category`:**

  * Use `event_name` when you need a specific event (e.g., only `Transfer`, not `ApprovalForAll`)
  * Use `event_category` when you want to detect any event in a category (e.g., all approval-related events)

  **Address Format:** Parsed addresses (from, to, owner, spender) are padded to 32 bytes (64 hex characters) as they appear in event topics. See [Fields](/rules/fields) for details.
</Info>

## Limitations

### Not Supported

❌ **Direct array index access:**

```yaml theme={null}
# NOT SUPPORTED
tx.logs[0].address == "0x..."
```

❌ **Complex nested conditions inside array methods:**

```yaml theme={null}
# NOT SUPPORTED - Use separate .any() calls instead
tx.logs.any(event_name == "Transfer" and (amount > 100 or from == "0x..."))
```

### Workarounds

For complex conditions, use multiple `.any()` or `.count()` calls:

```yaml theme={null}
# Instead of nested logic inside .any():
condition: >
  tx.logs.any(event_name == "Transfer") and
  tx.logs.any(address == "0x...")
```

## Common Patterns

### Token Burn Detection

```yaml theme={null}
- rule: Token Burn Detected
  desc: Detects ERC-20 token burns
  tags: ["token", "burn"]
  condition: >
    tx.logs.any(event_name == "Transfer" and to == "0x0000000000000000000000000000000000000000000000000000000000000000")
  output: "Token burn detected in tx %tx.hash (from=%tx.logs.matched.from amount=%tx.logs.matched.amount)"
  priority: NOTICE
  enabled: true
```

### Multiple Transfers

```yaml theme={null}
- rule: Multiple Token Transfers
  desc: Detects transactions with many token transfers
  tags: ["token", "transfers"]
  condition: tx.logs.count(event_name == "Transfer" and from != "") > 10
  output: "Multiple transfers detected in tx %tx.hash"
  priority: NOTICE
  enabled: true
```

## Next Steps

<CardGroup cols={2}>
  <Card title="Fields" icon="book" href="/rules/fields">
    Learn about transaction fields
  </Card>

  <Card title="Examples" icon="code" href="/rules/examples">
    See complete rule examples
  </Card>
</CardGroup>
