Skip to content

Instantly share code, notes, and snippets.

@jtremback
Last active February 27, 2022 13:47
Show Gist options
  • Star 5 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save jtremback/058daafe1116435b6a2e to your computer and use it in GitHub Desktop.
Save jtremback/058daafe1116435b6a2e to your computer and use it in GitHub Desktop.
Universal Payment Channels

I am not actively updating this gist and it is already out of date. Please see http://altheamesh.com/documents/universal-payment-channels.pdf

Universal Payment Channels

Jehan Tremback

Zackary Hess

Introduction

In this paper, we lay out a specification for Universal Payment Channels. UPC is a type of payment network that can handle any type of fiat or crypto currency, as well as physical or virtual goods, as long as these goods can be owned "on paper" and kept in escrow. Furthermore, UPC routes payments across currencies, with the network automatically arriving at the best exchange rate.

The vast majority of UPC payments are made without ever interfacing with any bank or blockchain. This means that there can be an almost unlimited amount of payments that do not put any strain on bank servers, or add anything to the blockchain. The only time that the bank or the blockchain is involved is when a network participant wants to take money out of the network, or put money into it.

This also makes it very easy for application developers to interface with UPC. The only thing that an application needs to do is to send cryptographically signed messages on behalf of the user. For example, there is software in development using UPC to allow internet backbone routers to pay one another per-packet, many times each second. These payments can happen in dollars, dogecoins, or any other currency. Even though the volume of payments created by this type of software is oceanic, the banks and blockchains backing up the network are rarely contacted.

UPC consists of a series of "channels" between network participants. A channel is an escrow arrangement between two parties and a cryptocurrency, a bank, or some other kind of institution. It allows the parties to exchange payment trustlessly, by sending signed, updated escrow balances to one another (not to the bank). At any time, each of the participants can be confident that they will be able to retrieve every cent (or satoshi!) that they are owed.

UPC's key innovation is a routing protocol inspired by the protocols that power the internet. It uses this routing protocol to route payments across interconnected channels, finding the cheapest path.

The internet is a packet-switched network. Any computer on the internet knows it can reach any other computer, and the network grows organically and routes around damage. Routing protocols ensure that each packet takes the fastest path through the network.

UPC is a payment-switched network. Any network participant can pay any other, and UPC grows organically and routes around damage. UPC ensures that each payment takes the cheapest path through the network.

Basic Channel

A channel is created when two parties put money in escrow with an entity such as a bank or a blockchain. The money is put into escrow with the understanding that at some point in the future it will be released upon receipt of a transaction signed by both parties. This transaction has a special number on it called a "nonce", and specifies two additional actions to take before transferring the funds back to the participants.

  1. Transfer a certain amount of money from one participant to another.
  2. Wait for a certain hold period before transferring the funds back. If someone gives you another transaction signed by both parties, and this transaction's nonce is higher, throw the current transaction out and use the new one, restarting the hold period.

Alice and Bob exchange transactions back and forth, changing the transfer amount to make payments to one another. Each time they change the transfer number, they increment the nonce. To accept a payment, both of them sign it.

  • If Bob disappears, Alice can post the last signed transaction and collect the money owed her without Bob's involvement, after the hold period is over.

  • If Bob tries to cheat by posting an old transaction where he's doing better than he is currently, Alice can post the latest transaction which will override the old one. As long as Alice checks whether Bob has cheated at least once every hold period, she can stop him from cheating.

Opening transaction


  • Opening Transaction:
    • Party 1: Public key or other signature verification information for one of the participants.
    • Party 2: Public key or other signature verification information for the other participant.
    • Amount 1: The amount of money that Party 1 has placed in the channel
    • Amount 2: The amount of money that Party 2 has placed in the channel
  • Signature 1: Party 1's signature.
  • Signature 2: Party 2's signature.

The opening transaction serves mostly to identify the channel and the parties, and place the money in escrow.

Update transaction:


  • Update Transaction:
    • Nonce: A number which is incremented with each new update transaction.
    • Transfer: The amount of money to transfer from Party 1 to Party 2 (can be negative).
    • Hold Period: An amount of time (or number of blocks) to wait before closing the channel and transferring funds, after a update transaction has been published
  • Signature 1: Party 1's signature.
  • Signature 2: Party 2's signature.

The update transaction is sent from Party 1 to Party 2 and serves to transfer the money. The vast majority of these are never posted to the bank or blockchain.

Making payments:

To make payments to one another, Alice and Bob pass signed update transactions back and forth.

If Alice wants to pay Bob, she adjusts Transfer, signs the update transaction, then passes it to Bob. None of this involves the transaction being given to anyone else, and can happen instantly. Alice and Bob can do this as many times as they want.

To actually claim the funds, either party posts the latest update transaction. After Hold Period is over, the channel closes: Transfer is subtracted from Amount 1 and added to Amount 2, and the amounts are transfered back to the accounts of the participants.

This means that if Alice disappears or becomes uncooperative, Bob can still get his money out by waiting for the Hold Period to end.

Stopping cheaters:

If a update transaction with a higher Nonce is published before a transaction closes, it overrides the older transaction.

If Bob tries to cheat by publishing an old update transaction where he has a higher amount than he does currently, Alice can simply publish the update transaction with a higher Nonce.

Another option is to "slash" Bob by transferring all his funds to Alice if she is able to post a higher-nonced transaction after him. This makes a cheating attempt riskier and may be beneficial in some situations.

Payment Conditions


  • Conditions:
    • 1:
      • Transfer: Add this to the channel's total Transfer if Function returns true.
      • Condition(argument): Takes an argument and returns either true or false

Update transactions can have a list of Conditions. A Condition consists of Transfer, a number to add to the Channel's total Transfer, and the Condition which takes an argument and returns either true or false. The Function does not have any side effects, it is a pure function.

Pieces of data called Fulfillments can be posted during the Hold Period. They only need to be signed by one of the channel participants.


  • Fulfillment:
    • Condition: Which condition does this fulfill?
    • Argument: Data to evaluate Condition with.

When a Fulfillment is posted, it is evaluated by its Condition. If the Condition evaluates to true, the Condition's Transfer is added to the channel's total Transfer, and the Condition is removed from the list.

Conditions can be used to implement complex logic over channels to give them enhanced capabilities.

For instance, here is how Alice and Bob would implement a 'hashlock' transaction. Specifically, Alice wants to guarantee that she will transfer 32 coins to Bob if he can supply the secret that hashes to "59A1904325CCB". Alice is Party 1 and Bob is Party 2.

Establishing a condition


Alice to Bob

  • Update Transaction:
    • Nonce: 12
    • Transfer: -34
    • Hold Period: 8
    • Conditions:
      • 1:
        • Transfer: 32
        • Condition(secret): if sha3(secret) is equal to "59A1904325CCB", return true; else return false
  • Signature 1: Alice's signature

Closing the channel

If Bob wants to close the channel at this point, he posts the Update Transaction, along with the signatures. He also posts a Fulfillment containing the secret for Condition 1.


Bob posts

  • Update Transaction:
    • Nonce: 12
    • Transfer: -34
    • Hold Period: 8
    • Conditions:
      • 1:
        • Transfer: 32
        • Condition(secret): if sha3(secret) is equal to "59A1904325CCB", return true; else return false
  • Signature 1: Alice's signature
  • Signature 2: Bob's signature

Bob also posts

  • Fulfillment:
    • Condition: 1
    • Argument: "theSecret"

Fulfilling the condition without closing

Of course, most of the time Bob doesn't want to close the channel right away. Bob can now prove that he could unlock the money if he wanted, so Alice might as well adjust the Transfer as specified by the Condition. Bob sends the secret to Alice, who adjusts the channel's Transfer, increments the Nonce, removes condition 1, and signs a new Update Transaction.


Bob to Alice

  • Fulfillment:
    • Condition: 1
    • Argument: "theSecret"

Both sign

  • Update Transaction:
    • Nonce: 13
    • Transfer: -2
    • Hold Period: 8
  • Signature 1: Alice's signature
  • Signature 2: Bob's signature

Cancelling the condition

Similarly, Bob can inform Alice that he will never be able to find the hashlock secret. In this case there is no reason for them to keep passing a condition that will never be fulfilled back and forth.


Bob to Alice

  • Cancellation
    • Condition: 1

Both sign

  • Update Transaction:
    • Nonce: 13
    • Transfer: -34
    • Hold Period: 8
  • Signature 1: Alice's signature
  • Signature 2: Bob's signature

Multihop channels

With the help of a hashlock condition, it is possible to trustlessly route payments across multiple hops. Let's say that Alice would like to transfer some coins to Charlie, but she does not have a channel open with him. If she has a channel with Bob, and Bob has a channel with Charlie, the coins can be transferred.

First, Alice sends a secret to Charlie:


Alice to Charlie

  • Secret: "theSecret"

Then, Alice sends a hashlocked payment to Bob:


Alice to Bob

  • Update Transaction:
    • Nonce: 13
    • Transfer: -2
    • Hold Period: 8
    • Conditions:
      • 1:
        • Transfer: -101
        • Condition(secret): if sha3(secret) is equal to "73B88F8C24EAA", return true; else return false
  • Signature 1: Alice's signature

Notice that Alice has sent Bob 101 coins instead of 100, as Bob charges her a 1% fee for routing payments.

Now, Bob sends the payment along to Charlie (Bob is Party 1 and Charlie is Party 2 in their channel):


Bob to Charlie

  • Update Transaction:
    • Nonce: 42
    • Transfer: 56
    • Hold Period: 10
    • Conditions:
      • 1:
        • Transfer: 100
        • Condition(secret): if sha3(secret) is equal to "73B88F8C24EAA", return true; else return false
  • Signature 1: Bob's signature

To claim the payment, Charlie can post this agreement, along with the secret that Alice sent him.


Charlie posts

  • Update Transaction:
    • Nonce: 42
    • Transfer: 56
    • Hold Period: 10
    • Conditions:
      • 1:
        • Transfer: 100
        • Condition(secret): if sha3(secret) is equal to "73B88F8C24EAA", return true; else return false
  • Signature 1: Bob's signature
  • Signature 2: Charlie's signature

Charlie also posts

  • Fulfillment:
    • Condition: 1
    • Argument: "theSecret"

Once Charlie has posted the update transaction, Bob is able to see the secret and unlock his hashlocked funds from Alice. In this way, a network of nodes are able to exchange payment trustlessly with one another. One interesting aspect of this system is that while Alice and Bob both need to have channels open on the same blockchain or bank, and Bob and Charlie need to have channels open with the same blockchain or bank, Alice and Charlie do not. As long as banks are willing to put money in escrow and honor channel update transactions for their customers, a payment network can be created that spans banks and countries.

Multihop payments across currencies

In the multihop payment example above, it is not neccesary for Alice and Bob's channel to be with the same bank or blockchain as Bob and Charlie's channel. It's actually not even neccesary for the channels to be holding the same currency.

If Alice wants to send Charlie some Euros, and Charlie and Bob have a Euro channel open, it can be done:

  $   €
 / \ / \
A   B   C

Alice needs to know how many dollars she needs to send Bob to have him send Charlie the right number of Euros (this can also be calculated from Bob's exchange rate and fee). Alice sends the hashlocked dollars to Bob, and Bob sends hashlocked Euros to Charlie. If Charlie is happy with the number of Euros he will receive, he reveals the secret to Bob as usual.

This can also be used to connect two parties transacting in the same currency, across hops of another currency. Let's say that Alice wants to send dollars to Doris, but her only connection to Doris is through Bart and Conrad, who have a channel open on the Dogecoin blockchain:

  $   Ð   $
 / \ / \ / \
A   B   C   D

If Alice knows Bob's fee and exchange rate, and Conrad's fee and exchange rate, she can calculate whether it would be worth it to send Doris payment across Bob and Conrad's Dogecoin channel. This technique could be very powerful for providing payment connectivity between seperate groups of people using non-crypto currency channels, as it will probably be a lot quicker to open a channel on a blockchain vs with a bank. Enterprising individuals can identify parts of the network lacking connectivity and supply it, earning transaction fees for their efforts.

@zack-bitcoin
Copy link

The compression bit at the end is where channels get their anonymity from.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment