
@ gandlaf21
2025-02-17 06:06:48
As promised in my last article:
nostr:naddr1qvzqqqr4gupzp394x6dfmvn69cduj7e9l2jgvtvle7n5w5rtrunjlr6tx6up9k7kqq2k6ernff9hw3tyd3y453rdtph5uvm6942kzuw08y0
In this one we will dive into how exactly an unidirectional payments channel powered ecash mint system would be implemented, using the tech available today! So if you haven't read that article yet, give it a read!
I first intended to write a longwinded article, explaining each part of the system. But then I realized that I would need some visualization to get the message across in a more digestable way. This lead me to create a slide deck, and as I started to design the slides it became more and more clear that the information is easier shown with visualizations, than written down. I will try to give a summary as best as I can in this article, but I urge you, to please go visit the slide deck too, for the best experience:
-----------
### [TAKE ME TO THE SLIDE DECK!](https://uni-chan.gandlaf.com/)
-----------
### Intro
In this article we will go over how we can build unidirectional payment channels on Bitcoin. Then we will take a look into how Cashu ecash mints work, and how we can use unidirectional payment channels to change the dynamics between ecash users and the mint.
Before we start, let me also give credits to nostr:npub1htnhsay5dmq3r72tukdw72pduzfdcja0yylcajuvnc2uklkhxp8qnz3qac for comming up with the idea, to nostr:npub148jz5r9xujcjpqygk69yl4jqwjqmzgrqly26plktfjy8g4t7xaysj9xhgp for providing an idea for non-expiring unidirectional channels, and nostr:npub1yrnuj56rnen08zp2h9h7p74ghgjx6ma39spmpj6w9hzxywutevsst7k5cx unconference for hosting an event where these ideas could be discussed and flourish.
### Building unidirectional payment channels
If you've read the previous article, you already know what unidirectional payment channels are. There are actually a coupple different ways to implement them, but they all do have a few things in common:
1. The `sender` can only send
2. The `Receiver` can only receive
3. They are VERY simple
Way simpler than the duplex channels like we are using in the lightning network today, at least. Of course, duplex channels are being deployed on LN for a reason. They are very versatile and don't have these annoying limitations that the unidirectional payment channels have. They do however have a few drawbacks:
1. Peers have liveness requirements (or they might forfeit their funds)
2. Peers must backup their state after each transaction (if they don't they might forfeit their funds)
3. It is a pretty complex system
This article is not meant to discredit duplex channels. I think they are great. I just also think that in some use-cases, their requirements are too high and the system too complex.
But anyway, let's see what kind of channels we can build!
#### Spillman/CLTV-Channel
The Spillman channel idea has been around for a long time. It's even explained in Tadge Dryjas [Presentation](https://www.youtube.com/watch?v=Hzv9WuqIzA0&t=1969s) on Payment channels and the lightning network from back in the day. I compiled a list of some of the most important propperties of them in the slide below:

Great!
Now that we know their properties, let's take a look at how we can create such a channel ([Slides](https://uni-chan.gandlaf.com/#/11)):

We start out by the `sender` creating a `funding TX`. The `sender` doesn't broadcast the transaction though. If he does, he might get locked into a multisig with the `receiver` without an unilateral exit path.
Instead the `sender` also creates a `refund TX` spending the outputs of the yet unsigned `funding TX`. The `refund TX` is timelocked, and can only be broadcast after 1 month. Both `sender` and `receiver` can sign this `refund TX` without any risks. Once `sender` receives the signed `refund TX`, he can broadcast the `funding TX` and open the channel. The `sender` can now update the channel state, by pre-signing update transactions and sending them over to the `receiver`. Being a one-way channel, this can be done in a single message. It is very simple. There is no need for invalidating old states, since the `sender` does not hold any signed `update TXs` it is impossible for the `sender` to broadcast an old state. The `receiver` only cares about the latest state anyways, since that is the state where he gets the most money. He can basically delete any old states. The only thing the `receiver` needs to make sure of, is broadcasting the latest `update TX` before the `refund TX's` timelock expires. Otherwise, the `sender` might take the whole channel balance back to himself.
This seems to be already a pretty useful construct, due to its simplicity. But we can make it even more simple!

This setup works basically the same way as the previous one, but instead of having a refund transaction, we build the `timelock` spend path directly into the `funding TX` This allows the `sender` to have an unilateral exit right from the start, and he can broadcast the `funding TX` without communicating with the `receiver`. In the worst case, the receiver rejects the channel, and the sender can get his money back after the timelock on the output has expired. Everything else basically works in the same way as in the example above.
The beauty about this channel construct is in its simplicity. The drawbacks are obvious, but they do offer some nice properties that might be useful in certain cases.

One of the major drawbacks of the `Spillman-style channels` (apart from being unidirectional) is that they expire. This expiry comes with the neat property that neither of the party has to watch the chain for channel closures, and the `sender` can operate the channel with zero additional state, apart from his private keys. But they do expire. And this can make them quite inflexible. It might work in some contexts, but not so much in others, where time needs to be more flexible.
This is where `Roose-Childs triggered channels` come into play.
#### Roose-Childs triggered channel
(I gave it that name, named after nostr:npub148jz5r9xujcjpqygk69yl4jqwjqmzgrqly26plktfjy8g4t7xaysj9xhgp and nostr:npub1htnhsay5dmq3r72tukdw72pduzfdcja0yylcajuvnc2uklkhxp8qnz3qac . If someone knows if this idea has been around before under a different name, please let us know!)
`Roose-Childs triggered channels` were an idea developed by Steven and Luke at the nostr:npub1yrnuj56rnen08zp2h9h7p74ghgjx6ma39spmpj6w9hzxywutevsst7k5cx unconference. They essentially remove the channel expiry limitation in return for introducing the need for the `sender` to create a channel backup at the time of channel creation, and for the `receiver` the need to watch the chain for trigger transactions closing the channel.

They also allow for splicing funds, which can be important for a channel without expiry, allowing the `sender` to top-up liquidity once it runs out, or for the `receiver` taking out liquidity from the channel to deploy the funds elsewhere.
Now, let's see how we can build them!

The `funding TX` actually looks the same as in the first example, and similarly it gets created, but not signed by the `sender`. Then, sender and receiver both sign the `trigger TX`. The `trigger TX` is at the heart of this scheme. It allows both `sender` and `receiver` to unilaterally exit the channel by broadcasting it (more on that in a bit).
Once the `trigger TX` is signed and returned to the `sender`, the sender can confidently sign and boradcast the `funding TX` and open the channel. The `trigger TX` remains off-chain though. Now, to update the channel, the `sender` can pre-sign transactions in similar fashion to the examples above, but this time, spending the outputs of the unbroadcasted `trigger TX`. This way, both parties can exit the channel at any time. If the `receiver` wants to exit, he simply boradcasts the `trigger TX` and immediately spends its outputs using the latest `update TX`. If the `sender` wants to exit he will broadcast the `trigger TX` and basically force the `receivers` hand. Either, the `receiver` will broadcast the latest `update TX`, or the `sender` will be able to claim the entire channel balance after the timelock expired.

We can also simplify the `receiver's` exit path, by the `sender` pre-signing an additional transaction `R exit TX` for each update. this way, the `receiver` only needs to broadcast one transaction instead of two.

As we've mentioned before, there are some different trade-offs for `Roose-Childs triggered channels`. We introduce some minimal state and liveness requirements, but gain more flexibility.

#### Ecash to fill in the gaps
(I will assume that the reader knows how ecash mints work. If not, please go check the [slides](https://uni-chan.gandlaf.com/#/43) where I go through an explanation)
Essentially, we are trying to get a lightning like experience, without all the lightning complexities and requirements. One big issue with ecash, is that it is fully custodial. If we can offset that risk by holding most of the funds in a self custodial channel, we can have a reasonable trade-off between usability and self custody.

In a system like that, we would essentially turn the banking model onto its head. Where in a traditional bank, the majority of the funds are held in the banks custody, and the user only withdraws into his custody what he needs to transact, in our model the user would hold most funds in his own custody.

If you ask me, this approach makes way more sense. Instead of a custodian, we have turned the "bank" into a service provider.
Let's take a look at how it would work in a more practical sense:

The `ecash user` would open an unidirectional payment channel to the `mint`, using one of his on-chain UTXOs. This allows him then to commit incrementally funds into the mints custody, only the amounts for his transactional needs. The mint offers connectivity to the lightning network an handles state and liveness as a service provider.
The `ecash user`, can remain offline at all times, and his channel funds will always be safe. The mint can only ever claim the balance in the channel via the `update TXs`. The `mint` can of course still decide to no longer redeem any ecash, at which point they would have basically stolen the `ecash user's` transactional balance. At that point, it would probably be best for the `ecash user` to close his channel, and no longer interact or trust this `mint`.
Here are some of the most important points of this system summarized:

And that is basically it! I hope you enjoyed this breakdown of Unidirectional payment channel enabled Ecash mints!
If you did, consider leaving me a zap. Also do let me know if this type of breakdown helps you understand a new topic well. I am considering doing similar breakdowns on other systems, such as ARK, Lightning or Statechains, if there is a lot of interest, and it helps people, I'll do it!
Pleas also let me know what you think about the `unidirectional channel - ecash mint` idea in the comments. It's kind of a new idea, an it probably has flaws, or things that we haven't thought about yet. I'd love to discuss it with you!
I'll leave you with this final slide:

Cheers,
Gandlaf