Event scanning
Test predicates by scanning historical blockchain data.
Chainhook's scanning mode lets you test predicates against historical blockchain data before deploying them in production. This is essential for validating predicate logic and understanding what events will be captured.
Basic scanning
Scan the blockchain using a predicate file:
Terminal
$chainhook predicates scan my-predicate.json --mainnet[33mDownloading chain archive...[0m[32mScanning blocks 100000 to 150000[0m[32mFound 234 matching events[0m[32mResults written to output.json[0m
The scan command:
- 1Downloads blockchain data from Hiro Archive (first run only)
- 2Evaluates your predicate against each block
- 3Outputs matching events to the specified destination
Scan specific block ranges
Limit scanning to specific blocks for faster testing:
Terminal
$chainhook predicates scan my-predicate.json \--start-block 150000 \--end-block 150100 \--mainnet[32mScanning 100 blocks[0m[32mCompleted in 2.3s[0m
Network selection
Scan different networks using flags:
Terminal
$chainhook predicates scan predicate.json --mainnet$chainhook predicates scan predicate.json --testnet$chainhook predicates scan predicate.json --devnet
Output formats
File output
Write results to a file:
predicate-file-output.json
{"then_that": {"file_append": {"path": "./scan-results.json"}}}
Console output
Use -
for stdout:
predicate-console-output.json
{"then_that": {"file_append": {"path": "-"}}}
Scan performance
Optimize scanning speed with these techniques:
1. Use specific scopes
// Slower - scans all transactions{"if_this": {"scope": "txid"}}// Faster - only contract calls{"if_this": {"scope": "contract_call","contract_identifier": "SP2C2YFP12AJZB4MABJBAJ55XECVS7E4PMMZ89YZR.arkadiko-dao"}}
2. Set block boundaries
{"networks": {"mainnet": {"start_block": 150000,"end_block": 151000,"if_this": { ... }}}}
3. Limit occurrences
{"networks": {"mainnet": {"expire_after_occurrence": 100,"if_this": { ... }}}}
Debugging scans
Enable verbose output to debug predicate matching:
Terminal
$chainhook predicates scan my-predicate.json --mainnet --verbose[90mEvaluating block 150000 (0x3a4b5c...)[0m[90m Transaction 0x1a2b3c... - No match (wrong contract)[0m[32m Transaction 0x4d5e6f... - MATCH[0m[90mEvaluating block 150001 (0x7d8e9f...)[0m
Common scan scenarios
Find first occurrence
Locate when a contract was first called:
Terminal
$chainhook predicates scan find-first.json \--start-block 100000 \--mainnet
With predicate:
{"expire_after_occurrence": 1,"if_this": {"scope": "contract_deployment","contract_identifier": "SP2C2YFP12AJZB4MABJBAJ55XECVS7E4PMMZ89YZR.arkadiko-dao"}}
Collect all NFT mints
Gather all mint events for analysis:
nft-mints.json
{"if_this": {"scope": "nft_event","asset_identifier": "SP2C2YFP12AJZB4MABJBAJ55XECVS7E4PMMZ89YZR.bitcoin-monkeys::bitcoin-monkeys","actions": ["mint"]},"then_that": {"file_append": {"path": "./all-mints.json"}}}
Monitor specific address
Track all STX transfers for an address:
address-monitor.json
{"if_this": {"scope": "stx_event","actions": ["transfer"],"predicate": {"or": [{ "equals": { "sender": "SP2C2YFP12AJZB4MABJBAJ55XECVS7E4PMMZ89YZR" } },{ "equals": { "recipient": "SP2C2YFP12AJZB4MABJBAJ55XECVS7E4PMMZ89YZR" } }]}}}
Troubleshooting
Issue | Solution |
---|---|
Archive download failed | Check internet connection and disk space |
No events found | Verify block range contains expected activity |
Scan terminates early | Check expire_after_occurrence setting |
Memory issues | Reduce block range or output to file |