Privacy Tools Guide

Bitcoin’s pseudonymous nature provides a layer of privacy, but that pseudonymity can be broken through blockchain analysis. One particularly effective technique for deanonymization is the dust attack — a method that exploits the traceability of Bitcoin’s UTXO model to link addresses and identify wallet owners. This guide explains how dust attacks work, how to detect them, and what you can do to protect your privacy.

What Is a Dust Attack?

A dust attack involves sending tiny amounts of Bitcoin — often just a few satoshis (the smallest unit of Bitcoin, 1 BTC = 100,000,000 satoshis) — to a large number of addresses. These amounts are small enough to be practically useless for spending, but large enough to create traceable links on the blockchain.

The attacker’s goal is not to steal these dust amounts. Instead, they rely on the fact that most wallet software will automatically consolidate dust UTXOs with larger transactions when users spend from their wallets. This behavior creates a chain of on-chain connections that blockchain analysis firms can exploit to cluster addresses and potentially identify the wallet owner.

How Dust Attacks Deanonymize Wallets

Bitcoin’s UTXO (Unspent Transaction Output) model means every transaction consumes previous outputs and creates new ones. When you spend Bitcoin, your wallet typically selects multiple UTXOs to fund the transaction. Here’s where privacy breaks down:

  1. Address Clustering: When your wallet combines multiple UTXOs in a single transaction, it reveals that all those addresses belong to the same wallet. An attacker sending dust to dozens of addresses you control creates multiple “breadcrumb” UTXOs waiting to be consolidated.

  2. Common Input Ownership Heuristic: Blockchain analysts use the assumption that if multiple inputs are signed in one transaction, they all belong to the same entity. Dust attacks exploit this by creating scenarios where you’ll eventually combine the dust with your main holdings.

  3. Change Address Detection: Modern analysis tools are sophisticated enough to identify change addresses (the address receiving the remainder of spent funds). When dust UTXOs appear as inputs alongside your main UTXOs, the analysis becomes trivial.

A practical example illustrates this:

# This is what happens when dust gets consolidated
# Transaction that reveals address ownership

# Inputs (UTXOs being spent):
# - 0.5 BTC from address 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa (your main address)
# - 0.00001 BTC from address 3分散注意力Dust7f5 (dust attack address)

# When you create this transaction, you just revealed
# that both addresses belong to you!

Detecting Dust Attacks

If you monitor your Bitcoin addresses, you can detect incoming dust transactions. Here’s a Python example using the bitcoinlib library:

from bitcoinlib.wallet import Wallet
from bitcoinlib.services.bitcoind import BitcoindClient

def check_for_dust(addresses, dust_threshold_satoshis=1000):
    """
    Check if any addresses have received dust amounts.

    Args:
        addresses: List of Bitcoin addresses to monitor
        dust_threshold_satoshis: Amount below which is considered dust

    Returns:
        List of tuples: (address, dust_amount_satoshis, txid)
    """
    client = BitcoindClient()
    dust_utxos = []

    for address in addresses:
        try:
            utxos = client.getutxos(address)
            for utxo in utxos:
                amount_sats = int(utxo['value'] * 100000000)
                if amount_sats <= dust_threshold_satoshis:
                    dust_utxos.append((
                        address,
                        amount_sats,
                        utxo['txid']
                    ))
        except Exception as e:
            print(f"Error checking {address}: {e}")

    return dust_utxos

# Example usage
my_addresses = [
    'bc1qxy2kgdygjrsqtzq2n0yrf2493p83kkfjhx0wlh',
    'bc1qw508d6qejxtdg4y5r3zarvary0c5xw7kv8f3t4'
]

dust_found = check_for_dust(my_addresses)
if dust_found:
    print(f"WARNING: Dust detected!")
    for addr, amount, txid in dust_found:
        print(f"  {addr}: {amount} sats (tx: {txid})")

For a more lightweight approach, you can use block explorers’ APIs:

import requests

def check_dust_with_blockstream(address):
    """Check address for small UTXOs using Blockstream API"""
    url = f"https://blockstream.info/api/address/{address}/utxo"
    response = requests.get(url, timeout=10)

    if response.status_code != 200:
        return []

    utxos = response.json()
    dust = []

    for utxo in utxos:
        # Less than 300 sats is almost certainly dust
        if utxo['value'] < 300:
            dust.append({
                'txid': utxo['txid'],
                'vout': utxo['vout'],
                'satoshis': utxo['value']
            })

    return dust

# Check for dust
result = check_dust_with_blockstream('your-address-here')
print(f"Found {len(result)} dust UTXOs")

Mitigation Strategies

1. Don’t Spend Dust Automatically

Configure your wallet to avoid automatically spending small UTXOs. Most wallets have an option to exclude small amounts from transactions:

# Example: Configure Electrum to not automatically spend small UTXOs
# In electrum.conf:
dust_threshold: 5460

The threshold of 5460 satoshis is significant because it’s slightly above Bitcoin’s dust limit (the minimum amount that can be sent in a standard transaction).

2. Use Coin Control Features

When creating transactions, use coin control to explicitly select which UTXOs to spend:

# Example: Explicit UTXO selection with Bitcoin Core
# bitcoin-cli command to list UTXOs first
import subprocess

def list_utxos(wallet_name):
    result = subprocess.run(
        ['bitcoin-cli', '-wallet', wallet_name, 'listunspent', '0', '9999999'],
        capture_output=True, text=True
    )
    import json
    utxos = json.loads(result.stdout)

    # Filter out small UTXOs
    return [u for u in utxos if u['amount'] * 1e8 > 5460]

3. Create Dedicated Dust Addresses

If you receive dust, consider creating a separate “burn” address that you never use with your main wallet. Send dust there manually if you need to consolidate, or simply leave it untouched.

4. Use Privacy-Enhanced Wallets

Wallets like Samourai, Whirlpool, or Wasabi implement CoinJoin and other privacy techniques that can break the link between your addresses. Wasabi Wallet specifically includes dust attack protection by warning users about small UTXOs.

5. Run Your Own Full Node

Using your own Bitcoin full node gives you complete control over transaction construction without leaking data to third-party servers:

# Bitcoin Core configuration for privacy
# Add to bitcoin.conf:
par=1
onlynet=onion
proxy=127.0.0.1:9050

6. Consider the Lightning Network

For frequent small transactions, Lightning Network payments don’t appear on the main blockchain, providing better privacy. Dust attacks on-chain become irrelevant for LN payments.

When Dust Attacks Matter Most

Dust attacks are particularly concerning in these scenarios:

Built by theluckystrike — More at zovo.one