Context is interaction with external UTXOs, which can mean a person signing their input in a CoinJoin transaction with someone else, or, what is currently more common, it can mean a dapp building a TX for you and adding some contract UTXO(s) and then sending the signing request to your wallet through WalletConnect.
How do WalletConnect dapps work? You give your address to the dapp, then the dapp does:
- Finds the current contract UTXOs
- Finds enough UTXOs belonging to your address to fund the interaction
- Builds a transaction spending both contract UTXOs and your UTXOs
- Gives your wallet the constructed transaction, and then your wallet signs it and broadcasts it
Here’s the thing: if you have just the raw TX, you only know the TXID:n
of the supposed contract UTXO. You know your own UTXO(s) details because your wallet will normally have it cached.
With SIGHASH_ALL, you can still produce a signature, without ever learning about exact contents of the supposed dapp’s contract UTXO(s), because your signature covers contents only for your own UTXO and not of other input’s UTXOs, it covers other inputs only by their prevout reference (the TXID:n
) so you’d be blindly accepting to interact with those, at this point they’re unknown UTXOs which you accept to pull into your TX.
What if the dapp is a fake dapp by some adversary, trying to trick you into interacting with some other contract? You can’t tell just from the raw TX given to you for signing. You can either trust the dapp, or you can look up other input’s UTXOs to check what exactly are you asked to interact with.
To verify the contents, you must look up the full source TX of the UTXO, and verify the hash matches the input’s prevout hash. This can be up to 1 MB per input.
With SIGHASH_UTXOS you can avoid this, because you can look up just the individual UTXO from some indexer like Fulcrum. You still can’t verify it without downloading the whole TX, BUT, you can skip verification if you’re signing with SIGHASH_UTXOS because you know that the signature will be failed by the network if the data you got was wrong, so you know that either: the data is correct and TX will go through, or if the data was wrong then TX will fail, so you will be saved from interacting under false pretenses.
So, at the edge, if you want to avoid interacting with unknown UTXOs, the difference can be 999968 bytes per input (1 MB of full TX vs 32 bytes for just 1 P2SH BCH UTXO).