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

Supported Arrays

ArrayDescriptionAlways Available?
tx.logsEvent logs with automatic parsing for known events✅ Yes

.any() Method

Check if any element in an array matches a condition.

Syntax

array.any(field operator value)

Examples

# 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

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

# 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):
# 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):
FieldTypeDescriptionExample
addressaddressContract that emitted the logtx.logs.any(address == "0x...")
event_signaturestringEvent signature hash (topic[0])tx.logs.any(event_signature == "0xddf...")
event_namestringParsed event nametx.logs.any(event_name == "Transfer")
event_categorystringEvent category (group of related events)tx.logs.any(event_category == "Transfer")
datastringLog data (hex string)tx.logs.any(data != "0x")
log_indexuintIndex of the log in the transactiontx.logs.any(log_index == 0)
block_numberuint64Block number where the log was emittedtx.logs.any(block_number > 18000000)
tx_indexuintTransaction index in the blocktx.logs.any(tx_index == 5)
removedboolWhether the log was removedtx.logs.any(removed == false)
Parsed Fields (automatically added for known events): For Transfer events (event_name == "Transfer"):
FieldTypeDescriptionExample
contractaddressToken contract addresstx.logs.any(event_name == "Transfer" and contract == "0x...")
fromaddressSource address (padded 32 bytes)tx.logs.any(event_name == "Transfer" and from == "0x0000...")
toaddressDestination address (padded 32 bytes)tx.logs.any(event_name == "Transfer" and to == "0x0000...")
amountstringTransfer amount (hex string)tx.logs.any(event_name == "Transfer" and amount != "0x0")
For Approval events (event_name == "Approval"):
FieldTypeDescriptionExample
contractaddressToken contract addresstx.logs.any(event_name == "Approval" and contract == "0x...")
owneraddressOwner address (padded 32 bytes)tx.logs.any(event_name == "Approval" and owner == "0x0000...")
spenderaddressSpender address (padded 32 bytes)tx.logs.any(event_name == "Approval" and spender == "0x0000...")
amountstringApproval amount (hex string)tx.logs.any(event_name == "Approval" and amount == "0xffff...")
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, UnknownEvent 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 for details.

Limitations

Not Supported

Direct array index access:
# NOT SUPPORTED
tx.logs[0].address == "0x..."
Complex nested conditions inside array methods:
# 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:
# Instead of nested logic inside .any():
condition: >
  tx.logs.any(event_name == "Transfer") and
  tx.logs.any(address == "0x...")

Common Patterns

Token Burn Detection

- 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

- 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