Building on Taproot: Payment Pools Could Be Bitcoin’s Next Layer Two Protocol
This article is about a technological concept based on the proposed Taproot protocol upgrade. If you’re not yet familiar with the basics of how Taproot works, it’s recommended that you first read this explainer.
Taproot, a potential upgrade to the Bitcoin protocol first proposed by Bitcoin Core contributor Gregory Maxwell, is in its late stages of development. The technology consists of a clever combination of crypto-tricks that would let users hide complex smart contracts inside regular-looking transactions — the complexity is only ever revealed if parties to a contract are uncooperative.
Leveraging this idea, Bitcoin Core contributors including (but not limited to) Jeremy Rubin, Antoine Riard, Gleb Naumenko and Gregory Maxwell himself have been speculating about a general concept referred to as payment pools, joinpools or coinpools. These pools — we’ll stick to calling them payment pools for now — would let groups of users share ownership of the same coins (technically: UTXOs) as recorded on the Bitcoin blockchain, while letting any of these users make (or receive) payments with them. As the group and its individual members “hide” in a Taproot structure, all of them enjoy more privacy, smart contract flexibility and other benefits… and they potentially even enjoy these benefits off-chain, making payment pools a new Layer Two solution.
Although design specifics vary a bit from one Payment Pool proposal to the next, the general concept is the same. Here’s the basic idea…
Sharing A Coin
First, to create a payment pool, users combine their (fractions of) coins by aggregating them in a Taproot address shared between them. So, let’s say Alice owns three coins, Bob owns two coins and Carol owns one coin, for a total of six. Together, they create a transaction that sends these coins to the shared address, making it a payment pool with six coins.
On the blockchain, the payment pool address looks like a regular Bitcoin address, now holding six coins. But underneath the surface, Alice, Bob and Carol cleverly used Taproot to ensure that each of them remains in control of their own share of coins in the payment pool. Alice can at any point claim three coins from the address, Bob can at any point claim two and Carol one.
This is because there are only two main options to spend coins from the address.
The first option is to spend directly from the address, in technical terms the Taproot key-path. This requires cooperation (that is: cryptographic signatures) from all three participants. If Alice, Bob and Carol all agree, the six coins can be spent however they like, and this will look like any other regular transaction on the Bitcoin network. The trio can for example decide to send their respective balances back to individual addresses: three for Alice, two for Bob and one for Carol. But if they’d so choose they could also cooperate to donate all six coins to Julian, or spend it in any other way they might agree on. The important thing is that all three of them need to participate, so no one’s balance is being spent without his or her own cooperation.
The second main option actually consists of several sub-options. Before sending their coins to the payment pool, Alice, Bob and Carol hid something in the cryptographic tree behind the Taproot address: they included alternative ways to send funds from the payment pool. (Currently, this could be realized by having all three participants pre-sign transactions from these paths, which would require some complexity to set up all the options and doesn’t scale very well; proposed protocol upgrades could potentially make this easier in the future.)
If one of the participants would choose to spend the coins in the payment pool through an alternative Taproot path, they would typically send an amount corresponding to that participant’s balance to an address of their choosing, like an individual address that they control. (In Alice’s case, three coins to her own address, in Bob’s case two to his address and in Carol’s case one.)
Using this alternative path, the remaining coins are automatically spent as well. This can be done in several ways depending on the design of the payment pool, offering different tradeoffs in regard to complexity and scalability.
The simplest solution is to send every other participant their share of coins as well, to an address of their choosing. In other words: if one user exits the pool, everyone exits the pool.
A second solution, preferred by Riard and Naumenko, is to send all the remaining coins to a new payment pool, that looks exactly like the first payment pool, just stripped from anything that involved the now-exited user. This design offers the best user experience, but is the hardest one to scale, most importantly because it’s necessary to prepare for all possible exit scenarios, including all possible exit scenarios for all potential new pools. Scale could, however, be achieved with a yet-to-be-named potential Bitcoin protocol upgrade to ensure that the rules from the previous payment pool are carried over to any new payment pool.
Rubin believes this second solution is impractical, however, and prefers to go for something in between the first and second solutions: some participants immediately receive their coins to an address of their choosing, other participants have their coins sent to a new payment pool. This design offers a less ideal user experience, but would scale better, and the potential OP_CHECKTEMPLATEVERIFY protocol upgrade would help simplify the design and increase scale even more. (Exits would happen through Tree Payments; these types of payments are explored further in this article.)
(There are more tradeoffs between the second and third solutions, but the details of all the pros and cons are outside the scope of this article; read the bitcoin-dev mailing list discussion for specifics.)
To see what it means when remaining coins are sent to a new payment pool, let’s say that Alice, Bob and Carol choose the second option, where all remaining coins are sent to a new payment pool. If in this design Alice exits the first payment pool, three coins are sent to an address of her choosing, while the other three coins are sent to a new payment pool between Bob and Carol. Alice at that point has sole control over her own coins again, while not that much has changed for Bob and Carol. The two can still cooperate to spend the three remaining coins however they wish, or either of them can exit unilaterally, as Alice had done before.
If Bob then exits unilaterally from the second payment pool, he sends two coins to an address of his choosing, and one coin to an even newer payment pool (the third one) with only Carol left. (Of course, in this simplified example, a design where this last payment pool is replaced with an address of Carol’s choosing would in actuality make more sense, but that’s an implementation detail.)
The important takeaway is that participants in a payment pool can cooperate to make any type of payment from the pool they want, while any one of them can at any point exit with their own coins, leaving other participants in control of theirs.
Putting The Payment In Payment Pool
So we’ve established that all participants can individually withdraw their balance from a payment pool, or — if they all agree — spend from the pool. It’s this second option that actually enables something clever: the payment pool can be dynamic. As long as all participants agree, they can not just pay themselves their funds back, or pay others (like Julian), but they can do something even more interesting. They can move their funds to newer versions of the payment pool, with different designs.
This for example lets any one of them spend from the pool.
Let’s say Alice is buying a new car, and wants to pay for it with one bitcoin. Alice, Bob and Carol could then create a transaction from the payment pool that sends one coin to the car dealership, and sends the remaining five coins to a new payment pool that looks the same as the first one, except this time Alice can only exit from it unilaterally with two coins, one less than before.
The transaction, meanwhile, looked like any other regular Bitcoin transaction. The car dealership (or blockchain spies) may conclude that Alice owned all six coins and simply used one to buy the car, and kept the other five as change. They would have no idea that some of the coins belong to Bob and Carol, or that they were involved with the transaction at all.
Next time, when Bob makes a payment and Alice and Carol cooperate, it’s made from the same payment pool, once again looking like an ordinary Bitcoin transaction to the outside world. In the resulting iteration of the payment pool, Bob can exit with one coin instead of two. Meanwhile, the same blockchain spies may have thought Alice was making a payment again, confusing them further. (And even if the blockchain spies would somehow figure out that the address is really a payment pool between Alice, Bob and Carol, they still couldn’t tell which of the three made the latest payment.)
Every time Alice, Bob or Carol spend coins, the transaction may have come from any one of them, and no one outside of the payment pool can tell the difference.
Payment pools don’t just allow for spending. If Alice wants to top up her “balance” in the payment pool, she could do this, too. Alice, Bob and Carol would in this case cooperate to move the current five coins to a new Taproot address, to which Alice would in the same transaction send one additional coin from one of her own (individual) addresses. The new Taproot address would once again contain six coins, three of which belong to Alice, as reflected in her unilateral exit option.
In the same way, entirely new users could join the payment pool, too. If Alice, Bob and Carol agree to let Dave participate, the three of them cooperate with Dave to create a transaction that sends the payment pool funds along with Dave’s new coins to a new payment pool, designed to also let Dave take part — and exit if he’d so choose.
Furthermore, there’s the option for participants within the payment pool to pay each other. If Alice would for example pay Bob one coin, the three could cooperate to send the funds to a new payment pool where Alice has a coin subtracted from her balance and Bob has a coin added. On the blockchain, again, it would look like a regular payment, and blockchain spies would have no idea who paid who, or how much. (It’s worth pointing out that Dave could have in a similar way entered the pool, by receiving an internal payment from one of the existing participants.)
With a little bit of extra complexity (and ideally with at least one extra Bitcoin protocol upgrade like Noinput), transfers could even be completed off-chain as well. When Alice pays Bob, all participants would in this case create a transaction spending funds to a new payment pool just the same, but this transaction would only be shared between them — not broadcast to the network (unless someone ever attempts to cheat). In this way, Alice, Bob and Carol could keep updating their balance “internally,” and even let Dave into the pool at some point. When they all agree to close the pool, they can create a final transaction that spends from the original payment pool, awarding each their latest balance.
Similar to an older idea known as Channel Factories, these types of payment pools could eventually even be used to themselves host Lightning channels, vaults or other Layer Two protocols. This may offer the potential to “wrap” any type of additional protocol layer in such pools, thus hiding all their complexity in identical and regular-looking transactions.