Complete reference of transaction fields available in rule conditions. All fields are always available and don’t require any special configuration.
Basic Transaction Fields
Essential transaction information available in every transaction.
| Field | Type | Description | Example |
|---|
tx.hash | string | Transaction hash (unique identifier) | tx.hash != "" |
tx.from | address | Sender address | tx.from == "0x742d35..." |
tx.to | address | Recipient address (null for contract creation) | tx.to in (known_addresses) |
tx.value | wei | Transaction value (use ether for readability) | tx.value > 100 ether |
tx.gas | uint64 | Gas limit | tx.gas > 500000 |
tx.gas_price | wei | Gas price (use gwei for readability) | tx.gas_price > 100 gwei |
tx.gas_used | uint64 | Actual gas consumed (from receipt) | tx.gas_used > 100000 |
tx.input | hex | Transaction input data (calldata, raw) | len(tx.input) > 100 |
tx.nonce | uint64 | Transaction nonce | tx.nonce == 0 |
tx.status | uint64 | Transaction status (0=failed, 1=success) | tx.status == 1 |
tx.logs_count | int | Number of event logs emitted | tx.logs_count > 5 |
Block Data
Block-level context for the transaction.
| Field | Type | Description | Example |
|---|
tx.block.number | uint64 | Block number | tx.block.number > 18000000 |
tx.block.timestamp | uint64 | Block timestamp (Unix timestamp) | tx.block.timestamp > 1234567890 |
Function Detection
Blocklight provides three ways to detect function calls, each with different use cases:
Using tx.function_selector (Raw Selector)
The raw 4-byte function selector extracted from transaction input. Use this when:
- You need to detect a function that’s not in Blocklight’s database
- You want maximum precision and control
- You’re monitoring a specific protocol’s custom functions
# ERC-20 transfer() function
condition: tx.function_selector == "0xa9059cbb"
# Custom protocol function (not in database)
condition: tx.function_selector == "0x12345678"
Using tx.function_name (Specific Function)
The human-readable function name from Blocklight’s function database. Use this when:
- You want to detect a specific function (e.g., only
transfer, not transferFrom)
- You need human-readable conditions for better maintainability
- The function is in Blocklight’s database
# Using full function signature
condition: tx.function_name == "transfer(address,uint256)"
# Using short function name (without parameters)
condition: tx.function_name == "transfer"
# ERC-20 approve
condition: tx.function_name == "approve(address,uint256)"
Using tx.function_category (Function Group)
The category that groups related functions together. Use this when:
- You want to detect any function in a category (e.g., all transfer functions)
- You need broad detection without listing every function variant
- You want rules that automatically include new functions as they’re added to the database
# Detect any transfer function (transfer, transferFrom, safeTransferFrom, etc.)
condition: tx.function_category == "Transfer"
# Detect any swap function (all Uniswap swap variants)
condition: tx.function_category == "Swap"
# Detect any approval function
condition: tx.function_category == "Approval"
Available Function Categories: Transfer, Approval, Swap, Liquidity, Lending, FlashLoan, Multicall, Mint, Burn, Claim
Available Event Categories: Transfer, Approval, Swap
Note: Function categories and event categories are designed to be consistent where possible. However, not all function categories have corresponding event categories because functions represent what was called while events represent what was emitted. Some operations (like Liquidity, Lending, FlashLoan) may emit standard events like Transfer or protocol-specific events that vary by implementation.
Function Database: Blocklight includes a database of common function selectors (ERC-20, ERC-721, Uniswap, Aave, etc.). If a function is not in the database, tx.function_name and tx.function_category will be empty, but tx.function_selector will always be available.Backward Compatibility: You can still use startswith(tx.input, "0x...") for raw selector matching.
When to Use Each Field
| Field | Use Case | Example |
|---|
tx.function_selector | Custom functions, maximum precision | tx.function_selector == "0x12345678" |
tx.function_name | Specific known function | tx.function_name == "transfer" |
tx.function_category | Any function in a category | tx.function_category == "Transfer" |
Recommendation: Start with tx.function_category for broad detection, then use tx.function_name or tx.function_selector when you need more specificity.
Arrays: Event Logs with Automatic Parsing
Blocklight provides a single array tx.logs for all event logs, with automatic parsing of known events.
tx.logs - Event Logs (Unified Array)
All event logs emitted by contracts. Use with array methods (.any(), .count()).
Raw Fields (always available):
| Property | 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"):
| Property | 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"):
| Property | 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...") |
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 without needing separate arrays.Recognized Events: Transfer, Approval, ApprovalForAll, Swap, UnknownEvent Categories: Transfer, Approval, Swap (more categories will be added as we expand event recognition)Address Format: Parsed addresses (from, to, owner, spender) are padded to 32 bytes (64 hex characters) as they appear in event topics. Example: 0x000000000000000000000000742d35cc6634c0532925a3b844bc9e7595f0beb
When to Use tx.logs.any() vs tx.function_name
Key Difference:
tx.function_name / tx.function_category: Detects the function being called in the transaction (from tx.input)
tx.logs.any(event_name == ...) / tx.logs.any(event_category == ...): Detects events emitted during transaction execution (from tx.logs)
Use tx.function_name / tx.function_category when:
- You want to detect what function was called in the transaction
- You’re monitoring function calls to specific contracts
- Example:
tx.function_category == "Transfer" detects when someone calls a transfer function
Use tx.logs.any(event_name == ...) / tx.logs.any(event_category == ...) when:
- You want to detect events emitted during execution
- You need to check event parameters (from, to, amount, etc.)
- You’re monitoring token transfers, approvals, or other on-chain events
- Example:
tx.logs.any(event_category == "Transfer" and to == "0x...") detects Transfer events with specific parameters
Common Pattern: Combine both for comprehensive detection:
condition: >
tx.function_category == "Transfer" or
tx.logs.any(event_category == "Transfer")
Unit Suffixes
Use these suffixes for better readability. Blocklight automatically converts units for you.
| Unit | Field | Conversion | Example |
|---|
ether | tx.value | 1 ether = 1018 wei | tx.value > 100 ether |
gwei | tx.gas_price | 1 gwei = 109 wei | tx.gas_price > 50 gwei |
Choosing the Right Field: Functions vs Events
Understanding when to use function detection vs event detection is crucial for writing effective rules.
Functions: What Was Called
Fields: tx.function_selector, tx.function_name, tx.function_category
Use when:
- You want to detect what function was called in the transaction
- You’re monitoring function calls to specific contracts
- You need to know the exact function being invoked
Examples:
# Detect any transfer function call
condition: tx.function_category == "Transfer"
# Detect specific transfer function
condition: tx.function_name == "transfer"
# Detect custom function (not in database)
condition: tx.function_selector == "0x12345678"
Key Point: Functions are detected from tx.input (the calldata sent with the transaction).
Events: What Was Emitted
Fields: tx.logs.any(event_name == ...), tx.logs.any(event_category == ...)
Use when:
- You want to detect events emitted during transaction execution
- You need to check event parameters (from, to, amount, etc.)
- You’re monitoring token transfers, approvals, or other on-chain events
Examples:
# Detect any Transfer event
condition: tx.logs.any(event_category == "Transfer")
# Detect specific Transfer event with parameters
condition: tx.logs.any(event_name == "Transfer" and to == "0x...")
# Detect any Approval event
condition: tx.logs.any(event_category == "Approval")
# Detect any Swap event
condition: tx.logs.any(event_category == "Swap")
Key Point: Events are detected from tx.logs (events emitted by contracts during execution).
When to Use Each
| Scenario | Use | Example |
|---|
| Monitor function calls | tx.function_name / tx.function_category | tx.function_category == "Transfer" |
| Monitor events emitted | tx.logs.any(event_name == ...) / tx.logs.any(event_category == ...) | tx.logs.any(event_category == "Transfer") |
| Need event parameters | tx.logs.any(...) | tx.logs.any(event_name == "Transfer" and to == "0x...") |
| Custom/unknown functions | tx.function_selector | tx.function_selector == "0x12345678" |
| Broad detection (any variant) | Categories | tx.function_category == "Swap" or tx.logs.any(event_category == "Swap") |
| Specific detection | Names | tx.function_name == "transfer" or tx.logs.any(event_name == "Transfer") |
Common Patterns
Detect both function calls AND events:
condition: >
tx.function_category == "Transfer" or
tx.logs.any(event_category == "Transfer")
Detect Swap operations (function call OR event):
condition: >
tx.function_category == "Swap" or
tx.logs.any(event_category == "Swap")
Detect function call with specific event:
condition: >
tx.function_category == "Transfer" and
tx.logs.any(event_category == "Transfer" and to == "0x0000...")
Field Naming Patterns
All fields follow consistent patterns:
- Direct properties:
tx.value, tx.hash, tx.from, tx.function_selector, tx.function_name, tx.function_category
- Nested structures:
tx.block.timestamp, tx.block.number
- Arrays:
tx.logs (use with array methods) - includes event_name and event_category
Next Steps