diff options
author | Ryan Havar <rhavar@protonmail.com> | 2018-10-08 01:53:25 +0600 |
---|---|---|
committer | Ryan Havar <rhavar@protonmail.com> | 2018-10-08 01:53:25 +0600 |
commit | 605c31a9e01c1cb0113cca91811571d7ad48f3c8 (patch) | |
tree | 9ce36546d7f1e03574b1888ae6fc32d4b09f656a /bip-bustapay.mediawiki | |
parent | ad3a16baab521bc6005cb0577f44a0677f24fe08 (diff) | |
download | bips-605c31a9e01c1cb0113cca91811571d7ad48f3c8.tar.xz |
Add bip for bustapay
Diffstat (limited to 'bip-bustapay.mediawiki')
-rw-r--r-- | bip-bustapay.mediawiki | 120 |
1 files changed, 120 insertions, 0 deletions
diff --git a/bip-bustapay.mediawiki b/bip-bustapay.mediawiki new file mode 100644 index 0000000..9417ec4 --- /dev/null +++ b/bip-bustapay.mediawiki @@ -0,0 +1,120 @@ +<pre> + BIP: 69 + Layer: Applications + Title: Bustapay :: a practical sender/receiver coinjoin protocol + Author: Ryan Havar <rhavar@protonmail.com> + Comments-Summary: No comments yet. + Comments-URI: https://github.com/bitcoin/bips/wiki/Comments:BIP-bustapay + Status: Proposed + Type: Informational + Created: 2018-10-5 + License: CC0-1.0 +</pre> + + +==Abstract== + +The way bitcoin transactions are normally created leaks more information than desirable, and as a result has been exploited by unreasonably effective blockchain analysis techniques to jeopardizes important properties that is expected of a useful currency. + +Bustapay is a simple and practical protocol for the sender and receiver of a payment to collaboratively sign a bitcoin transaction in such a way that busts some analysis assumptions to immediate benefit of the sender and receiver. Furthermore it does so in such a way that gives a significant amount of control to the receiver to help manage their utxo set size, a constant problem for bitcoin merchants. + +==Copyright== + +This document is licensed under the Creative Commons CC0 1.0 Universal license. + +==Motivation== + +One of the most powerful blockchain analysis heuristics has been to assume all inputs of a transaction are controlled by a single party unless otherwise known (such as by the distinctive structure of a traditional coinjoin, or multisig spends that are validated onchain). Combined with other techniques (notably change-output guessing) this has lead to unexpectedly accurate tracking that has exposed bitcoin participants to unacceptable personal, business and financial risks -- undermining bitcoin's utility and fungibility -- and ultimately jeopardizing its ability to function as useful money. + +We however can bust these assumption, in a relatively simple way with a sender-receiver coinjoin. With our protocol we bypass many of the DoS and complexity problems that have plagued previous coinjoin protocols and hampered hopes of adoption. Besides being efficient and simple, bustapay most promisingly does have an identifiable structure for attackers, which erodes the confidence of their entire models, providing positive externalities for the entire bitcoin ecosystem. + +Bustapay transactions also they do not grow the receiver's count of unspent transaction outputs, and in fact gives the receiver an opportunity to better manage their utxo set, something normally only done when sending payments. Large utxo sets are often problematic and expensive, and frequently requiring privacy-destroying consolidation. Besides busting clustering assumptions, bustapay also provides a layer of obfuscation of send amounts. + +It is worth noting that this specification has eschewed complexity and potentially useful extensions on the assumption that simplicity is of the most important to encourage adoption. + + +==Overview== + +A bustapay payment is made from a sender to a receiver. + +====Step 1. Sender creates a bitcoin transaction paying the receiver==== + +This transaction must use segwit for all inputs, and be fully valid and signed. The transaction must be eligible for propagation on the network (but not done so at this stage) + +====Step 2. Sender gives the "template transaction" to the receiver==== + +This is done via an HTTP POST request, sent to a "bustapay url" + +====Step 3. Receiver processes the transaction and returns a partially signed coinjoin==== + +The receiver validates the transaction, and pays himself. The receiver then adds one or more of his own inputs (known as the ''contributed inputs'') and (optionally) increases the output that pays himself (generally by the sum of the ''contributed inputs''). Doing so creates a ''partial transaction'', which the receiver returns to the sender. It is called such as it requires the sender to resign his own inputs. + +====Step 4. Receiver validates, re-signs, and propagates on the bitcoin network==== + +The receiver MUST validate the ''partial transaction'' was changed correctly and non-maliciously (to allow using potentially untrusted communication channels), resign its original inputs and propagates the final transaction over the bitcoin network. + +====Step 5. Receiver observes the finalized transaction on the bitcoin network==== + +Once the receiver has seen the finalized transactions on the network (and has enough confirmations) it can process it like a normal payment for the sent amount (as opposed to the amount that it looks like on the network). If the receiver does not see the finalized transaction after a timeout will propagate the original "template transaction" to ensure the payment happens and function a strong anti-DoS mechanism. + +== Specification == + +The standard way of letting a sender know where to send a bustapay transaction is done via a bip21 encoded address. The key value "bpu" (short for "BustaPayUrl") should be used. An example such address would be bitcoin:2NABbUr9yeRCp1oUCtVmgJF8HGRCo3ifpTT?bpu=https://bp.bustabit.com/submit It is highly encouraged that urls are kept short. + +When the sender is creating a "template transaction" it is done almost identically to creating a normal send, with the exception that *only* segwit inputs may be used. The sender is also encouraged to use a slightly more aggressive feerate than usual as well as BIP125 (Opt-in Full Replace-by-Fee Signaling), but neither is strictly required. + +The template transaction should be sent to the receiver via an HTTP POST to the bustapay url, with a binary encoded body. + +The receiver is then responsible for validating the template transaction. If there is a problem with the transaction, or the receiver is generally unhappy with the transaction (e.g. fees are too small) the HTTP response code of 422 should be used and a human-readable string containing information on why which can be directly given to the user. + +Should the receiver reject a transaction, it should not attempt to propagate it on the network. + +=== Contributed Input Choice === + +The receiver must add at least one input to the transaction (the "contributed inputs"). If the receiver has no inputs, it should use a 500 internal server error, so the client can send the transaction as per normal (or try again later). Its generally advised to only add a single contributed input, however they are circumstances where adding more than a single input can be useful. + +To prevent an attack where a receiver is continually sent variations of the same transaction to enumerate the receivers utxo set, it is essential that the receiver always returns the same contributed inputs when it's seen the same inputs. + +It is strongly preferable that the receiver makes an effort to pick a contributed input of the same type as much the other transaction inputs if possible. + +=== Output Adjustment === + +After adding inputs to the transaction, the receiver will generally want to adjust the output that pays himself. This is the *only* output that the receiver should adjust. All other outputs *must* be left intact. The receiver *must never* decrease the amount they get paid nor increase, and generally not increase it by more than the contributed input amount. + +=== Returning the partial transaction === + +The receiver must sign all contributed inputs in the partial transaction. The partial transaction should also remove all witnesses from the the original template transaction as they are no longer valid, and need to be recalculated by the sender. The receiver returns the partial transaction as a binary-encoded HTTP response with a status code of 200. + + +=== Sender Validation === + +The sender *must* do important validation on the partial transaction. They *must* verify: + +* All template transaction inputs are in the partial transaction (but perhaps different order) and have the same sequence numbers. +* The partial transaction contains at least one new (and signed) segwit input (owned by the receiver) +* All outputs from the template transaction exist in the partial transaction, except they are allowed to be reordered and have their amounts increased (but *never* decreased) + +=== Creating Final Transaction === + +After validating the partial transaction, the sender signs all its inputs to create what is now the final transaction. It is important that the sender is careful to not be tricked by the receiver into signing other inputs it owns. The sender must only sign inputs that existed in the template transaction. If the sender is not careful the receiver may "contribute" inputs that are actually owned with by the sender, with the hope the sender blindly signs everything. + + +=== Transaction Publishing === + +One the final transaction is created, the sender should publish it directly onto the bitcoin network. If the sender does not do this after a reasonable time (e.g. 1 minute), the receiver should publish the template transaction as an important anti-spy/anti-DoS tactic . The sender may also choose to publish the template transaction instead of the final transaction if they believe the receiver to have unreasonably lowered the feerate of the transaction (i.e. increased the size of the transaction, but not the feerate enough). And both parties can consider publishing the template transaction even after the finalized transaction is on the network (taking advantage of replace-by-fee) if the final transaction is not confirming and the template transaction has more fees. + + +=== Implementation Notes === +For anyone wanting to implement bustapay payments, here are some notes for receivers: + +* A transaction can easily be checked if it's suitable for the mempool with testmempoolaccept in bitcoin core 0.17+ +* Tracking transactions by txid is precarious. To keep your sanity make sure all inputs are segwit. But remember segwit does not prevent txid malleability unless you validate the transaction. So really make sure you're using testmempoolaccept at the very least +* Bustapay could be abused by a malicious party to query if you own a deposit address or not. So never accept a bustapay transaction that pays an already used deposit address +* You will need to keep a mapping of which utxos people have showed you and which you revealed. So if you see them again, you can reveal the same one of your own +* Check if the transaction was already sorted according to BIP69, if so ensure the result stays that way. Otherwise probably just shuffle the inputs/outputs +* A reference implementation is maintained at https://github.com/rhavar/bustapay which functions as a wrapper around some RPC calls to bitcoin core's wallet. +* The sender must be careful of an attack where the receiver tries to add additional inputs that are controlled by the sender, with the hope that the sender blindly signs it. + + +== Credits == +The idea is obviously based upon Dr. Maxwell's seminal CoinJoin proposal, and reduced scope inspired by a simplification of the "pay 2 endpoint" blog post by blockstream. |