Privatesend
Dash Core's PrivateSend feature provides a way to improve privacy by performing coin-mixing without relinquishing custodial access. For additional details, reference this Official Documentation PrivateSend page.
The following video provides an overview with a good introduction to the details:
PrivateSend Wallet Preparation
The wallet completes two operations in this phase:
-
Split value into inputs matching the PrivateSend denominations by sending transactions to itself
-
Split value into inputs to use for collateral by sending transactions to itself
Note: Both these operations incur the standard transaction fee like any other transaction
Creating Denominations
The PrivateSend denominations include a bit mapping to easily differentiate them. The dsa
message and dsq
message use this bit shifted integer instead of sending the actual denomination. The table below lists the bit, its associated integer value used in P2P messages, and the actual Dash value.
Bit | Denom. (Integer) | Denomination (DASH) |
---|---|---|
0 | 1 | 10.0001 |
1 | 2 | 01.00001 |
2 | 4 | 00.100001 |
3 | 8 | 00.0100001 |
4 | 16 | 00.00100001 |
Protocol version 70213 added a 5th denomination (0.001 DASH).
Example Testnet denomination creation transaction
Creating Collaterals
PrivateSend collaterals are used to pay mixing fees, but are kept separate from the denominations to maximize privacy. Since protocol version 70213, the minimum collateral fee is 1/10 of the smallest denomination for all mixing sessions regardless of denomination. In Dash Core, collaterals are created with enough value to pay 4 collateral fees (4 x 0.001 DASH). (Dash Core Reference)
In protocol version 70208, collateral inputs can be anything from 2x the minimum collateral amount to the maximum collateral amount (currently defined as 4x the minimum collateral). In protocol versions > 70208, Dash Core can use any input from 1x the minimum collateral amount to the maximum collateral amount.
Example Testnet collateral creation transaction
Example Testnet collateral payment transaction
PrivateSend Mixing
The mixing phase involves exchanging a sequence of messages with a masternode so it can construct a mixing transaction with inputs from the clients in its mixing pool.
PrivateSend Data Flow
Clients | Direction | Masternode | Description | |
---|---|---|---|---|
0 | Client determines whether to join an existing mixing pool or create a new one | |||
1 | dsa message | → | Client asks to join mixing pool or have the masternode create a new one | |
2 | ← | dssu message | Masternode provides a mixing pool status update (Typical - State: POOL_STATE_QUEUE , Message: MSG_NOERR ) | |
3 | ← | dsq message | Masternode notifies clients when it is ready to mix | |
4 | dsi message | → | Upon receiving a dsq message with the Ready bit set, clients each provide a list of their inputs (unsigned) to be mixed, collateral, and a list of outputs where mixed funds should be sent | |
5 | ← | dssu message | Masternode provides a mixing pool status update (typical - State: POOL_STATE_ACCEPTING_ENTRIES , Message: MSG_ENTRIES_ADDED ) | |
6 | ← | dsf message | Masternode sends the final transaction containing all clients inputs (unsigned) and all client outputs to each client for verification | |
7 | ← | dssu message | Masternode provides a mixing pool status update (Typical - State: POOL_STATE_SIGNING , Message: MSG_NOERR ) | |
8 | dss message | → | After verifying the final transaction, clients each sign their own inputs and send them back | |
9 | ← | dsc message | Masternode verifies the signed inputs, creates a dstx message to broadcast the transaction, and notifies clients that the mixing transaction is complete (Typical - Message: MSG_SUCCESS ) | |
10 | ← | inv message | Masternode broadcasts a dstx inventory message | |
11 | getdata message (dstx) | → | (Optional) |
Additional notes
Step 0 - Pool Selection
- Existing mixing pool information is derived from the Queue messages seen by the client
- Dash Core attempts to join an existing mixing pool and only requests creation of a new one if that fails, although this is not a requirement that alternative implementations would be required to follow
Step 1 - Pool Request
- The
dsa
message contains a collateral transaction- This transaction uses a collateral input created in the Wallet Preparation phase
- The collateral is a signed transaction that pays the collateral back to a client address minus a fee of 0.001 DASH
Step 3 - Queue
- A masternode broadcasts
dsq
messages when it starts a new queue. These message are relayed by all peers. - As of protocol version 70214, mixing sessions have a variable number of participants defined by the range
nPoolMinParticipants
(3) tonPoolMaxParticipants
(5). Prior protocol version mixing sessions always contained exactly 3 participants - Once the masternode has received valid
dsa
messages from the appropriate number of clients (nSessionMaxParticipants
), it sends adsq
message with the ready bit set- Clients must respond to the Queue ready within 30 seconds or risk forfeiting the collateral they provided in the
dsa
message (Step 1) (Dash Core Reference)
- Clients must respond to the Queue ready within 30 seconds or risk forfeiting the collateral they provided in the
Step 4 - Inputs
- The collateral transaction can be the same in the
dsi
message as the one in thedsa
message (Step 1) as long as it has not been spent - Each client can provide up to 9 (
PRIVATESEND_ENTRY_MAX_SIZE
) inputs (and an equal number of outputs) to be mixed (Dash Core Reference) - This is the only message in the PrivateSend process that contains enough information to link a wallet's PrivateSend inputs with its outputs
- This message is sent directly between a client and the mixing masternode (not relayed across the Dash network) so no other clients see it
Step 6 - Final Transaction (unsigned)
- Once the masternode has received valid
dsi
messages from all clients, it creates the final transaction and sends adsf
message- Inputs/outputs are ordered deterministically as defined by BIP-69 to avoid leaking any data (Dash Core Reference)
- Clients must sign their inputs to the Final Transaction within 15 seconds or risk forfeiting the collateral they provided in the
dsi
message (Step 4) (Dash Core Reference)
Step 10 - Final Transaction broadcast
- Prior to protocol version 70213, masternodes could only send a single un-mined
dstx
message at a time. As of protocol version 70213, up to 5 (MASTERNODE_MAX_MIXING_TXES
) un-mineddstx
messages per masternode are allowed.
General
With the exception of the dsq
message and the dstx
message (which need to be public and do not expose any private information), all PrivateSend P2P messages are sent directly between the mixing masternode and relevant client(s).
PrivateSend Fees
Mixing Fees
- If mixing completes successfully, Dash Core charges the collateral randomly in 1/10 mixing transactions to pay miners (Dash Core Reference)
- Clients that abuse the mixing system by failing to respond to
dsq
messages ordsf
messages within the timeout periods may forfeit their collateral. Dash Core charges the abuse fee in 2/3 cases (Dash Core Reference)
Sending Fees
To maintain privacy when using PrivateSend, PrivateSend transactions must fully spend all inputs to a single output (with the remainder becoming the fee - i.e. no change output). This can result in large fees depending on the value being sent.
For example, an extreme case is sending the minimum non-dust value (546 duffs) via PrivateSend. This results in an extremely large transaction fee because the minimum PrivateSend denomination (0.00100001 DASH or 100,001 duffs) must be fully spent with no change. This results in a fee of 0.00999464 DASH and a sent value of only 0.00000546 DASH as shown by the calculation below.
100001 duffs (smallest PrivateSend denomination) - 546 duffs (value to send) = 99455 duffs (fee)
Updated over 4 years ago