Before we begin: this post describes a very limited protocol idea. It's possible that what we describe here is a start towards, or a component of, something genuinely useful, but in itself it's really more of a toy, albeit it's fun.
Since the 90s, there was a dream that cash could be sent online just like email. We've basically been experimenting with tradeoffs against this pure vision ever since. Sometimes the tradeoff is: there's a central party we have to trust (either with our privacy or our money or the management or inflation or..), but otherwise we get the goal. Often the tradeoff includes: we have to interact with the receiver. In pretty much every case there's an online-ness requirement: we have to exchange messages with a p2p network of active nodes (bitcoin) or a central server and our counterparty, or at least, directly with our counterparty (e.g. Lightning) in the payment transaction.
What we want is something closer to: I come up to your lunch cart on the street, buy a hotdog by "handing over" "digital cash", you don't have to trust me but can accept it as money, I walk off with the hotdog and both people forget the other. And of course, we want that to work the same in an internet payment (especially the 'forget' part).
Nice dream.
How far, though, could you go, if you doggedly insisted, in a Bitcoin context, that the actual act of payment, was simply the handing over of some data or text.
Above is pictured a different way of trading off to achieve the goal; the opendime, which is a very cool cypherpunk idea (a spiritual cousin of, if not technically related to, Hal Finney's RPOW idea of the early 00s). If you trust that the hardware is not hackable (enough), you can accept the device as being == the coin.
A reminder, in case these ideas are not front of mind: I can't give you money by "handing over my private key", because that's really sharing data, not transferring it. You have no way of knowing whether I remember it; and if I remember it I have as much control over the coin as you do. So private key transfer is generally not a useful idea. There are big caveats - see Mercury wallet and perhaps even Intel SGX, but see also: opendime, as mentioned - the private key cannot be accessed without physically (and demonstrably) "breaking" the opendime; before that time people can transfer it physically, and treat it as physical transfer of ownership of the signing key.
The limitation of this meaning a "fixed denomination" coin is interesting; statechains, of which the above-mentioned Mercury is an implementation, in general, have this kind of limitation too.
Statechains make one of the various tradeoffs we already discussed, in that they have a trust in a third party (more particularly they are trusting in absence of collusion, something we're going to discuss at length here!). We're going to see how far we can get without that trust element.
So: can we make this kind of construction, without trust, in software, not hardware? Let's try! What is presented next as "PathCoin" is based on that idea. As we said at the start, it is VERY limited compared to what we would like to do in the "dream" explained above. But maybe it's the start of something?
First of all, let's consider shared ownership of a single utxo, in a taproot and Schnorr and MuSig2 world.
It's already pretty nice. There can be 100 people owning a multisig together and because of the above tech, it can look the same as one person, to the outside world (I won't discuss MuSig further in this doc, as it's kind of orthogonal. Simpler multisig exists, in taproot, if we need it).
For the rest of this description, though, let's have it be 5 people Alice, Bob, Carol, David, Eve. Just to keep things manageable.
So if they make a 5 of 5 multisig they can control funds together.
With taproot, they can create multiple spending paths with different spending conditions, when they set up this address, such as:
1 coin -> (Alice and Carol) OR (all 5) OR ( Bob and Carol after 1000 blocks OR (all 5)) OR (David and Eve after 2000 blocks)
So that convoluted script logic was just made up, but the point is we can use the 'script path spend' in taproot to make lots and lots of different spending paths that don't end up abusing the blockchain space limitation; only one of the spending paths ends up getting satisfied, and displayed, in the spending transaction. Great, simple so far, just taproot.
Now if all we really want to do is "use taproot to share and transfer money", we may well be better off with the kind of model explored in payment pools (that link is only one of several disparate discussions on this topic, I think). In that scenario, there is unilateral withdrawal available, but payments are cooperative, updating the contract inside the taproot output. It's a very promising direction, but here we're, again, insisting on no further interaction to make payments, in line with the 'cypherpunk dream'.
From here we'll build up the PathCoin idea in stages, starting with the most restrictive and slowly dragging it closer to useable, with more elements.
So, continuing from taproot: we could deliberately create several different paths with the same condition, like this:
Person | Alice | Bob | Carol | David | Eve | |
---|---|---|---|---|---|---|
multisig script 1 | A1 | B1 | C1 | D1 | E1 | -> TXA |
multisig script 2 | A2 | B2 | C2 | D2 | E2 | -> TXB |
multisig script 3 | A3 | B3 | C3 | D3 | E3 | -> TXC |
multisig script 4 | A4 | B4 | C4 | D4 | E4 | -> TXD |
multisig script 5 | A5 | B5 | C5 | D5 | E5 | -> TXE |
These are all 5/5 multisigs. Each list of 5 is different keys (see number suffixes), but the letter denotes which person owns the private key for that key. So this is just a 5 x 5 matrix of keys. The 'scripts' are just a single pubkey spending script, which happens to be a MuSig2 aggregated key.
Alternatively, and more simply, we could just define one 5/5 MuSig multisig, use the key-path spending in taproot, and simply perform 5 separate signing sessions on the same key (each session signing different transaction messages). So:
Person | Alice | Bob | Carol | David | Eve | |
---|---|---|---|---|---|---|
musig session 1 | A1 | B1 | C1 | D1 | E1 | -> TXA |
musig session 2 | A1 | B1 | C1 | D1 | E1 | -> TXB |
musig session 3 | A1 | B1 | C1 | D1 | E1 | -> TXC |
musig session 4 | A1 | B1 | C1 | D1 | E1 | -> TXD |
musig session 5 | A1 | B1 | C1 | D1 | E1 | -> TXE |
Functionally, this is not different; each signing session requires all 5 participants to agree on the outcome in both cases. We will use the latter, though, because it's simpler, and key path spending is more efficient and more private.
Now notice what happens if, let's say, Alice is the one who funds the output containing this 5 of 5 MuSig taproot output, and demands that she be provided signatures so as to be able to spend it, thusly:
Person | Alice | Bob | Carol | David | Eve |
---|---|---|---|---|---|
Session 1 | σA1 | σB1 ✔️ | σC1 ✔️ | σD1 ✔️ | σE1 ✔️ |
Session 2 | σA2 | σB2 | σC2 ✔️ | σD2 ✔️ | σE2 ✔️ |
Session 3 | σA3 | σB3 | σC3 | σD3 ✔️ | σE3 ✔️ |
Session 4 | σA4 | σB4 | σC4 | σD4 | σE4 ✔️ |
Session 5 | σA5 | σB5 | σC5 | σD5 | σE5 |
(The coin value is U
from now on).
If at the time we set up the address (and we of course all have to interact to do this - just like with any multisig), we have the signatures marked with checkmarks all be shared (amongst everybody to keep it simple), then you'll notice that Alice is the unconditional owner of the coin. She has 4 signatures given to her, meaning she can spend using path 1 at any time. While crucially none of the other parties (including Bob, who doesn't have Alice's signature on path 2) can spend the coin, and Alice knows that - she hasn't shared her signatures for other paths. So far so good.
As we explained earlier, transferring a private key does not transfer ownership. Similarly, if Alice gives her signature σA2 to Bob, so that he is now able to spend from Path 2, it sadly is not a functional payment, since Alice can still use Path 1, any time. How to get round this?
One thought that might spring to mind is: in Lightning, they have a penalty mechanism, to punish a cheater on one side of a channel, who spends an old state, by giving all the money to the other side of the channel. If we tried to apply that idea here it wouldn't work. Here's why, concretely:
- We set everything up. Alice owns the coin.
- Alice transfers to Bob by giving her signature σA2, but also gives a 'promise' that if she ever spends using Path 1 (σA1), then Bob can claim a penalty (more than the coin being spent). This stops her being incented to spend using Path 1.
- Bob now transfers to Carol. What is Carol's assurance that Bob won't spend, now, using Path 2? The same - there would be a penalty payment from Bob to Carol. BUT! What is Carol's assurance that Alice won't spend the coin using Path 1?
The problem isn't that there's not a penalty (Bob could even send proof to Carol that the penalty existed). The problem is where it goes. If it goes to Bob, how does Carol know that Bob and Alice are not colluding, or are not both called Sybil? If they work together, then a penalty from Alice to Bob is meaningless and so Carol actually has no defence at all, and so this scheme fails.
This applies to any number of parties greater than two. It will never be enough to be safe from the misbehaviour of one party, you need to be safe from the misbehaviour of all.
One way to try to solve it is with burned funds. I claim that this could be viable, but it is very problematic, to the point I would not pursue it. An honest party attacked with a double spend of U
, when the defence against it is burned funds, does not gain from the burned funds, thus an additional positive incentive as well as the burn, is required. Moreover, whether that extra incentive helps is very dependent on how much the attacker could bribe you to not execute the burn. If you look into it, you find that this approach is too game theoretically fragile.
We might conclude, from this line of reasoning, that every other party must benefit whenever one cheats, so that even if there is only one honest actor, they always have a defence. For example, with 5 parties as described, we can imagine that Alice might have to forfeit, to all of Bob, Carol, David and Eve, an amount strictly larger than U
; thus her fidelity bond would be roughly 4 x (U + δ). This wouldn't be great, but we'll address this point later. Before we do, let's at least sketch out one way we could create such a forfeit or penalty.
The fidelity bond concept is widely enough known; in its traditional sense it exists to be used as a penalty in a contract violation, and that's how we'd use it here.
Participants put up a certain amount of money in a 'fixed' location (fixed by a timelock). Let's say Alice pays to an output with a script like this:
EITHER (to Alice after 100 days) OR (to key TA AND CTV <hash of tx1>)
, where tx1 is fixed to have 4 outputs, one each for Bob, Carol, David, Eve, each have amount U + δ.
(The use of δ here is of course just to create a negative incentive to cheat, even in the worst case.)
Here CTV refers to the currently-under-discussion (Jan 2022) covenant op code which may be added to Bitcoin (see CHECKTEMPLATEVERIFY). Any similar scheme that allows us to constrain where an output can be spent, rather than who can spend it, could play that role, in the following.
So this type of fidelity bond has a get-out clause, instead of just 'lock your funds for time 100 days', but: that get-out clause can only pay out to Alice's counterparties. In the normal case she'll lose more than 4 time the value of U
, so that's a disaster for her; but even in the most adversarial case, where Alice colludes with 3 others (Bob, David, Eve) in an attempt to attack one victim (Carol), she (they) will still lose more than they gain (δ), and more important than that: Carol will gain more than she loses.
Now, when Alice creates this "fidelity bond", she'll need to actually know the private key tA corresponding to the pubkey TA (we'll see why shortly), but she won't ever want to use it! Nor to publish it such that anyone else could immediately destroy her funds.
Before we fix up the inefficiency of that fidelity bond, let's flesh out how the transfer of value happens.
Given the above setup created at the same time as the set of 5x5 paths in the taproot output (we'll now call it the pathcoin output, value U
), we can force a cryptographic linkage between that, and the fidelity bond outputs. When Alice sends σA2, she will actually send, to Bob, this full list:
σA1' , (σA2, ... σA5) The ' is for a signature adaptor rather than an actual signature. For the basics of signature adaptors and how they can be used to tie the revealing of a secret to the broadcast of a signature, see here and here. They require Schnorr signatures, which is one reason that this is only realizable in taproot.
Giving rise to this situation:
Person | Alice | Bob | Carol | David | Eve |
---|---|---|---|---|---|
Session 1 | σA1 ❌ | σB1 ✔️ | σC1 ✔️ | σD1 ✔️ | σE1 ✔️ |
Session 2 | σA2 ✔️ | σB2 | σC2 ✔️ | σD2 ✔️ | σE2 ✔️ |
Session 3 | σA3 ✔️ | σB3 | σC3 | σD3 ✔️ | σE3 ✔️ |
Session 4 | σA4 ✔️ | σB4 | σC4 | σD4 | σE4 ✔️ |
Session 5 | σA5 ✔️ | σB5 | σC5 | σD5 | σE5 |
This short list of values she sends (should be around 320 bytes(?), in this toy case, with TA implicit if it was shared upfront), we're claiming here that Alice has effectively entirely transferred control of the pathcoin utxo to Bob. (And it does mean full control - he can spend it immediately or at any time before some long fidelity bond timeout).
It could be sent in a simple format via email or text or literally anything. Not requiring a p2p network or an interactive exchange (Bob can be asleep when you send it, he can pick it up on a third party server etc. etc., you get the idea). Obviously there is a liveness requirement of Bob - check for a cheating transaction, so the advance here isn't so much "offline" transactions, it's non-interactive and off-chain transactions.
But first, what exactly are we claiming happened here? By sending the signature adaptor σA1', on point TA, for the signature σA1, which is the signature Alice would have to broadcast to spend the pathcoin output herself, it means that if she ever does so, Bob would learn tA (the formula is just tA = σA1 - σA1'), the private key of TA, and as discussed above, could use the fidelity bond (at least before the timeout) to claim an amount as penalty, greater than U
.
The necessity to create this adaptor is why Alice must actually know the value tA.
A sane Alice will actually therefore be much more likely to want to delete the signature σA1 than use it, and perhaps the value tA also, but there is a finesse in there that we'll get to later.
But for now, let's follow the logic down the chain:
After Alice has paid Bob as per above, the situation looks like the previous table.
Bob has 100% ownership. He can either spend the coin outside, or, pay Carol by repeating the process. He will send a longer list of items:
σA1'(TA), σB2'(TB), (σA3, ... σA5), (σB3, ... σB5)
Basically, he's sending Alice's revocation of her own claim, Alice's authorization of future payments in the path, and also his own revocation of his own claim, and his own authorization of future payments on the path.
Though it's a slightly longer list, it's still something you can trivially email. (It's crudely an O(N2) scaling in this simple model, but we hit other limitations before that matters!).
After this second transfer the table looks like this:
Person | Alice | Bob | Carol | David | Eve |
---|---|---|---|---|---|
Session 1 | σA1 ❌ | σB1 ✔️ | σC1 ✔️ | σD1 ✔️ | σA2 ✔️ |
Session 2 | σA2 ✔️ | σB2 ❌ | σC2 ✔️ | σD2 ✔️ | σA2 ✔️ |
Session 3 | σA3 ✔️ | σB3 ✔️ | σC3 | σD3 ✔️ | σA2 ✔️ |
Session 4 | σA4 ✔️ | σB4 ✔️ | σC4 | σD4 | σA2 ✔️ |
Session 5 | σA5 ✔️ | σB5 ✔️ | σC5 | σD5 | σA2 |
At this point, like Alice, Bob would rationally immediately delete his σB2 value so as not to accidentally get his fidelity bond destroyed by revealing tB .
The crucial point is of course, that here, Carol is defended against any collusion between Alice and Bob. If either of them (or both) tried to spend the pathcoin utxo, they would be revealing to Carol their adaptor secrets which would allow an immediate and uncontested penalty transaction, taking from the attacker more than they lost. Notice that in a case where the attacker is more than one step up the path, it doesn't matter who uses the adaptor to claim the punishment; everyone except the attacker gets it.
This latter asymmetry (not only the stolen-from gets rewarded) could incentivise malicious attempts to reveal the adaptor, which is why I said earlier: the rational thing to do is to indeed delete the full signature as soon as the adaptor has been revealed. They are indeed toxic waste.
Anyway, just for completion, here is what Carol would send to David:
σA1'(TA), σB2'(TB), σC3'(TC), (σA4, σA5), (σB4, σB5), (σC4, σC5),
And David to Eve:
σA1'(TA), σB2'(TB), σC3'(TC), σD4'(TD), (σA5), (σB5), (σC5), (σD5)
Now we've laid out the general idea, let's address the main limitations to the construction:
- This is a single coin with a single denomination
U
. - This is only allowing payment along one path (any person can cut the path short of course, by spending the coin, but the most that can happen is A->B->C->D->E). This is such a huge limitation that it makes the construction as-is nearly 100% impractical (you could find a use-case where this is viable, but .. you'll struggle).
- This requires allocation of capital to an FB of value approximately N x U, where N is the length of the path.
All three of these limitations are best described as 'very very big' :)
In the rest of this document I'm going to propose a solution to (3), but I have only some unclear ideas about (2), and no particular ideas right now about (1).
As discussed, (3) is a deal breaker, as presented, to doing long paths. Nobody would reasonably lock up 100 times the value of a coin to spend it.
Can we make it so that each participant only has to put up a bond of U + δ, not N x (U + δ)? I claim we can.
Let's define some terms: FA means the utxo which represents a fidelity bond for A. CTV(tA)-> means a script condition that forces the spending to the output indicated by the forwards arrow, but where the signature requires knowledge of the secret tA (as discussed above, this secret will usually be revealed with reference to an adaptor signature on another, now illegal, spending event). H(SC)-> is as for CTV(tA)-> except the condition is just the knowledge of a secret S, in this case owned by C.
Our goal will be that the fidelity bond, before the timeouts indicated as TLX, of party 1 will be claimable only by party 2, who is the aggrieved party, i.e. specifically the current holder of the pathcoin utxo, and we want this to be the case even though there is only forwards transfer of data as outlined above, i.e. we don't want to renegotiate contracts with everyone during payment events.
Let's start with Alice, making this chain of spends for her fidelity bond:
FA script:
(A and TLA) OR (CTV(tA) -> (B and TLB) OR (CTV(tA) AND H(SB) -> (C and TLC) OR (CTV(tA) AND H(SC) -> (D and TLD) OR (CTV(tA) AND H(SD) -> E))))) ;
tA <-> σA1'
Unpacking: rather than Alice just locking a penalty to her adaptor σA1', she's pre-creating a chain of payouts of the penalty. When she pays Bob, he'll get the adaptor and know that he can wait on the TL_B before claiming the coin via that utxo. He'll know that Carol will not be able to cheat (colluding with Alice) by pulling it forwards into the third utxo, because it's locked to a secret S_B) that only he controls. Those S secrets block all similar forms of collusive attack.
Then if later Bob pays Carol, he'll transfer (σA1') and also transfer SB, (as well as the signatures as described above). That means that Carol will be assured that if Alice spends, she'll be able to use CTV signatures to push it forwards to the third utxo, but as before, she knows it won't go any further due to her keeping hold of SC, and wait for the TL_C. And so on.
And of course it doesn't stop there. Bob will need to do something similar:
FB script:
(B and TLB) OR (CTV(tB) -> (C and TLC) OR (CTV(tB) AND H(SC2) -> (D and TLD) OR (CTV(tB) AND H(SD2) -> E))))) ;
tB <-> σB2'
At the point where Carol receives the coin, Bob has rescinded all control of the funds, so he has no need for a penalty tx vs Alice. So Carol will have effective control of the coin in both the above paths, in the event that either of them illegally spends the pathcoin utxo. They can't both do it, of course (although they could both stupidly reveal the signature), because only one gets onto the bitcoin network.
Repeating this all the way down the path gives us another "triangular matrix" type situation (i.e. there are ~ NxN/2 of these FBX outputs). The end result is that every honest owner can claim exactly one of these outputs as penalty, after a time delay which needn't be very long.
For this reason, in this (admittedly complex!) construction, each participant will only have to fund their FBX output with an amount somewhat larger than the pathcoin utxo, i.e. U + δ, not N times that amount.
With this preparation in advance, we could reasonably consider constructing paths of length such that the O(N2) scaling of the initial setup signature transfer does not become overwhelming. I would tentatively suggest numbers N between 100 and 1000 are at least reasonable, depending on .... things.
What I certainly can't claim is that this construction is particularly useful. Remember that the root cause of the inflexibility is: we want each party to be able to pay forwards without any contract renegotiation, which means we have to 'expand out' all the possible future changes of ownership at the start.
It's certainly possible to try to construct a (yet more complex) version of PathCoin that allows multiple different paths amongst the same set of participants, but note that the number of paths is factorial in N, hence this is only even worth considering for very small numbers of participants (<=10 probably).
Whether there is a smart usage of other opcodes/signature constructions (for example, ANYPREVOUT) that would extend this out to be usable for different paths in some ways is .. an exercise for the reader!
This is more just musing about (2) than really attempting to solve it, for now.
One could imagine taking a current owner (say: David) who wants to then move the coin in a different direction than to Eve, taking the existing set of data (signature adaptors, signatures, hash secrets) that constitute his defence against malicious spending, and therefore constitute his current unconditional ownership, and using that as a starting point for the creation of a new path. This approach is obviously nontrivial, because: all the previous owners remain "in play" (and this can only done before the timelock that prevents them swiping out their FBs and then illegally spending). Also, David would have to convice a new bunch of potential owners (Fred, Grace, Harry, Ivy perhaps) that they do not have a threat from the earlier owners. I haven't yet figured out if that is possible, but perhaps it is, and if it or something similar could work, then chaining such paths almost gets it to the point of being practically useful (though still a bit too clunky, really, even given the wow factor of 'send money like email, without hitting the chain'; you have fixed denominations and you still have to decide upfront who to pay next, or otherwise rejig).
i think i don't understand the weeds enough yet, but maybe let me try at a high level:
each participant should have 1 path with O(1) storage space. That path looks like:
All that I'm commenting is that by binding
fraud proof
to the combination ofTo do an update, holder i first "blind signs" for transfering to holder i+1, and then revokes signature i and includes all i-j revokations.
If signature i appears on the network, then any party has PERIOD to generate a fraud proof from it.
However, if i+1 shows up, and there is no revokation known, then no one can steal.
it's possible to use the same path per person many times over because generating a revokation is bound to a specific blinded signature, and not to just the key.