This is a thinking out loud post. It might be totally unfeasible and I’d like to know if that’s the case.
In a traditional coinjoin, participants mix their coins with coins of others and get back the same amount (minus fees) they entered with. The outputs are of equal size which easily identifies the coinjoin transaction.
What if coinjoin participants were to make a payment to a third party (or to themselves, it doesn’t matter) during the coinjoin, i.e. they would be providing a typical combination of receiver’s address (or multiple) + change address. The following example illustrates the concept:
Inputs: User A: 0.7 BTC User B: 0.5 BTC User C: 0.9 BTC
Total: 2.1 BTC
Outputs:
  1. 0.2 BTC User B paying
  2. 0.3 BTC User A paying
  3. 0.4 BTC User C paying
  4. 0.4 BTC User A change
  5. 0.2 BTC User C paying
  6. 0.3 BTC User B change
  7. 0.1 BTC User C paying
  8. 0.2 BTC User C change
Total: 2.1 BTC
Obviously, the inputs and outputs must make sense from the privacy standpoint in terms of amounts - there can’t be 0.8 BTC output which would be easily linked to User C. The coordinator’s task would be to identify such cases and reject them.
The anonymity set grows exponentially with number of participants and/or number of inputs/outputs. Technologically, it shouldn't differ much from the traditional coinjoin.
The privacy benefit should be clear, less block space would be used and less fees would be paid. Why not make most of the transactions collaborative in a similar fashion?
This is a thinking out loud post. It might be totally unfeasible and I’d like to know if that’s the case.
I have good news for you: Not only is it feasible, it's already implemented in multiple wallets! You can send payments directly in a coinjoin with BTCPay Server's coinjoin plugin or with Wasabi Wallet's RPC.
I demonstrated how you can make completely anonymous on chain Bitcoin payments by sending 100k sats to Vlad in this coinjoin transaction: https://mempool.space/tx/52a1f40b1d1dae560c02f0bb65304172d936e01d67ee633c2f846c139fef8c0b
This doesn't require the recipient to provide multiple addresses or accept specific sized amounts, you can send arbitrarily sized payments to a single address. It's extremely block space efficient because there's no premix transaction or postmix transaction required - you can consolidate UTXOs, batch payments, and anonymize any leftover change all in a single coinjoin transaction.
reply
This looks great, I'll explore more for sure. Thanks.
It seems much simpler than the traditional coinjoin. Makes one wonder why isn't it the default way to spend coins. What do you think is the reason this isn't a standard in majority of wallets yet?
reply
The reason it isn't the default way to spend coins is because you would have to wait up to 1 hour for the other participants to join and build the transaction, which introduces the chance for prices to change in the meantime. Also, the coordinator chooses the fee rate for all participants, so if the fee for the round is higher than you are willing to pay then you would have to wait for the coordinator to create a round with a lower fee. Unfortunately, most wallets simply don't care about any privacy feature that would introduce UX tradeoffs.
reply
With enough adoption, I imagine the wait time would be negligible. Same for the fees, if you don't go too low.
Anyway, this is the way I want to spend my coins. I'll explore the existing options and see if there's anything I can do to help with the adoption.
reply
This is already how Joinmarket works. You can make payments using joinmarket... to 3rd parties. In other words a 'coinjoin' of sorts happens except the utxo goes to a third party and you still receive the change.
Joinmarket - learn it and love it
reply
Paying third parties using a JoinMarket coinjoin doesn't add privacy because an observer can still calculate which inputs belong to the taker and their change.
To use JoinMarket privately, you pay your own wallet with a coinjoin sweep for any incoming UTXO or any change UTXO created from a payment. Then you wait as a maker in between your own transactions to get paid for contributing remixing liquidity.
reply
With respect (and I absolutely could be wrong...) I don't think the first part of this is true.
The outputs look identical from a Joinmarket transaction. With an anon set of... 8, 9, 10 etc.
Then when a 'change' address is provided from a payment it is never-before-used.
Which change output was the result of which tx output? Who knows. All the tx outputs look the same and are for the same amounts... so any 'change' from the actual 'spending' output could be from any the original outputs.
My understanding is that while coinjoins/Joinmarket txs don't add perfect anonymity... they obscure the utxo set for a price. Obviously one coinjoin will not provide infinite privacy... but alternating roles as taker and maker with coinjoins improves the anon set significantly.
reply
Here's a JoinMarket coinjoin that demonstrates the scenario I'm describing: https://mempool.space/tx/1e513e339213b1c02e574d34b920014a96bccd2a4b857e63c05243bd34d6615b
In this case, we know bc1q...vrhtt is the taker - His change landed in bc1q...lrl23, paying 10,212 sats in total fees:
  • 3,200 sats in fees to the bigger maker bc1q...5pll3 whose change went to bc1q...jd0vd
  • 2,200 sats in fees to the smaller maker bc1q...95xww whose change went to bc1q...cjz9p
  • 4,812 sats in fees to miners
So if you are the recipient of one of the 1 BTC equal sized outputs, you would know exactly which input sent it to you and you would know exactly which change output is owned by the same sender to continue tracing, just like any regular non-coinjoin transaction.
reply
Thank you for your comment, it is very thoughtful.
On looking at that transaction my initial reaction is.... wow that's a pitiful coinjoin. There are 3 outputs that are the same meaning that the anonymity set is... 3? That's not good.
Joinmarket's default settings I believe has an anon set of somewhere between 8-10. And so imagine if there are 10 outputs of the same size, with a few other outputs of various sizes... it seems to me it would be difficult to determine which sats belong to whom.
Especially if there are other coinjoins or 'maker' transactions before or after with the same outputs.
reply
10 sats \ 1 reply \ @kruw 28 Sep
Exactly, I cherry picked that JoinMarket tx for the demonstration because it is very small. Here's a very large JoinMarket tx where it's more difficult to determine the set of inputs linked to the users who created the bc1q...f2yxq and bc1q...xvdwu change outputs: https://mempool.space/tx/63b28f5e17e03fef27795e1ea7fbf821e2d5f072098ffcef3d27b8b2d23ca719
reply
This is a really interesting tx
reply
You're the second one pointing me to joinmarket. I'll explore it deeper, thank you!
reply
Obviously, the inputs and outputs must make sense from the privacy standpoint in terms of amounts - there can’t be 0.8 BTC output which would be easily linked to User C. The coordinator’s task would be to identify such cases and reject them.
It is even possible to do it with equal size outputs. No change amounts involved in the coinjoin transaction. No coordinator required.
Joinstr protocol allows users to create pools with custom denominations and number of peers.
In some cases it's better to avoid paying third parties in coinjoin transactions. Payjoin or Octojoin works better in such situations because less or no coordination and transactions look normal.
reply
Why would you want to "wash" your bitcoin? Any specific reason?
reply
I'm not thinking in terms of washing. I simply don't want my counterparty to know where my bitcoin is coming from, i.e. what UTXO(s) I'm spending.
reply
You know you deserve a nice big NICE TRY FED! for that one!
reply
Haha That is true. I dont think I have heard that in a while.
reply