📅 Original date posted:2022-09-04
📝 Original message:Over the past few days I've figured out a novel way to batch transactions together into blocks, thereby compacting the transaction size and increasing the transactions-per-second. This is all on layer 1, without any hardforks - only a single softfork is required to add MuSig1 support for individual invoice addresses.
The nucleus of the idea was born after a discussion with Greg Maxwell about a different BIP (Implementing multisig using Taproot, to be specific)[1]. He suggested to me that I should add MuSig1 signatures into the Taproot script paths.
After some thinking, I realized a use case for MuSig1 signatures as a kind of on-chain Lightning Network. Allow me to explain:
LN is very attractive to users because it keeps intermediate transaction states off-chain, and only broadcasts the final state. But without mitigations in the protocol, it suffers from two disadvantages:
- You have to trust the other channel partner not to broadcast a previous state
- You also have to trust all the middlemen in intermediate channels not to do the above.
Most of us probably know that many mitigations have been created for this problem, e.g. penalty transactions. But what if it were possible to create a scheme where so-called technical fraud is not possible? That is what I'm going to demonstrate here.
My scheme makes use of MuSig1, OP_CHECKLOCKTIMEVERIFY (OP_CLTV) timelock type, and negligible OP_RETURN data. It revolves around constructs I call "multipayment channels", called so because they allow multiple people to pay in one transaction - something that is already possible BTW, but with much larger tx size (for large number of cosigners) than when using MuSig1. These have the advantage over LN channels that the intermediate state is also on the blockchain, but it's very compact.
A channel consists of a fixed amount of people N. These people open a channel by creating a (optionally Taproot) address with the following script:
<blockheightofoutput+desiredwaitingblocks>* OP_CTLV OP_DROP <N-of-N MuSig1> OP_CHECKMUSIG**
Simultaneously, each of the N participants receives the N signatures and constructs the N-of-N MuSig. Each participant will use this MuSig to generate his own independent "commitment transaction" with the following properties:
- It has a single input, the MuSig output. It has an nSequence of desiredwaitingblocks. <This prevents the output from being spent immediately.>
- It has outputs corresponding to the addresses and balances of each of the participants in the agreed-upon distribution.
Disadvantage: Because the N-of-N signature is given to all participants, it might be leaked into the public and consequentially anybody can spend this transaction after the timelock, to commit the balance.*** On the other hand, removing the timelocks means that if one of the participants goes missing, all funds are locked forever.****
A second output with a script OP_RETURN <32-byte connection ID> can be added to the transaction to enable L1 channel discovery.
Full nodes parsing the blockchain can maintain a list of connection IDs to connect to (but without a non-malleable refund transaction, nobody is going to use this). SPVs can simply export a list of them from Full Nodes.
A connection only lasts for one transaction. Spending the output to another MuSig of the above format will create a new connection if it spends to a similarly-constructed MuSig output with different signature. In all cases, the current connection is destroyed.
*This introduces a variable grace period, in blocks, after which anybody can broadcast this transaction to commit the channel funds distribution to each of the participants' addresses. blockheightofoutput is the block height of the musig output, and desiredwaitingblocks is the maximum number of blocks the connection can stay alive for.
**This implies that a hypothetical OP_CHECKMUSIG would take a single aggregated signature, a single aggregated public key, and an integer N that denotes how many public keys were combined together. I elected not to overload OP_CHECKSIG since MuSig and regular signatures are both valid for the same address types. This part is a rought draft and requires lots of work on making an OP_CHECKMUSIG opcode that satisfies the requirements of multipayment channels.
***This is quite a bad flaw of this scheme because it means that all the participants must be trustworthy - you can't use this in trustless environments. I appreciate any ways on how to implement non-malleable refund transactions with single (non-aggregated) signatures!
****Perhaps the best solution is to offer both alternatives: <N-of-N MuSig1> OP_CHECKMUSIG in a public scenario where none of the participants want to face the prospect of losing their money, and <blockheightofoutput+desiredwaitingblocks>* OP_CTLV OP_DROP <N-of-N MuSig1> OP_CHECKMUSIG with signature sharing in private scenarios.
This draft is very crude and parts have not been fully developed. Tips for fleshing it out is much appreciated. Not that there's anything wrong with LN for that matter, I'm just concerned about the security reprocussions of not broadcasting intermediate transactions, and its enabling of crime.
- Ali
[1]: https://bitcointalk.org/index.php?topic=5410553.0