Introducing Blockchain Scanning with Zebra

Zcash Viewing Keys

When a Zcash user creates a shielded transaction, they encrypt it to the recipient’s address. Being able to access the data hidden behind the encryption is a necessary condition for the recipient to spend the funds, but it’s not sufficient since the recipient also needs to prove ownership of the spending key corresponding to the address. To decrypt the shielded transaction, the recipient uses a so-called viewing key, which they derive from their spending key. A viewing key allows decryption of the shielded data but reveals nothing about the spending key, effectively allowing “viewing” of shielded transactions but not spending of them.

Blockchain Scanning with Zebra

All Zcash users use their viewing keys to learn about what transactions belong to them. They try to decrypt each transaction in the blockchain to see if they can unlock the shielded data. We refer to this process as scanning or trial decryption. Light clients can perform the scanning locally so that the public server they communicate with doesn’t learn anything about their transactions. However, some users operate their own infrastructure. These are typically enterprise users, such as exchanges, which are best served using a scanning service closely linked to their full node.

At Zcon4, the Electric Coin Company and Zcash Foundation agreed to move the Zcash ecosystem to Zebra. To be able to do so, Zebra needs to support wallets capable of replacing the wallet in zcashd. As a first step toward this goal, we decided to extend Zebra with a blockchain scanner that accepts viewing keys and performs the trial decryption of shielded transactions. The scanner then stores the results in persistent storage. This functionality should allow for an efficient implementation of wallets relying on Zebra.

Implementation Details

The current scanner is a new crate in the Zebra repository, in the form of a minimum viable product. It relies on the librustzcash library to perform the scanning, and supports only Sapling. It reads all blocks through Zebra’s internal state service and stores the TXIDs, referring to transactions that contain notes decryptable by the provided viewing keys. The storage is a separate instance of RocksDB that Zebra also uses for storing the state.

The current version of the scanner is documented for users in our Zebra book. If you want to give it a try, you can use this tool to read the scanning results. If you submit the scanning key from ZECpages, it will print all posts from the board to standard output. The next step for the scanner is to implement a gRPC frontend, exposing the scanner’s capabilities to Zebra users.

If you have any feedback or suggestions, let us know in our Discord, or on the Zcash Community Forum.