Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
89 changes: 89 additions & 0 deletions docs/how-payjoin-saves.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
---
sidebar_position: 1
---

# How Can Payjoin Save 1/3 of the Cost of Transacting?

Payment batching is the most common way for high-volume settlement services like exchanges and payment processors to save fees. But it has been limited to one party, the sender, combining multiple sends together. Ideally, multiple types of transfers could all be combined together. Imagine your deposit to an exchange was batched with others' withdrawals. This combination saves significant overhead compared to making individual transfers, [scaling Bitcoin](./why-payjoin/scaling). It also results in better preserved [privacy](./why-payjoin/privacy) since, like bitcoin itself, only inputs and outputs are recorded, but less information about which inputs and outputs are clustered would be revealed, breaking the [common input heuristic](https://en.bitcoin.it/wiki/Common-input-ownership_heuristic)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Much improved!

Bitcoin casing inconsistent, missing period:

Suggested change
Payment batching is the most common way for high-volume settlement services like exchanges and payment processors to save fees. But it has been limited to one party, the sender, combining multiple sends together. Ideally, multiple types of transfers could all be combined together. Imagine your deposit to an exchange was batched with others' withdrawals. This combination saves significant overhead compared to making individual transfers, [scaling Bitcoin](./why-payjoin/scaling). It also results in better preserved [privacy](./why-payjoin/privacy) since, like bitcoin itself, only inputs and outputs are recorded, but less information about which inputs and outputs are clustered would be revealed, breaking the [common input heuristic](https://en.bitcoin.it/wiki/Common-input-ownership_heuristic)
Payment batching is the most common way for high-volume settlement services like exchanges and payment processors to save fees. But it has been limited to one party, the sender, combining multiple sends together. Ideally, multiple types of transfers could all be combined together. Imagine your deposit to an exchange was batched with others' withdrawals. This combination saves significant overhead compared to making individual transfers, [scaling Bitcoin](./why-payjoin/scaling). It also results in better preserved [privacy](./why-payjoin/privacy) since, like Bitcoin itself, only inputs and outputs are recorded, but less information about which inputs and outputs are clustered would be revealed, breaking the [common input heuristic](https://en.bitcoin.it/wiki/Common-input-ownership_heuristic).


Transactions compete to get included in blocks according to network fees they pay since each block is limited to a fixed weight. At a high level, each transaction weight pays some base costs (𝑏), per-input costs (𝑖) and per-output costs (𝑜). In reality not all inputs and outputs have equal cost but the principle can be explained assuming they do, and be backed up by real examples.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if we should mention the concept of weight, since this may be a confusing term for people not familiar with Segwit. Or if we do, maybe link the term "weight" to some Segwit article. I think everyone gets the idea that blocks are storage limited, calling it weight is perhaps unnecessarily technical. Perhaps:

Suggested change
Transactions compete to get included in blocks according to network fees they pay since each block is limited to a fixed weight. At a high level, each transaction weight pays some base costs (𝑏), per-input costs (𝑖) and per-output costs (𝑜). In reality not all inputs and outputs have equal cost but the principle can be explained assuming they do, and be backed up by real examples.
Transactions compete to get included in blocks according to network fees they pay since block space is limited. At a high level, each transaction pays for base costs (𝑏), per-input costs (𝑖) and per-output costs (𝑜). In reality not all inputs and outputs have equal cost but the principle can be explained assuming they do, and be backed up by real examples.


Take a fictional exchange with 5 BTC in their treasury selling 1 bitcoin each to Alice, bob, and Carol for example.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Take a fictional exchange with 5 BTC in their treasury selling 1 bitcoin each to Alice, bob, and Carol for example.
Take a fictional exchange with 5 BTC in their treasury selling 1 bitcoin each to Alice, Bob, and Carol for example.


```
Exchange 5 btc -> 1 btc to Alice
~4 btc minus fees to Exchange
```

```
Exchange 4 btc -> 1 btc to Bob
~3 btc minus fees to Exchange
```
Comment on lines +12 to +21
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would you like me to make excalidraw mockups for these?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's find numbers that we're happy with before spending time on nice graphics. Content first.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note from convo: let's do small numbers in btc (Alice 1 btc, Bob 3 btc, etc)


```
Exchange 3 btc -> 1 btc to Carol
~2 btc minus fees to Exchange
```

Each transaction would cost the exchange 𝑏 + 𝑖 + 2𝑜, and they would pass the fees onto their customers in order to make a profit. The sum of these costs would be 3𝑏 + 3𝑖 + 6𝑜, which would come out of the final ~2 BTC change the exchange keeps in the end.

## Old-school Payment Batching

Batching helps the exchange save time and money in two ways. First, the overall cost to post such a transaction is cheaper than the cost of making three individual transactions to produce the same result. Second, a single unspent output can fund multiple withdrawals without waiting for each one to settle.

your typical exchange withdrawal looks like this:
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
your typical exchange withdrawal looks like this:
Your typical exchange withdrawal looks like this:


```
Exchange 5 btc -> 1 btc to Alice
1 btc to Bob
1 btc to Carol
~2 btc minus fees to Exchange
```

All else being equal, an exchange making this batch instead of three separate transactions will only pay 𝑏 + 𝑖 + 4𝑜 in fees, saving 2𝑏 + 2𝑖 + 2𝑜 compared to 3𝑏 + 3𝑖 + 6𝑜, at least 33% cheaper than making those three transactions separately. Second, the exchange does not have to wait for each withdrawal to settle before paying out the next one since they can service them all with a single UTXO. Sure, the exchange could keep multiple UTXOs ready for spending, but that is always going come at the cost of making even more transactions in preparation.

## Payjoin Payment Batching

What if Dave the depositor can payjoin? He gets a benefit of breaking some privacy heuristics, and he can save the exchange some fees that might be able to be pased on to him. Payjoin lets the exchange fund withdrawals with Dave's deposit in the same transaction.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
What if Dave the depositor can payjoin? He gets a benefit of breaking some privacy heuristics, and he can save the exchange some fees that might be able to be pased on to him. Payjoin lets the exchange fund withdrawals with Dave's deposit in the same transaction.
What if Dave the depositor can payjoin? He gets a benefit of breaking privacy heuristics, and he can save the exchange some fees that could be passed on to him. Payjoin lets the exchange fund withdrawals with Dave's deposit in the same transaction.


```
Dave 3 btc -> 1 btc to Alice
Exchange 2 btc 1 btc to Bob
1 btc to Carol
~2 btc minus fees to Exchange
```

𝑏 + 2𝑖 + 4𝑜

Since Dave's sweep to the exchange "[cut-through](./why-payjoin/scaling#transaction-cut-through)" to Alice, Bob, and Carol,

1. The exchange never had to take on a new UTXO from Dave's deposit and pay fees to spend it.
2. The exchange saved the fixed costs of making a second transaction, since Dave paid them.
3. All parties enjoy better privacy since deposits and withdrawals are indistinguishable from an exchange consolidation, and these batched transactions are indistinguishable from individual transactions.

Dave knows that Payjoin was used, but not which outputs are withdrawals vs consolidations.
The Exchange can see everything as it could before, but an outside observer cannot without that information being leaked.
Alice, Bob, and Carol can't tell whether or not all inputs came from the exchange or include an outsider's deposit. They know they got paid and that's their main concern.

In total, the payjoin only cost

*1 × base costs + 2 × input costs + 2 × output costs*

saving at least 1/3 of the cost of a regular transaction, and fees were split between Dave and the Exchange by custom.[^1]

## Future Payjoin Batching

Bitcoin technically allows even more depositors to batch their transactions, too. Even though today's version of Payjoin only allows Dave to pay the exchange, future versions of Payjoin will allow others pay the exchange and each other in the same transaction too. More batching means more saving, and potentially more privacy too.

```
Dave 3 btc -> 1 btc to Alice
Erin 1 btc 1 btc to Bob
Frank 2 btc 1 btc to Carol
Exchange 2 btc ~5 btc minus fees to Exchange
```

However, such transactions are more difficult to coordinate, so it will take an effort to develop this new protocol and get it deployed. Integrating Payjoin V2 can save money, improve privacy, and help get to the next iteration that massively fixes bitcoin's privacy through batching. Batching Bitcoin, saving sats, and preserving privacy seem like different goals, but with a little communication, the three goals can be achieved in every single transaction.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
However, such transactions are more difficult to coordinate, so it will take an effort to develop this new protocol and get it deployed. Integrating Payjoin V2 can save money, improve privacy, and help get to the next iteration that massively fixes bitcoin's privacy through batching. Batching Bitcoin, saving sats, and preserving privacy seem like different goals, but with a little communication, the three goals can be achieved in every single transaction.
However, such transactions are more difficult to coordinate, so it will take an effort to develop this new protocol and get it deployed. Integrating Payjoin V2 can save money, improve privacy, and help get to the next iteration that massively fixes Bitcoin's privacy through batching. Batching bitcoin, saving sats, and preserving privacy seem like different goals, but with a little communication, they can be achieved in every single transaction.


[^1]: Let 𝑏 represent fixed costs, 𝑖 represent input costs, and 𝑜 represent output costs. The cost of the unbatched transactions is 2𝑏 + 3i + 3o. The cost of the batched transactions is 2𝑏 + 2𝑖 + 2𝑜. Thus, the savings from batching is calculated as 1/3(2𝑏 + 3𝑖 + 3𝑜) = 2/3(𝑏) + 𝑖 + 𝑜, which is less than 𝑏 + 𝑖 + 𝑜. In this example The unbatched virtual weight is 152.25 vB + 168.5 vB = 320.75 vB. The payjoin batched virtual weight is 211.25 vB. (211.25 vB / 320.75 vB) = ~0.66, so making these transactions without batching is over 1/3 smaller than with batching. Put another way (320.75 / 211.25 vB) = ~1.51, so making these transactions without batching costs more than 50% more than the cost of making them with payjoin.
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
[^1]: Let 𝑏 represent fixed costs, 𝑖 represent input costs, and 𝑜 represent output costs. The cost of the unbatched transactions is 2𝑏 + 3i + 3o. The cost of the batched transactions is 2𝑏 + 2𝑖 + 2𝑜. Thus, the savings from batching is calculated as 1/3(2𝑏 + 3𝑖 + 3𝑜) = 2/3(𝑏) + 𝑖 + 𝑜, which is less than 𝑏 + 𝑖 + 𝑜. In this example The unbatched virtual weight is 152.25 vB + 168.5 vB = 320.75 vB. The payjoin batched virtual weight is 211.25 vB. (211.25 vB / 320.75 vB) = ~0.66, so making these transactions without batching is over 1/3 smaller than with batching. Put another way (320.75 / 211.25 vB) = ~1.51, so making these transactions without batching costs more than 50% more than the cost of making them with payjoin.
[^1]: Let 𝑏 represent fixed costs, 𝑖 represent input costs, and 𝑜 represent output costs. The cost of the unbatched transactions is 2𝑏 + 3i + 3o. The cost of the batched transactions is 2𝑏 + 2𝑖 + 2𝑜. Thus, the savings from batching is calculated as 1/3(2𝑏 + 3𝑖 + 3𝑜) = 2/3(𝑏) + 𝑖 + 𝑜, which is less than 𝑏 + 𝑖 + 𝑜. In this example, the unbatched virtual weight is 152.25 vB + 168.5 vB = 320.75 vB. The Payjoin batched virtual weight is 211.25 vB. (211.25 vB / 320.75 vB) = ~0.66, so these transactions are over 1/3 smaller with batching than without it. Put another way (320.75 / 211.25 vB) = ~1.51, so making these transactions without batching costs over 50% more than the cost of making them with Payjoin.



2 changes: 1 addition & 1 deletion docs/why-payjoin/scaling.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,4 @@ The Payjoin using exclusively Pay-to-Taproot addresses (P2TR) [here](https://mut
Payjoin got its start as a way to make a sort of coinjoin from a payment. A receiver combines their input with the sender's, effectively joining a [consolidation](https://bitcoin.stackexchange.com/questions/103194/confused-about-utxo-management-and-consolidation) transaction with a simple transfer. An observer looking at the Payjoin is cannot tell it apart from a simple transfer where all of the inputs come from the same entity.

## Transaction Cut-Through
Payjoin not only creates opportunity to batch consolidation, but may create any output with the incoming funds. Because Payjoin involves live interaction, the receiver may open lightning channels, forward funds to a different wallet, pay for goods and services, or batch forward transactions with incoming funds without first taking them into a new UTXO.
Payjoin not only creates opportunity to batch consolidation, but may create any output with the incoming funds. Because Payjoin involves live interaction, the receiver may [open lightning channels](./lightning), forward funds to a different wallet, pay for goods and services, or batch forward transactions with incoming funds without first taking them into a new UTXO.
2 changes: 1 addition & 1 deletion src/components/HeaderContent/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export default function HeaderContent() {
</h2>
</div>
<div className="flex gap-4 flex-col sm:flex-row">
<a href="#whypayjoin">
<a href="./docs/how-payjoin-saves">
<Button variant="primary">Learn More</Button>
</a>
<a target="_blank" href="https://payjoindevkit.org/">
Expand Down