> ## 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.

# Output Placeholders

> Use placeholders in the output field to include dynamic values in your alert messages

Use placeholders in the `output` field to include dynamic values in your alert messages. Format: `%variable` (single % prefix, no trailing %).

<Warning>
  **Important:** Use `%tx.hash` NOT `%tx.hash%`. Only one % at the beginning!
</Warning>

## Available Placeholders

### Basic Transaction Fields

| Placeholder             | Output Value                                | Example                       |
| ----------------------- | ------------------------------------------- | ----------------------------- |
| `%tx.hash`              | Transaction hash                            | `0xd6343c3d...`               |
| `%tx.from`              | Sender address                              | `0x2fb074...`                 |
| `%tx.to`                | Recipient address                           | `0x6c3ea9...`                 |
| `%tx.value`             | Value in wei (string)                       | `1000000000000000000`         |
| `%tx.value_eth`         | Value in ETH (formatted to 4 decimals)      | `1.0000`                      |
| `%tx.nonce`             | Transaction nonce                           | `952`                         |
| `%tx.gas`               | Gas limit                                   | `21000`                       |
| `%tx.gas_used`          | Actual gas consumed                         | `102876`                      |
| `%tx.gas_price`         | Gas price in wei (string)                   | `100000000000`                |
| `%tx.gas_price_gwei`    | Gas price in gwei (formatted to 2 decimals) | `100.00`                      |
| `%tx.input`             | Transaction input data (hex)                | `0x095ea7b3...`               |
| `%tx.function_selector` | Function selector (4 bytes, hex)            | `0xa9059cbb`                  |
| `%tx.function_name`     | Function name (if in database)              | `transfer(address,uint256)`   |
| `%tx.function_category` | Function category (if in database)          | `Transfer`                    |
| `%tx.block.number`      | Block number                                | `18500000`                    |
| `%tx.block.timestamp`   | Block timestamp (Unix timestamp)            | `1705312200`                  |
| `%tx.block_hash`        | Block hash                                  | `0x1234abcd...`               |
| `%tx.tx_index`          | Transaction index in block                  | `5`                           |
| `%tx.chain`             | Chain identifier                            | `ethereum`                    |
| `%tx.status`            | Transaction status                          | `1` (success) or `0` (failed) |
| `%tx.logs_count`        | Number of event logs                        | `5`                           |
| `%tx.timestamp`         | Timestamp (RFC3339 format)                  | `2024-01-15T10:30:00Z`        |
| `%tx.timestamp_unix`    | Unix timestamp (seconds)                    | `1705312200`                  |

### Matched Log Placeholders

When a rule uses `tx.logs.any(...)` in its condition, you can access information about the log that matched using these placeholders:

**Raw Fields** (always available):

| Placeholder                        | Output Value                                  | Example                                                              |
| ---------------------------------- | --------------------------------------------- | -------------------------------------------------------------------- |
| `%tx.logs.matched.address`         | Contract address that emitted the matched log | `0x6c3ea9...`                                                        |
| `%tx.logs.matched.event_name`      | Name of the matched event                     | `Transfer`                                                           |
| `%tx.logs.matched.event_category`  | Category of the matched event                 | `Transfer`                                                           |
| `%tx.logs.matched.event_signature` | Event signature hash (topic\[0])              | `0xddf252ad...`                                                      |
| `%tx.logs.matched.log_index`       | Index of the matched log in the transaction   | `0`                                                                  |
| `%tx.logs.matched.data`            | Log data (hex string)                         | `0x0000000000000000000000000000000000000000000000000de0b6b3a7640000` |
| `%tx.logs.matched.block_number`    | Block number where the log was emitted        | `18500000`                                                           |
| `%tx.logs.matched.tx_index`        | Transaction index in the block                | `5`                                                                  |
| `%tx.logs.matched.removed`         | Whether the log was removed (true/false)      | `false`                                                              |

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

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

| Placeholder                 | Output Value                          | Example                                                              |
| --------------------------- | ------------------------------------- | -------------------------------------------------------------------- |
| `%tx.logs.matched.contract` | Token contract address                | `0x6c3ea9...`                                                        |
| `%tx.logs.matched.from`     | Source address (padded 32 bytes)      | `0x0000000000000000000000001234567890123456789012345678901234567890` |
| `%tx.logs.matched.to`       | Destination address (padded 32 bytes) | `0x0000000000000000000000005678901234567890123456789012345678901234` |
| `%tx.logs.matched.amount`   | Transfer amount (hex string)          | `0x2386f26fc10000`                                                   |

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

| Placeholder                 | Output Value                      | Example                                                              |
| --------------------------- | --------------------------------- | -------------------------------------------------------------------- |
| `%tx.logs.matched.contract` | Token contract address            | `0x6c3ea9...`                                                        |
| `%tx.logs.matched.owner`    | Owner address (padded 32 bytes)   | `0x0000000000000000000000001234567890123456789012345678901234567890` |
| `%tx.logs.matched.spender`  | Spender address (padded 32 bytes) | `0x0000000000000000000000005678901234567890123456789012345678901234` |
| `%tx.logs.matched.amount`   | Approval amount (hex string)      | `0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff` |

<Info>
  **When Available**: These placeholders are only populated when:

  * The rule condition uses `tx.logs.any(...)`
  * The condition matches (rule triggers)
  * The matched log is from `tx.logs`

  **Parsed Fields**: Fields like `from`, `to`, `amount`, `owner`, `spender`, and `contract` are automatically parsed and added to the log entry when Blocklight recognizes the event (Transfer or Approval). If the matched log is not a recognized event, these parsed fields will be empty strings.

  If no item matched or the condition doesn't use `tx.logs.any(...)`, all placeholders will be empty strings.
</Info>

## Format Details

* **`%tx.value`**: Raw wei value as string (e.g., `"1000000000000000000"`)
* **`%tx.value_eth`**: Formatted ETH value with 4 decimal places (e.g., `"1.0000"`)
* **`%tx.gas_price`**: Raw gas price in wei as string (e.g., `"100000000000"`)
* **`%tx.gas_price_gwei`**: Formatted gas price in gwei with 2 decimal places (e.g., `"100.00"`)
* **`%tx.timestamp`**: RFC3339 formatted timestamp (e.g., `"2024-01-15T10:30:00Z"`)
* **`%tx.timestamp_unix`**: Unix timestamp in seconds (e.g., `"1705312200"`)
* **`%tx.block.number`**: Block number (same syntax as in conditions: `tx.block.number`)
* **`%tx.block.timestamp`**: Block timestamp in Unix seconds (same syntax as in conditions: `tx.block.timestamp`)
* **Numeric fields**: All converted to strings (e.g., `%tx.nonce` → `"952"`)
* **Address fields**: Full address in hex format (e.g., `%tx.from` → `"0x2fb074..."`)

<Info>
  **Consistency:** Placeholders use the same syntax as conditions. For example:

  * Condition: `tx.block.number > 18000000`
  * Placeholder: `%tx.block.number`

  This ensures that any field you can use in a condition can also be used as a placeholder in the output.
</Info>

## Example Usage

### Basic Transaction Information

```yaml theme={null}
- rule: High Value Transfer
  desc: Detects large ETH transfers
  tags: ["high-value"]
  condition: tx.value > 100 ether
  output: >
    Large transfer detected!
    From: %tx.from
    To: %tx.to
    Amount: %tx.value_eth ETH
    TX: %tx.hash
    Block: %tx.block.number (%tx.block_hash)
    Gas: %tx.gas_used / %tx.gas
    Chain: %tx.chain
    Time: %tx.timestamp
  priority: WARNING
  enabled: true
```

### Using Matched Log Placeholders

```yaml theme={null}
- rule: Transfer Event Detected
  desc: Detects Transfer events in transaction logs
  tags: ["events", "erc20"]
  condition: tx.logs.any(event_name == "Transfer")
  output: >
    Transfer event detected!
    Event: %tx.logs.matched.event_name
    Contract: %tx.logs.matched.address
    Signature: %tx.logs.matched.event_signature
    Log Index: %tx.logs.matched.log_index
    TX: %tx.hash
  priority: NOTICE
  enabled: true
```

### Using Parsed Transfer Fields

```yaml theme={null}
- rule: High Value ERC-20 Transfer
  desc: Detects large ERC-20 token transfers
  tags: ["erc20", "high-value"]
  condition: >
    tx.logs.any(event_name == "Transfer" and to == "0x0000000000000000000000001234567890123456789012345678901234567890")
  output: >
    High value transfer detected!
    Event: %tx.logs.matched.event_name
    Contract: %tx.logs.matched.contract
    From: %tx.logs.matched.from
    To: %tx.logs.matched.to
    Amount: %tx.logs.matched.amount
    TX: %tx.hash
  priority: WARNING
  enabled: true
```

### Using Parsed Approval Fields

```yaml theme={null}
- rule: Unlimited Approval Detected
  desc: Detects unlimited token approvals
  tags: ["erc20", "approval", "security"]
  condition: >
    tx.logs.any(event_name == "Approval" and amount == "0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")
  output: >
    Unlimited approval detected!
    Event: %tx.logs.matched.event_name
    Contract: %tx.logs.matched.contract
    Owner: %tx.logs.matched.owner
    Spender: %tx.logs.matched.spender
    Amount: %tx.logs.matched.amount (unlimited)
    TX: %tx.hash
  priority: WARNING
  enabled: true
```

### Using Function Name and Category Placeholders

```yaml theme={null}
- rule: ERC-20 Transfer Function
  desc: Detects ERC-20 transfer() function calls
  tags: ["erc20", "function"]
  condition: tx.function_name == "transfer(address,uint256)"
  output: >
    Transfer function called!
    Function: %tx.function_name
    Category: %tx.function_category
    Selector: %tx.function_selector
    From: %tx.from
    To: %tx.to
    TX: %tx.hash
  priority: NOTICE
  enabled: true
```

### Using Function Category Placeholders

```yaml theme={null}
- rule: Any Transfer Function
  desc: Detects any transfer-related function call
  tags: ["function", "transfer"]
  condition: tx.function_category == "Transfer"
  output: >
    Transfer function category detected!
    Function: %tx.function_name
    Category: %tx.function_category
    Selector: %tx.function_selector
    From: %tx.from
    To: %tx.to
    TX: %tx.hash
  priority: NOTICE
  enabled: true
```

### Using Event Category Placeholders

```yaml theme={null}
- rule: Transfer Event Category
  desc: Detects any Transfer category event
  tags: ["events", "transfer"]
  condition: tx.logs.any(event_category == "Transfer")
  output: >
    Transfer event category detected!
    Event: %tx.logs.matched.event_name
    Category: %tx.logs.matched.event_category
    Contract: %tx.logs.matched.contract
    From: %tx.logs.matched.from
    To: %tx.logs.matched.to
    TX: %tx.hash
  priority: NOTICE
  enabled: true
```

### Using Swap Event Category Placeholders

```yaml theme={null}
- rule: Swap Event Category
  desc: Detects any Swap category event
  tags: ["events", "swap", "defi"]
  condition: tx.logs.any(event_category == "Swap")
  output: >
    Swap event category detected!
    Event: %tx.logs.matched.event_name
    Category: %tx.logs.matched.event_category
    Contract: %tx.logs.matched.address
    Signature: %tx.logs.matched.event_signature
    TX: %tx.hash
  priority: NOTICE
  enabled: true
```

## Best Practices

1. **Use `%tx.value_eth` for human-readable amounts** instead of `%tx.value` (which shows raw wei)
2. **Include transaction hash** (`%tx.hash`) for easy lookup on block explorers
3. **Format consistently** - numeric placeholders are already formatted, don't add extra formatting

## Next Steps

<CardGroup cols={2}>
  <Card title="Fields" icon="file-lines" href="/rules/fields">
    Learn about transaction fields available in conditions
  </Card>

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

  <Card title="Structure" icon="pen-to-square" href="/rules/structure">
    Learn about rule structure
  </Card>

  <Card title="Test Rules" icon="flask" href="/cli/dryrun">
    Test your rules with `blocklight dry-run`
  </Card>
</CardGroup>
