I am looking for code examples (in rust-bitcoin, but even in Python) of how to calculate sighash for various input types. Specifically, I need to calculate the sighashes for M of N multisig unlocking script inputs for these transaction types: P2MS, P2SH, P2WSH and P2TR (to determine which M of N keys correspond to the M input signatures).
For example for a P2SH case, I am looking at output 0 in this tx.
In the spending transaction, the input #3 contains a redeem 2 of 3 mutisig script with 3 compressed 33 byte PubKeys
OP_PUSHNUM_2 OP_PUSHBYTES_33 02261f84d51bb64371cb5e9eec3bbc0c0c7320eb7fa9c5076a394a48a9cd74bfd3 OP_PUSHBYTES_33 023e66621cf94ac25d8bb687abef86d01847805d6e9bff8c3999f18f478cde5ab6 OP_PUSHBYTES_33 02d844059fae247b8e1325f56519d1eb7d4b632ec77b9f71f03102167f3c7fa591 OP_PUSHNUM_3 OP_CHECKMULTISIG
and two signatures in the ScriptSig (
OP_PUSHBYTES_72). I concretely want to know which two of the three PubKeys above correspond to these two signatures.
For that, I need to double-loop over the two keys and the three signatures and pass these pairs along with the scriphash into
verify_ecdsa(&script_hash, &signature, &pubkey) from secp256k1, and I would like to understand in detail how to compute the sighashes. I am also not clear if these multisig inputs can have any of these three sighash flags
SIGHASH_NONE, or only the first one is ever used with multisig?
PS. In the Andrew Poelstra's answer, there's an example sighash computation for P2WPKH. Although I do not need the P2(W)PKH cases because I am not trying to verify the blocks, the example involves manually converting the
P2WPKH output into a
P2PKH output by wrapping the pkh into
OP_DUP OP_HASH160 <pkh-from-P2WPKH-out> OP_EQUALVERIFY OP_CHECKSIG and passing the result into
sighash.segwit_encode_signing_data_to(). It would be good to see explicit multisig examples.