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.logsRaw event logs emitted by contracts✅ Yes
tx.transfersParsed ERC-20 Transfer events✅ Yes
tx.approvalsParsed ERC-20 Approval 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
condition: tx.logs.any(event_name == "Transfer")

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

# Detect transfer to burn address (padded format)
condition: tx.transfers.any(to == "0x0000000000000000000000000000000000000000000000000000000000000000")

# Detect approval to specific spender
condition: tx.approvals.any(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
condition: tx.logs.count(event_name == "Transfer") > 5

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

# Multiple transfers to burn address
condition: tx.transfers.count(to == "0x0000000000000000000000000000000000000000000000000000000000000000") > 1

# Count approvals
condition: tx.approvals.count(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.transfers.count(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

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")
Recognized Events: Transfer, Approval, ApprovalForAll, Unknown

tx.transfers Fields

FieldTypeDescriptionExample
contractaddressToken contract addresstx.transfers.any(contract == "0x...")
fromaddressSource address (padded 32 bytes)tx.transfers.any(from == "0x0000...")
toaddressDestination address (padded 32 bytes)tx.transfers.any(to == "0x0000...")
amountstringTransfer amount (hex string)tx.transfers.any(amount != "0x0")

tx.approvals Fields

FieldTypeDescriptionExample
contractaddressToken contract addresstx.approvals.any(contract == "0x...")
owneraddressOwner address (padded 32 bytes)tx.approvals.any(owner == "0x0000...")
spenderaddressSpender address (padded 32 bytes)tx.approvals.any(spender == "0x0000...")
amountstringApproval amount (hex string)tx.approvals.any(amount != "0x0")
Address Format: Addresses in tx.transfers and tx.approvals 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.transfers.any(to == "0x0000000000000000000000000000000000000000000000000000000000000000")
  output: "Token burn detected in tx %tx.hash"
  priority: NOTICE
  enabled: true

Multiple Transfers

- rule: Multiple Token Transfers
  desc: Detects transactions with many token transfers
  tags: ["token", "transfers"]
  condition: tx.transfers.count(from != "") > 10
  output: "Multiple transfers detected in tx %tx.hash"
  priority: NOTICE
  enabled: true

Next Steps