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 

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 

bitcoin-dev mailing list

Reply via email to