Skip to content
This repository has been archived by the owner on May 13, 2022. It is now read-only.

Step by step running the tumbler

chris-belcher edited this page Aug 21, 2015 · 37 revisions

Tumbler is a JoinMarket bot which attempts to completely break the link between addresses. It is used to restore privacy where it has been damaged. It creates many many coinjoins to bounce coins around in different amounts and times.

Examples of users might be people who bought bitcoins with a very privacy-invading method, such buying from an exchange, and wish to have privacy in all their purchases again. Some bitcoin users also just need it as a simple medium of exchange, buying bitcoins with traceable fiat and immediately spending them on goods and services. Example would be an anonymous buyer of a domain name, VPS hosting, email or VPN provisions. Users also might be those who engage in capital flight or want to store bitcoins without anyone knowing, tumbling them into cold storage.

Quick simple tumbling

First create a wallet and send bitcoins to the zeroth mixing depth.

You will need two or more addresses of your destination. If you use just one address, your enemy could see X amount of bitcoins going in and then just search for an output of similar size to X. Using two or more addresses means you can split up payments into different sizes which together add up to X. The tumbler.py application can be made to ask you for a new address just before it needs to send, giving you the chance to click Generate New Address on whatever service you're using and copypaste it in. (Beware: Some services like Bitstamp only allow one new address every 24 hours)

Warning: This step is very important. You CANNOT use just a single address and expect good privacy.

Run tumbler.py with your wallet file and at least one address.

It will print out an estimate of the time taken,

waits in total for 19 blocks and 35.96 minutes
estimated time taken 225.96 minutes or 3.77 hours
tumble with these tx? (y/n):

Type 'y' if you're happy to tumble. Bot will then connect to the JoinMarket pit and start doing transactions.

When tumbler.py needs another destination address, it will ask for a new address.

insert new address: 1JPFmg1RSa2gtzcsow9fBjwdvWPsxcP3eX

Come back later when the bot has finished.

Transaction List

Tumbler will print out a list of transactions it intends to do, carefully look through them to check. It also gives you an idea of the time taken.

tumbler transaction list
[{'srcmixdepth': 0,
  'tx': [{'amount_fraction': 0.16690761108397631,
	  'destination': 'internal',
	  'makercount': 3,
	  'wait': 0.6},
	 {'amount_fraction': 0.20858522879638042,
	  'destination': 'internal',
	  'makercount': 2,
	  'wait': 0.24},
	 {'amount_fraction': 0.1228094525360878,
	  'destination': 'internal',
	  'makercount': 2,
	  'wait': 1.82},
	 {'amount_fraction': 0.37165574977649202,
	  'destination': 'internal',
	  'makercount': 2,
	  'wait': 0.11},
	 {'amount_fraction': 0.13004195780706343,
	  'destination': 'internal',
	  'makercount': 3,
	  'wait': 2.01}]},
 {'srcmixdepth': 1,
  'tx': [{'amount_fraction': 0.17961951168167614,
	  'destination': 'internal',
	  'makercount': 3,
	  'wait': 1.25},
	 {'amount_fraction': 0.34597908520497495,
	  'destination': 'internal',
	  'makercount': 4,
	  'wait': 2.56},
	 {'amount_fraction': 0.18015480070784087,
	  'destination': 'internal',
	  'makercount': 2,
	  'wait': 2.31},
	 {'amount_fraction': 0.18923022116479027,
	  'destination': 'internal',
	  'makercount': 2,
	  'wait': 0.28},
	 {'amount_fraction': 0.10501638124071778,
	  'destination': 'mprGzBA9rQk82Ly41TsmpQGa8UPpZb2w8c',
	  'makercount': 3,
	  'wait': 1.25}]},
 {'srcmixdepth': 2,
  'tx': [{'amount_fraction': 0.19808511069342036,
	  'destination': 'internal',
	  'makercount': 2,
	  'wait': 0.03},
	 {'amount_fraction': 0.29131168887009173,
	  'destination': 'internal',
	  'makercount': 3,
	  'wait': 0.07},
	 {'amount_fraction': 0.037847453584973274,
	  'destination': 'internal',
	  'makercount': 3,
	  'wait': 0.39},
	 {'amount_fraction': 0.47275574685151467,
	  'destination': 'addrask',
	  'makercount': 3,
	  'wait': 0.45}]},
 {'srcmixdepth': 3,
  'tx': [{'amount_fraction': 1.0,
	  'destination': 'addrask',
	  'makercount': 3,
	  'wait': 1.71}]}]
waits in total for 15 blocks and 15.08 minutes
estimated time taken 165.08 minutes or 2.75 hours

An explaination of some of the labels.

  • srcmixdepth The source mix depth. The mix depth in the internal wallet from where the coins will be spent from. The change address will stay in the same mix depth, the coinjoin address will be in mixdepth + 1
  • amount_fraction The fraction of the coins in this mix depth to be spent in this transaction. All the fractions in a single srcmixdepth will sum to 1.0
  • destination Where the coins will go. 'internal' means the coins are sent to another internal wallet address. A bitcoin address e.g. mprGzBA9rQk82Ly41TsmpQGa8UPpZb2w8c means the coins are sent there. 'addrask' means the application will ask the user to input a new address.
  • makercount How many market makers to use in a coinjoin.
  • wait How many minutes to wait after a coinjoin transaction has been created, broadcast and mined into a block.

Parameters

To get a list of parameters, run

python tumbler.py --help

Tips

  1. The coinjoin amounts are randomly generated. If the bot generates an amount smaller than any market maker's minimum amount, your tumbler will not be able to do a coinjoin. Use this command line flag to set a floor on the coinjoin amount.

       -s MINCJAMOUNT, --mincjamount=MINCJAMOUNT
                     minimum coinjoin amount in transaction
    
  2. If your tumbler is ended prematurely or crashes, your coins will either be still in your wallet or some might have been sent to your destination addresses. Run wallet-tool.py to see them. You may have to use the -m flag to see higher mixing depths than the default of 5. You can restart the tumbler from a higher mixing depth than zero if you just want to pick up where you left off.