The Zcash tx-tool is designed to create and send Zcash transactions to a node (e.g., Zebra). It currently supports transaction versions V5 and V6, including the Orchard ZSA (Zcash Shielded Assets) functionality.
This repository includes a simple Zebra Docker image that incorporates the OrchardZSA version of Zebra and runs in regtest mode.
WARNING: This tool is not a wallet and should not be used as a wallet. This tool is in the early stages of development and should not be used in production environments.
- Features
- Core Components
- Prerequisites
- Getting Started
- Configuration
- Build Instructions
- Test Scenarios
- Block Data Storage
- Block Data Storage Considerations
- Running the tx-tool in Docker
- Connecting to the Public ZSA Testnet
- License
- Acknowledgements
- Transaction Creation: Craft custom Zcash transactions.
- Transaction Submission: Send transactions to a Zcash node.
- ZSA Support: Work with Zcash Shielded Assets (Orchard ZSA).
- Version Compatibility: Supports transaction versions V5 and V6.
- Tested on Ubuntu 22.04 LTS but should work on any Linux distribution that support the Prerequisites.
- Alpha - Everything, including APIs and data structures, is subject to breaking changes. Feature set is incomplete.
- librustzcash: Used for transaction creation and serialization. This version includes slight modifications for additional functionality.
- Diesel ORM Framework: A safe and extensible ORM and query builder for Rust.
- Abscissa Framework: A microframework for building Rust applications.
- Docker: Install Docker
- Rust & Cargo: Install Rust and Cargo
- Diesel CLI: Installed via Cargo.
- Linux Dev tools:
sudo apt update
sudo apt install pkg-config libssl-dev libsqlite3-dev Open a terminal and execute the following commands:
# Clone the zebra repository with the ZSA integration branch
git clone -b zsa-integration-demo --single-branch --depth=1 https://github.com/QED-it/zebra.git
# Navigate to the Zebra directory
cd zebra
# Build the Zebra Docker image
docker build -t qedit/zebra-regtest-txv6 -f testnet-single-node-deploy/dockerfile .
# Run the Zebra Docker container
docker run -p 18232:18232 qedit/zebra-regtest-txv6For more details on how the Docker image is created and synchronized, refer to the Dockerfile in the zebra repository.
In a separate terminal window, perform the following steps:
Install Diesel CLI and set up the database and get Zcash Params for Sapling:
# Install Diesel CLI with SQLite support
cargo install diesel_cli --no-default-features --features sqlite
# Set up the database (Diesel CLI requires DATABASE_URL)
DATABASE_URL=walletdb.sqlite diesel setup
# Get Zcash Params for Sapling (if needed)
./zcutil/fetch-params.shThe application uses the same default as above: if DATABASE_URL is not set at runtime, it connects to walletdb.sqlite.
There are multiple test scenarios provided in the repository, viz.
test-orchard-zsa(The detailed script for the flow is at test_orchard_zsa.rs.)test-three-party(The detailed script for the flow is at test_three_party.rs.)test-orchard(The detailed script for the flow is at test_orchard.rs.)test-issue-one(The detailed script for the flow is at test_issue_one.rs.)
Build and run the test case of your choice using the Zcash Transaction Tool, by replacing <test-case> in the command below with either of the test scenarios listed above:
# Build and run with ZSA feature enabled
cargo run --release --package zcash_tx_tool --bin zcash_tx_tool <test-case>For example, to run the test-orchard-zsa scenario, use:
cargo run --release --package zcash_tx_tool --bin zcash_tx_tool test-orchard-zsaNote: To re-run the test scenario (or to run a different scenario), reset the Zebra node by stopping and restarting the Zebra Docker container.
You can specify the path to the configuration file using the --config flag when running the application. The default configuration file name is config.toml.
An example configuration file with default values is provided in regtest_config.toml.
To set up the Diesel database:
-
Install Diesel CLI:
cargo install diesel_cli --no-default-features --features sqlite
-
Set Up the Database:
DATABASE_URL=walletdb.sqlite diesel setup
To build the application:
# Debug build
cargo build
# Release build (recommended for performance)
cargo build --releaseTo test ZSA functionality with the tool, enable the corresponding feature flag:
cargo build --releaseWe describe here
This test scenario (src/commands/test_orchard_zsa.rs) is a two-party setting which performs the following steps:
- Issue an Asset: Create and issue a new ZSA.
- Transfer the Asset: Send the issued asset to another account.
- Burn the Asset (Twice): Burn the asset in two separate transactions.
To run the test scenario:
cargo run --release --package zcash_tx_tool --bin zcash_tx_tool test-orchard-zsaThis test scenario (src/commands/test_three_party.rs) is a three-party setting which performs the following steps:
- Issue an Asset: Create and issue a new ZSA.
- Transfer the Asset (Twice): Send the issued ZSA to another account, and then from that account to a third account.
- Burn the Asset: The third account burns the ZSA.
To run the test scenario:
cargo run --release --package zcash_tx_tool --bin zcash_tx_tool test-three-partyThis test scenario (src/commands/test_issue_one.rs) is a minimal test that performs only the asset issuance step:
- Issue an Asset: Create and issue a single ZSA asset (1 unit).
This simplified scenario is useful for quick testing of the asset issuance functionality without the complexity of transfers and burns.
To run the test scenario:
cargo run --release --package zcash_tx_tool --bin zcash_tx_tool test-issue-oneIt is also possible to construct your own scenario in a manner similar to these. To do so, copy one of the test scenario files to a new file in the same location and make the changes to fit your setting.
To allow this new file to be run, make the following changes to commands.rs:
- Add the module corresponding to your new file to the start of commands.rs.
- Add an analogous new variant to the
AppCmdenum.
You should then be able to run your scenario via (assuming test-scenario is the name of your scenario):
cargo run --release --package zcash_tx_tool --bin zcash_tx_tool test-scenarioThe tx-tool records block hashes locally so later runs can validate the stored chain head and detect chain reorganizations.
The block data storage stores:
- Block hashes: For chain validation and reorg detection
- Wallet tree state: The note commitment tree and last synced block
On subsequent runs, the tool:
- Validates the stored chain matches the node's chain
- Resumes sync from the persisted wallet head when wallet state is consistent with
block_data - Uses preserved block hashes to validate rescans after
reset() - On any chain reorganization (or wallet/block-data inconsistency), wipes all persisted state (
block_data,wallet_state, notes, commitment tree) and resyncs from scratch — there is no per-block rollback or partial rewind
Note: Wallet::reset (and the clean subcommand) wipes everything: block_data, wallet_state, notes, and the in-memory tree. Subsequent runs auto-load any persisted wallet_state row and resume sync from wallet_head + 1, with no full re-sync.
The tx-tool stores two pieces of state on disk:
block_datatable: one row per synced block (height+ hex-encoded 32-bytehash). Each row is ~100 bytes including SQLite overhead, independent of the block's transaction size. Storage scales linearly with block count.wallet_statetable: a single row holding the serialized commitment tree, last synced height, and last synced hash. Size scales withO(N * log(T / N)), whereNis the number of wallet notes andTis the total chain commitments.
There are currently (January 2026) ~3.2M blocks on Zcash mainnet. Approximate totals at that scale:
block_data: ~100 bytes per block × 3.2M ≈ ~300 MB on mainnet (< 1 MB on regtest / ZSA testnet).wallet_state: ~2 MB for 1K notes / 5M commitments on mainnet (a few KB on regtest / ZSA testnet).
Notes:
block_datastorage is bounded by block count, not block size, so heavy mainnet blocks don't make it any larger.wallet_stateis rewritten in-place on each sync step, so it does not grow with sync time, only with wallet activity.- Disk usage grows over time on mainnet unless old
block_datarows are pruned (not implemented yet).
The tx-tool is normally built and run natively, as described above. A Docker workflow is also supported for CI and self-contained deployments. See docs/tx_tool_docker_setup.md for the build, persistence-volume layout, and a host-network example, plus a pointer to the multi-container recipe in .github/workflows/zebra-test-ci.yaml.
For instructions on connecting to the public ZSA testnet (including available endpoints, environment variables, and example usage), see the Running tx‑tool wiki page.
This project is licensed under the MIT License. See the LICENSE file for details.
- Zcash: The privacy-protecting digital currency.
- Zebra: An independent Zcash node implementation.
- librustzcash: The Rust library underpinning Zcash.
- Diesel ORM Framework: For database interactions.
- Abscissa Framework: For application structure.
Feel free to contribute to this project by opening issues or submitting pull requests.