The Dusk Network
Learning Hub
Privacy-first regulated blockchain for real-world assets. A visual, developer-focused reference for the Dusk protocol — architecture, consensus, node operations, and smart contracts.
Protocol Architecture
A modular three-layer stack: settlement at the base, EVM and privacy execution on top, connected by a trustless native bridge.
- Canonical chain ordering & finality
- Succinct Attestation consensus (PoS)
- Phoenix + Moonlight transaction models
- Transfer & Stake genesis contracts
- Kadcast P2P networking (UDP 9000)
- Piecrust WASM VM (10× faster than predecessor)
- ZK-friendly host functions: PLONK, Groth16, BLS
- Rust contracts with
#[contract]macro - Delta-based state — only changes persisted
- Full EVM equivalence via OP Stack port
- Settles to DuskDS — no 7-day fault window
- Standard tooling: MetaMask, Hardhat, Foundry
- Chain IDs: 744 (mainnet), 745 (testnet)
- Trustless, no wrapped assets needed
- Single DUSK token across all three layers
- MIPS pre-verifier eliminates fraud proof delay
- ~15 min withdrawal finalization
Succinct Attestation
Dusk's PoS consensus delivers deterministic finality in three clean steps — essential for financial settlement applications.
- Minimum 1,000 DUSK to stake & participate
- 2-epoch maturity period (4,320 blocks) before earning
- Deterministic Sortition — no randomness oracle needed
- BLS signature aggregation for compact certificates
- Security: honest stake > 2/3 of total
- 1 epoch = 2,160 blocks
- 64 committee credits per round
- Max 50 iterations per round before timeout
- Block reward: ~19.86 DUSK/block (Period 1)
- Split: 70% proposer + up to 10% bonus / 5% validation / 5% ratification / 10% Dusk Dev Fund (unclaimed bonus burned)
Committee Selection Visualized
Phoenix & Moonlight
Dusk's dual transaction model — choose privacy or transparency per transaction. Unique in blockchain design.
Kadcast P2P Network
Structured UDP-based broadcast protocol using Kademlia DHT. O(log n) complexity vs gossip's unpredictable fan-out.
- Peer IDs: 128-bit Blake2b hash of IP+port
- XOR distance routing (Kademlia-style)
- k-buckets with LRU eviction + PING/PONG liveness
- β=3 delegates per bucket on broadcast
- Duplicate CHUNK messages are ignored (no storms)
- 25–50% bandwidth reduction vs gossip
- Predictable, lower latency
- Handles 12% UDP packet loss gracefully
- Sybil and Eclipse attack resistant by design
- Port: 9000/UDP — must be open inbound
DuskEVM
Full EVM equivalence via OP Stack, settling to DuskDS instead of Ethereum. Solidity contracts with no code changes. Integration time drops from months to ~2 weeks.
| Network | Chain ID |
|---|---|
| Mainnet | 744 |
| Testnet | 745 |
- COINBASE → sequencer fee wallet (not miner)
- PREVRANDAO → DuskDS beacon (not ETH beacon)
- tx.origin → aliased for cross-layer calls
- All other opcodes identical to standard EVM
module.exports = {
solidity: "0.8.24",
networks: {
duskEVM: {
url: "https://rpc.evm.dusk.network",
chainId: 744,
accounts: [process.env.PRIVATE_KEY],
},
},
};
Economic Protocol
How DUSK flows through the system — staking rewards, gas fees, autocontracts, and the transfer contract as financial middleware.
- Execute autonomously when triggered by on-chain events
- Useful for: trading strategies, automated transfers, rebalancing
- Contracts can pay gas on behalf of users (sponsor model)
- Enables subscription fee models vs traditional tx taxes
- Max supply: 1,000,000,000 DUSK
- 500M initial + 500M emitted over 36 years
- Halving every 4 years (Bitcoin-style)
- Period 1 ends ~2029 — highest emission now
Emission Schedule — 500M DUSK over 36 Years
| Period | Years | Emission | DUSK/Block |
|---|---|---|---|
| 1 | 0–4 | 250.48M | ~19.86 |
| 2 | 4–8 | 125.24M | ~9.93 |
| 3 | 8–12 | 62.62M | ~4.96 |
| 4 | 12–16 | 31.31M | ~2.48 |
| 5 | 16–20 | 15.65M | ~1.24 |
| 6 | 20–24 | 7.83M | ~0.62 |
| 7 | 24–28 | 3.91M | ~0.31 |
| 8 | 28–32 | 1.95M | ~0.16 |
| 9 | 32–36 | 0.98M | ~0.08 |
Dusk vs Ethereum
Ethereum is a general-purpose platform. Dusk is purpose-built for regulated finance. Not a fork — a ground-up redesign for the institutions that actually need compliance.
| Feature | Ethereum | Dusk |
|---|---|---|
| Consensus | Gasper (Casper FFG + LMD GHOST) | Succinct Attestation |
| Min Stake | 32 ETH | 1,000 DUSK |
| Block Time | 12s (targeting 2s by 2029) | ~10s DuskDS / ~2s DuskEVM |
| Finality | ~16 min (targeting 6-16s by 2029) | Deterministic via SA |
| Privacy | Public by default, privacy is multi-phase roadmap | Native — Phoenix (ZK UTXO) + Moonlight (transparent) |
| Transaction Model | Account-based only | Dual: Phoenix (UTXO/private) + Moonlight (account/public) |
| Smart Contracts | Solidity on EVM | Solidity on DuskEVM + Rust/WASM on DuskVM |
| ZK Proofs | L2 rollups only — L1 has none | Native PLONK at protocol level |
| MEV Protection | Transparent mempool → MEV extraction | Private execution — no surface to front-run |
| Compliance | No native compliance tooling | Citadel ZK-ID, NPEX licensed (MTF, ECSP, Broker) |
| Hardware | 32 ETH + execution + consensus clients | 2 cores, 4 GB RAM, 1,000 DUSK |
| P2P Network | Gossip (libp2p) | Kadcast — O(log n) structured broadcast |
Node Setup Guides
Three tracks: standard setup, separated key for security, or USB cold storage with LUKS encryption for maximum protection.
# Install Rusk (mainnet)
curl --proto '=https' --tlsv1.2 -sSfL \
https://github.com/dusk-network/node-installer/releases/latest/download/node-installer.sh \
| sudo bash
# Create wallet (save mnemonic securely!)
rusk-wallet create
# Export consensus key to correct location
rusk-wallet export -d /opt/dusk/conf -n consensus.keys
# Set consensus key password
sh /opt/dusk/bin/setup_consensus_pwd.sh
# Fast sync state, then start node
service rusk stop && download_state && service rusk start
# Monitor sync progress
tail -F /var/log/rusk.log | grep "block accepted"
# Check block height (compare with explorer)
ruskquery block-height
# Stake once synced (min 1000 DUSK)
rusk-wallet stake --amt 1000
# Verify stake
rusk-wallet stake-info
When you run
rusk-wallet stake --amt 1000 --owner <owner-address> from the node wallet, you're writing an on-chain record: "this node's consensus key earns rewards, but only the owner address can unstake or withdraw." The node wallet can only sign consensus messages — if the server is compromised, the attacker cannot move funds. The owner address (your cold/hardware wallet) is the sole key that can call unstake or withdraw. Think of it as: the node is a worker, the owner holds the paycheck.
# Create the OWNER wallet on a secure machine (offline preferred)
rusk-wallet create
# Note your owner address — you'll need it for the staking step
rusk-wallet addresses
# Example output: owner address = 27xyK9gR...a1Bk
# Install Rusk node
curl --proto '=https' --tlsv1.2 -sSfL \
https://github.com/dusk-network/node-installer/releases/latest/download/node-installer.sh \
| sudo bash
# Create a SEPARATE wallet on the node (different mnemonic!)
rusk-wallet create
# Export consensus key for the node to use
rusk-wallet export -d /opt/dusk/conf -n consensus.keys
sh /opt/dusk/bin/setup_consensus_pwd.sh
# Fast sync state, then start node
service rusk stop && download_state && service rusk start
# Wait for sync — check block height matches explorer
ruskquery block-height
# From the NODE machine, stake with the --owner flag
# Replace <owner-address> with the address from Step 1
rusk-wallet stake --amt 1000 --owner <owner-address>
# Verify stake and owner assignment
rusk-wallet stake-info
# You should see: owner = <owner-address> (NOT the node address)
# What this means:
# Node wallet → signs blocks, earns rewards
# Owner wallet → sole key that can unstake or withdraw
# Server hacked? → attacker CANNOT touch staked DUSK
This is the most secure owner key setup. The wallet is generated directly onto a LUKS-encrypted USB drive — the owner key never exists on any hard drive. Even if the USB is lost or stolen, the data is encrypted and unreadable without your passphrase. You only plug it in when you need to unstake or withdraw rewards.
# Insert USB drive and identify it (usually /dev/sdb or /dev/sdc)
lsblk
# IMPORTANT: Replace /dev/sdX with YOUR device — this ERASES the drive
# Install cryptsetup if not present
sudo apt update && sudo apt install -y cryptsetup
# Wipe and create a LUKS-encrypted partition
# You will be asked to set a strong passphrase — DO NOT FORGET IT
sudo cryptsetup luksFormat /dev/sdX1
# Open the encrypted partition (you'll enter the passphrase)
sudo cryptsetup open /dev/sdX1 dusk-cold
# Format the decrypted volume with ext4
sudo mkfs.ext4 /dev/mapper/dusk-cold
# Create a mount point and mount
sudo mkdir -p /mnt/dusk-cold
sudo mount /dev/mapper/dusk-cold /mnt/dusk-cold
# Set permissions so your user can write
sudo chown $(whoami):$(whoami) /mnt/dusk-cold
# Create the owner wallet DIRECTLY on the encrypted USB
# The -w flag tells rusk-wallet to use a custom directory
rusk-wallet create -w /mnt/dusk-cold/wallet
# Save your mnemonic phrase on paper (NOT digitally)
# This mnemonic + the USB are your only recovery paths
# Get the owner address — write this down, you need it for staking
rusk-wallet -w /mnt/dusk-cold/wallet addresses
# Example output: owner address = 27xyK9gR...a1Bk
# Verify the wallet files exist only on the USB
ls -la /mnt/dusk-cold/wallet/
# Should show .dat wallet files
# Unmount the drive
sudo umount /mnt/dusk-cold
# Close the LUKS encryption layer
sudo cryptsetup close dusk-cold
# Physically remove the USB drive
# Store it in a safe place (fireproof safe, safety deposit box, etc.)
# === ON NODE MACHINE (server/VPS) ===
# Install Rusk node
curl --proto '=https' --tlsv1.2 -sSfL \
https://github.com/dusk-network/node-installer/releases/latest/download/node-installer.sh \
| sudo bash
# Create a SEPARATE node wallet (different mnemonic from USB!)
rusk-wallet create
# Export consensus key
rusk-wallet export -d /opt/dusk/conf -n consensus.keys
sh /opt/dusk/bin/setup_consensus_pwd.sh
# Sync and start
service rusk stop && download_state && service rusk start
ruskquery block-height # Wait for sync
# Stake using the owner address from your USB wallet
# Replace <owner-address> with the address from Step 2
rusk-wallet stake --amt 1000 --owner <owner-address>
# Verify: owner should show the USB wallet address
rusk-wallet stake-info
# When you need to unstake or withdraw rewards:
# Insert the USB drive
sudo cryptsetup open /dev/sdX1 dusk-cold
sudo mount /dev/mapper/dusk-cold /mnt/dusk-cold
# Unstake or withdraw using the USB wallet
rusk-wallet -w /mnt/dusk-cold/wallet unstake
rusk-wallet -w /mnt/dusk-cold/wallet withdraw
# Close up when done
sudo umount /mnt/dusk-cold
sudo cryptsetup close dusk-cold
# Remove USB and store safely
lsblk confirms the correct device before formattingSmart Contract Development
Two parallel paths: Solidity on DuskEVM for EVM-standard contracts, or Rust/WASM on DuskVM for privacy-native contracts.
- Use Forge framework — #[contract] macro
- Target: wasm32-unknown-unknown
- State as ordinary Rust structs (no key-value store)
- Native ZK host functions: verify_plonk, verify_bls
- Deploy via rusk-wallet contract-deploy
- Standard Solidity 0.8.x — no modifications needed
- OpenZeppelin, ERC20/ERC721/ERC4626 all work
- T-REX (ERC-3643) security tokens deployed and live
- OnchainID (ERC734/ERC735) for KYC identity
- Verify contracts on Blockscout explorer
#![no_std]
#![cfg(target_family = "wasm")]
extern crate alloc;
use dusk_forge::contract;
#[contract]
mod counter {
use dusk_core::abi;
pub struct Counter { value: i64 }
impl Counter {
pub const fn new() -> Self { Self { value: 0 } }
pub fn read_value(&self) -> i64 { self.value }
pub fn increment(&mut self) {
self.value += 1;
abi::emit("incremented", self.value);
}
}
}
Wallet & Key Management
The rusk-wallet CLI manages DUSK, staking, smart contracts, and the Phoenix/Moonlight conversion in one tool.
| Command | What It Does |
|---|---|
| rusk-wallet create | Create a new wallet, generates 12-word mnemonic — back it up immediately |
| rusk-wallet restore | Restore from mnemonic — enter all words in lowercase |
| rusk-wallet balance | Show DUSK balance (all accounts) |
| rusk-wallet stake --amt 1000 | Stake 1,000 DUSK (minimum) |
| rusk-wallet stake-info | View current stake, maturity, rewards |
| rusk-wallet withdraw | Withdraw accumulated staking rewards |
| rusk-wallet unstake | Unstake — no waiting period, no penalty |
| rusk-wallet shield --amt 100 | Convert public (Moonlight) → shielded (Phoenix) |
| rusk-wallet unshield --amt 100 | Convert shielded (Phoenix) → public (Moonlight) |
| rusk-wallet export -d /opt/dusk/conf -n consensus.keys | Export consensus key to node directory |
| rusk-wallet contract-deploy --bytecode ./my.wasm | Deploy a smart contract to DuskVM |
Node Maintenance & Security
Keep your node healthy to avoid slashing. Dusk currently uses soft slashing only — stake is moved to claimable rewards, not burned.
- Triggered: missed block production (offline/slow)
- 1st offense: warning only, no stake loss
- 2nd+: N×10% moved to claimable rewards
- Suspended N epochs per consecutive fault
- Recoverable: withdraw and restake
- Faults reset on next reward earned
- Never run two nodes with the same consensus.keys
- Monitor block height against explorer.dusk.network
- Keep your node updated to the latest Rusk version
- Use sentry node architecture for DoS protection
- Set up log monitoring and alerting
# Service status
service rusk status
# Live block acceptance (healthy node shows frequent output)
tail -F /var/log/rusk.log | grep "block accepted"
# Current block height (compare with explorer.dusk.network)
ruskquery block-height
# Stake status
rusk-wallet stake-info
# Port check — 9000/UDP must be open
ss -ulnp | grep 9000
# Node stuck? Fast resync:
service rusk stop && download_state && service rusk restart
Ecosystem & Community Projects
Live projects, integrations, and developer tools built on or partnered with Dusk Network.
Resources & Links
Official documentation, GitHub repositories, block explorers, and community channels.