zsWalletTxJSON (z_listsentbyaddress, z_listreceivedaddress, getalldata) runs once per wallet tx under LOCK2(cs_main, cs_wallet). For every shielded output it copied the wallet's address set, and for each address fetched the spending key, re-derived its full viewing key (an elliptic-curve operation), and trial-decrypted the output; the sends side did the same with the ovk. Every received or sent note in a tx with spends walked the whole wallet in GetNullifiersForAddresses for the change check. The spends side decrypted every spent note again and deep-copied its SaplingNoteData (witnesses included). The GUI runs z_listsentbyaddress over the whole wallet on every launch. SaplingHistoryKeys, built once per RPC call, holds each address with a usable spending key (in GetSaplingPaymentAddresses order, with its ivk and ovk as the spending key gives them, and its ivk as GetSaplingIncomingViewingKey gives it). It also gives the change check as a lookup into the wallet's (ivk, nullifier) pairs, collected on first use. The helpers keep their exact structure and quirks. Each output's JSON object and change flag still accumulate across the addresses that decrypt it. Diversified addresses sharing a key still produce one entry each. An unknown address still checks change under a zero ivk. A locked wallet still reports no shielded received or sent entries. Only the repeated work is gone: - each output is decrypted at most once per distinct key. Once it is known which ivk decrypts an output, no other ivk is tried: the cached plaintext, or a decryption under the ivk the wallet's note data records. Two canonical ivks can't both pass the note commitment check, which pins pk_d = [ivk]g_d; - outCiphertexts are decrypted once per distinct ovk; the t->z shielding ovk is derived from the seed once per tx; - spends use the cached plaintext of the spent note. Two deliberate behaviour changes. The spends helper looked notes up with operator[]: it inserted a null-outpoint entry into mapSaplingNullifiersToNotes for every other wallet's nullifier it met. After getalldata or z_listsentbyaddress had run, z_viewtransaction of any tx spending someone else's note (every incoming z->z payment) failed with map::at. And with an inconsistent nullifier map, it inserted an empty note into a wallet tx. The helpers now only read the wallet. Also, if the walletpassphrase timer relocks the wallet during the call, the whole call reports the keys as of its start; the old per-output lookups switched over partway. test_wallet_history.cpp holds 69bb035e7's helpers verbatim (renamed) and a wallet exercising every branch: - default and diversified addresses, a viewing-key-only address, and a key imported after its note arrived; - z->z sends with change, and with text, empty and binary memos; - a send nobody's ovk reads, and a t->z shielding send; - our spends, someone else's, and a mixed tx. Every tx x every return type x nine address filters gives byte-identical JSON: with the plaintext cache warm, cold, and on an encrypted wallet both locked and unlocked. Mutation-checked: dropping the ivk check from the uniqueness shortcut fails the test. DoesNotModifyTheWallet pins the read-only change (and shows that the old helpers did insert the foreign nullifier). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
DragonX
A fully-private, RandomX CPU-mineable cryptocurrency.
| Introduction | Build | Run | Mine |
|---|---|---|---|
| What is DragonX? | Build from source | Run a node | CPU mining |
| Key facts | Install a release | Fastest sync | Wallets |
What is DragonX?
DragonX implements extreme privacy via blockchain technology. It is private from
genesis: every ordinary transaction is shielded (z2z), so your transaction metadata
stays private. DragonX is based on Bitcoin code with Zcash's zero-knowledge Sapling
cryptography, and its defining feature is RandomX Proof-of-Work — it is mined with a
CPU, not ASICs or GPUs.
DragonX has its own genesis block. Its lineage is Bitcoin → Zcash → Komodo → Hush → DragonX; it is a fork of the Hush full node, with the Proof-of-Work changed from Equihash to RandomX and privacy enforced from the very first block.
This software is the DragonX full node and command-line client. It downloads and stores the entire history of DragonX transactions; depending on your computer and network connection this can take a while, so most users start from the bootstrap snapshot.
DragonX is experimental software. Use at your own risk, just like Bitcoin.
Key facts
| Ticker | DRAGONX |
| Proof-of-Work | RandomX (CPU-mineable) |
| Privacy | fully private from genesis (ac_private=1, Sapling active at height 1) |
| Block time | 36 seconds |
| Block reward | 3 DRAGONX, halving every 3,500,000 blocks |
| Max block size | 4 MB |
| RPC port | 21769 |
| P2P port | 18030 |
| Data directory | ~/.hush/DRAGONX (Linux) |
| Config file | DRAGONX.conf |
| Binaries | dragonxd, dragonx-cli, dragonx-tx |
Fastest way to sync (bootstrap)
The quickest way to get a fully-synced node is the signed bootstrap snapshot, which installs a pre-built blockchain so you skip re-validating the whole chain from genesis:
# Stop dragonxd first if it is running, then:
./util/bootstrap-dragonx.sh
The script preserves your wallet.dat and DRAGONX.conf, verifies the download's
checksums and (once a release key is published) its cryptographic signature, then starts
you near the chain tip. If you prefer to sync from the network instead, a larger
-dbcache (e.g. -dbcache=2048) noticeably speeds up the initial block download.
Build from source
Building uses 3 build processes by default; you need ~2GB of RAM for each.
Debian or Ubuntu
sudo apt-get install build-essential pkg-config libc6-dev m4 g++-multilib \
autoconf libtool ncurses-dev unzip git zlib1g-dev wget \
bsdmainutils automake curl unzip nano libsodium-dev cmake
git clone https://git.dragonx.is/DragonX/dragonx
cd dragonx
./build.sh -j3
Arch
sudo pacman -S gcc libsodium lib32-zlib unzip wget git python rust curl autoconf cmake
git clone https://git.dragonx.is/DragonX/dragonx
cd dragonx
./build.sh -j3
Fedora
sudo dnf install make automake gcc gcc-c++ kernel-devel cmake libtool ncurses-devel patch -y
git clone https://git.dragonx.is/DragonX/dragonx
cd dragonx
./build.sh -j3
macOS
Install Xcode Command Line Tools and Homebrew, then:
xcode-select --install
brew install gcc autoconf automake pkgconf libtool cmake curl
# Install Rust (needed for librustzcash on macOS Sequoia+)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
source "$HOME/.cargo/env"
git clone https://git.dragonx.is/DragonX/dragonx
cd dragonx
# Make sure libtool gnubin and cargo are on PATH
export PATH="$HOME/.cargo/bin:/usr/local/opt/libtool/libexec/gnubin:$PATH"
./build.sh -j3
For a release build:
export PATH="$HOME/.cargo/bin:/usr/local/opt/libtool/libexec/gnubin:$PATH"
./build.sh --mac-release -j$(sysctl -n hw.ncpu)
Windows (cross-compiled on Linux)
sudo apt-get install \
build-essential pkg-config libc6-dev m4 g++-multilib libdb++-dev \
autoconf libtool ncurses-dev unzip git zip \
zlib1g-dev wget bsdmainutils automake mingw-w64 cmake libsodium-dev
git clone https://git.dragonx.is/DragonX/dragonx
cd dragonx
./util/build-win.sh -j$(nproc)
ARM (Raspberry Pi)
Any ARMv7 machine cannot build this repo because the underlying zk-SNARK library does not
support that instruction set. You need an ARMv8-based board (Raspberry Pi 4 or newer). Either
install an aarch64 release package (see below) or cross-compile from amd64.
Installing DragonX binaries
- Download a release with a
.debextension. - Install it, substituting the version you downloaded:
sudo dpkg -i dragonx-VERSION-amd64.deb(or-aarch64.debon ARM). - Run with:
dragonxd.
Running a node
Start the daemon:
./src/dragonxd
It stores data in ~/.hush/DRAGONX and reads ~/.hush/DRAGONX/DRAGONX.conf. Query it with
./src/dragonx-cli, for example:
./src/dragonx-cli getinfo
To run DragonX as a background service, see doc/dragonxd-systemd.md.
CPU mining (RandomX)
DragonX is CPU-mineable via RandomX (the same algorithm family as Monero); ASICs and GPUs do not apply. To mine with your node, enable generation and choose how many threads to use:
# mine with 4 CPU threads
./src/dragonxd -gen=1 -genproclimit=4
or add to DRAGONX.conf:
gen=1
genproclimit=4
Mining rewards arrive as transparent coinbase, which is directly spendable; you can optionally
move it into the shielded pool with z_shieldcoinbase (see
doc/shield-coinbase.md). For more on the algorithm and its tuning
options, see doc/randomx.md.
Wallets
The DragonX full node includes a built-in wallet, managed via dragonx-cli (see
doc/wallet-backup.md and doc/seed-phrase.md).
Graphical and mobile wallets:
- ObsidianDragon — desktop wallet, available in both full-node and light-wallet modes.
- SilentDragonXAndroid — wallet for Android devices.
DragonX light and mobile wallets use BIP39 seed phrases that are compatible with the full node — see doc/seed-phrase.md.
Support and links
- Website: https://dragonx.is
- Source code: https://git.dragonx.is/DragonX
- Block explorer: https://explorer.dragonx.is
- Issues / bounties: https://git.dragonx.is/DragonX/dragonx/issues
- Telegram: https://dragonx.is/tg
- Matrix: https://dragonx.is/matrix
- Twitter / X: https://twitter.com/DragonXchain
License
For license information see the file COPYING.
