[bitcoin-dev] BIP sighash_noinput

ZmnSCPxj ZmnSCPxj at protonmail.com
Fri May 4 09:15:41 UTC 2018

Good morning Christian and list,

It seems to me, that `SIGHASH_NOINPUT` may help make some protocol integrate better with existing wallets.

I remember vaguely that `SIGHASH_NOINPUT` was also mentioned before in LN discussions, when the issue of transaction malleation was considered (before SegWit, being totally uncontroversial, was massively adopted).  The sketch below, I believe, is somewhat consistent with how it could have been used in funding a channel.

Consider a CoinSwap protocol.  Each side writes a transaction that pays out to an ordinary 2-of-2 multisig address.  But before each side writes and signs that transaction, it first demands a timelocked backout transaction to let them recover their own funds in case it falls through (more generally, every offchain protocol has a similar setup stage where some way to back out is signed before all parties enter into the contract).

Now, without `SIGHASH_NOINPUT`, we would first require that the initial funding transaction be written (but not signed and broadcast), and then the txid to the other side.  The other side then generates the backout transaction (which requires the txid and outnum of the funding outpoint) and returns the signature for the backout transaction to the first side.

Because of this, an implementation of CoinSwap needs to have control of its own coins.  This means that coin selection, blockchain tracking, and mempool tracking (i.e. to handle RBFs, which would invalidate any further transactions if you used coins received by RBF-able transactions while unconfirmed) needs to be implemented.

But it would be much nicer if instead the CoinSwap implementation could simply say "okay, I started our CoinSwap, now send X coins to address A", and then the user uses their ordinary wallet software to send to that address (obviously before the CoinSwap can start, the user must first provide an address to which the backoff transaction should pay; but in fact that could simply be the same as the other address in the swap).

1.  The user will not have to make a separate transfer from their wallet, then initiate a swap, then transfer from the CoinSwap implementation to their usual wallet: instead the user gets an address from their wallet, initiates the swap, then pays to the address the CoinSwap implementation said to pay and wait to receive the swapped funds to their normal wallet.
2.  Implementing the CoinSwap program is now somewhat easier since we do not need to manage our own funds: the software only needs to manage the single particular coin that was paid to the single address being used in the swap.
3.  The smaller number of required features for use means easier implementation and testing.  It also makes it more likely to be implemented in the first place, since the effort to make it is smaller.
4.  The lack of a wallet means users can use a trusted wallet implementation (cold storage, hardware wallet, etc) in conjunction with the software, and only risk the amount that passes through the CoinSwap software (which is smaller, since it does not have to include any extra funds to pay for fees).

With `SIGHASH_NOINPUT`, we can indeed implement such a walletless CoinSwap (or other protocol) software.  We only need to provide the public keys that will be used in the initial 2-of-2, and the other side can create a signature with `SIGHASH_NOINPUT` flag.

The setup of the CoinSwap then goes this way.  The swapping nodes exchange public keys (two for each side in this case), they agree on who gets to move first in the swap and who generates the preimage, and then they agree on what the backout transactions look like (in particular, they agree on the address the backout transactions spend) and create signatures, with `SIGHASH_NOINPUT`.  In particular, the signatures do not commit to the txid of the transaction that they authorize spending.  The CoinSwap sofwares then turn around to their users and say "okay, send to this address", the users initiate the swap using their normal wallet software, the CoinSwap software monitors only the address it asked the user to use, then when it appears onchain (the CoinSwap software does not even need to track the mempool) it continues with the HTLC offers and preimage exchanges until the protocol completes.

In a world where walletless CoinSwap exists, consider this:

1.  A user buys Bitcoin from an exchange.  The exchange operates a wallet which they credit when the user buys Bitcoin.
2.  The user starts a CoinSwap, giving the destination address from their cold-storage wallet.
3.  The CoinSwap tells the user an address to send to.  The user withdraws money from the exchange using that address as destination (1 transaction)
4.  The user waits for the CoinSwap to finish, which causes the funds to appear in their cold-storage wallet (1 transaction).

If CoinSwap implementations all needed their own wallets, then instead:

1.  A user buys Bitcoin from an exchange.
2.  The user withdraws the funds from the exchange to a CoinSwap implementation wallet (1 transaction).
3.  The user performs a CoinSwap which goes back to the CoinSwap implementation wallet (2 transactions).
4.  The user sends from the CoinSwap wallet to their cold storage (1 transaction). (granted, the CoinSwap implementation could offer a feature that immediately transfers the swapped funds to some other wallet, but we still cannot get around the transfer from the exchange to the CoinSwap wallet)

A drawback of course, is that `SIGHASH_NOINPUT` is an unusual flag to use; it immediately paints the user as using some special protocol.  So much for `SIGHASH_NOINPUT` CoinSwap.


More information about the bitcoin-dev mailing list