Zebra Shielded Scanning
The zebra-scanner
binary is a standalone application that utilizes Zebra libraries to scan for transactions associated with specific Sapling viewing keys. It stores the discovered transactions and scanning progress data in a RocksDB database.
For this application to function, it requires access to a Zebra node's RPC server and state cache.
For now, we only support Sapling, and only store transaction IDs in the scanner results database.
Ongoing development is tracked in issue #7728.
Important Security Warning
Zebra's shielded scanning feature has known security issues. It is for experimental use only.
Do not use regular or sensitive viewing keys with Zebra's experimental scanning feature. Do not use this feature on a shared machine. We suggest generating new keys for experimental use or using publicly known keys.
Build & Install
Use Zebra 1.9.0 or greater, or the main
branch to get the latest features.
You can also use Rust's cargo
to install zebra-scanner
from the latest release Zebra repository:
cargo install --locked --git https://github.com/ZcashFoundation/zebra zebra-scan
The scanner binary will be at ~/.cargo/bin/zebra-scanner
, which should be in your PATH
.
Arguments
Retrieve the binary arguments with:
zebra-scanner --help
Scanning the Block Chain
Before starting, ensure a zebrad
node is running locally with the RPC endpoint open. Refer to the lightwalletd zebrad setup or zebrad mining setup for instructions.
To initiate the scanning process, you need the following:
- A zebrad cache state directory. This can be obtained from the running zebrad configuration file, under the
state
section in thecache_dir
field. - A key to scan with, optionally including a birthday height, which specifies the starting height for the scanning process for that key.
- A zebrad RPC endpoint address. This can be found in the running zebrad configuration file, under the
rpc
section in thelisten_addr
field.
Sapling diversifiable/extended full viewing keys strings start with zxviews
as
described in
ZIP-32.
For example, to scan the block chain with the public ZECpages viewing key, use:
RUST_LOG=info zebra-scanner --sapling-keys-to-scan '{"key":"zxviews1q0duytgcqqqqpqre26wkl45gvwwwd706xw608hucmvfalr759ejwf7qshjf5r9aa7323zulvz6plhttp5mltqcgs9t039cx2d09mgq05ts63n8u35hyv6h9nc9ctqqtue2u7cer2mqegunuulq2luhq3ywjcz35yyljewa4mgkgjzyfwh6fr6jd0dzd44ghk0nxdv2hnv4j5nxfwv24rwdmgllhe0p8568sgqt9ckt02v2kxf5ahtql6s0ltjpkckw8gtymxtxuu9gcr0swvz", "birthday_height": 419200}' --zebrad-cache-dir /media/alfredo/stuff/chain/zebra --zebra-rpc-listen-addr '127.0.0.1:8232'
- A birthday lower than the Sapling activation height defaults to Sapling activation height.
- A birthday greater or equal than Sapling activation height will start scanning at provided height, improving scanner speed.
The scanning process begins once Zebra syncs its state past the Sapling activation height. Scanning a synced state takes between 12 and 24 hours. The scanner searches for transactions containing Sapling notes with outputs decryptable by the provided viewing keys.
You will see log messages in the output every 10,000 blocks scanned, similar to:
...
2024-07-13T16:07:47.944309Z INFO zebra_scan::service::scan_task::scan: Scanning the blockchain for key 0, started at block 571001, now at block 580000, current tip 2556979
2024-07-13T16:08:07.811013Z INFO zebra_scan::service::scan_task::scan: Scanning the blockchain for key 0, started at block 571001, now at block 590000, current tip 2556979
...
If your Zebra instance goes down for any reason, the Zebra scanner will resume the task. Upon a new start, Zebra will display:
2024-07-13T16:07:17.700073Z INFO zebra_scan::storage::db: Last scanned height for key number 0 is 590000, resuming at 590001
2024-07-13T16:07:17.706727Z INFO zebra_scan::service::scan_task::scan: got min scan height start_height=Height(590000)
Displaying Scanning Results
An easy way to query the results is to use the Scanning Results Reader.
Querying Raw Scanning Results
A more advanced way to query results is to use ldb
tool, requires a certain level of expertise.
Install ldb
:
sudo apt install rocksdb-tools
Run ldb
with the scanner database:
ldb --db="$HOME/.cache/zebra/private-scan/v1/mainnet" --secondary_path= --column_family=sapling_tx_ids --hex scan
Some of the output will be markers the scanner uses to keep track of progress, however, some of them will be transactions found.
To learn more about how to filter the database please refer to RocksDB Administration and Data Access Tool