The PR branch HEAD was 905d672b74 at the time of this review club meeting.
Bitcoin transactions encode spending conditions through a scriptPubKey in outputs and a witness
and scriptSig in the inputs. You can read more about Bitcoin Script
here. In the functional test framework, scripts are represented
class, and can be initialized using an array of opcodes and byte-encoded data.
PR #22363 replaces many manually-constructed
default scripts in the functional tests with helper functions provided in script_util.py.
It also corrects an error in the helper function,
in which the P2SH-wrapped P2WSH script hadn’t hashed the witness script before putting it into the
scriptSig. We’ll use this opportunity to review script and output types.
To test your understanding of scripts and output types, you can try to fill out this table (Hint:
a few cells have been pre-filled, and some cells should remain blank):
What do key_to_p2pkh_script, script_to_p2sh_script, key_to_p2wpkh_script and
script_to_p2wsh_script in script_util.py do? In what cases would we want to use or not use them?
Review of Terminology: Let’s define script code, witness script, redeem script, scriptPubKey,
scriptSig, witness, and witness program (some of these terms are synonymous).
What does the operation OP_HASH160 do? (Hint: what does the script
do when it sees this opcode? What are the differences between the
Review of P2PKH: to send coins to someone by public key hash (pre-segwit), what is included in
the scriptPubKey of the output? What needs to be provided in the input when the coin is spent?
Review of P2SH: to send coins to someone with spending conditions encoded in a script, what is
included in the scriptPubKey of the output? What needs to be provided in the input when the coin is
spent? Why do we use Pay-To-Script-Hash instead of Pay-To-Script?
Review of P2SH-P2WSH: What is the purpose of “P2SH wrapped segwit” outputs? When a non-segwit
node validates a P2SH-P2WSH input, what does it do?
Review of P2SH-P2WSH: When a node with segwit enabled validates a P2SH-P2WSH input, what does it
do in addition to the procedure performed by a non-segwit node?
What is wrong with the P2SH-P2WSH script
(Hint: which variable holds the 2-of-3 multisig script itself? Which variable holds the scriptSig
which will be included in the input?)
How would you verify the correctness of helper functions like get_multisig()? Can we add tests
Can you find any other places in functional tests that could use the script_util.py helper
functions instead of manually creating scripts?
<LarryRuane> Witness script is part of the tx input (but not included in the txid hash), and it's placed into the execution to-do list (probably using the wrong terms here) after the special segwit pattern is seen, 0,32-byte-hash
<LarryRuane> I'm confused about this part of p2wpkh: once the stack has the special pattern 20-byte-hash,0, then magically the command set (to-do list) becomes the standard p2pkh sequence, sig, pubkey, OP_DUP, OP_HASH160, 20-byte-hash, OP_EQUALVERIFY, OP_CHECKSIG .... my question is, is THAT the witness? Or is this sequence "manufactured" on the fly, and the
<glozow> Same question for P2SH: to send coins to someone with spending conditions encoded in a script, what is included in the scriptPubKey of the output? What needs to be provided in the scriptSig when the coin is spent?
<jnewbery> The "motivation" section for BIP16 is very short, but it contains the key point: "The purpose of pay-to-script-hash is to move the responsibility for supplying the conditions to redeem a transaction from the sender of the funds to the redeemer."
<jnewbery> And the second point: "The benefit is allowing a sender to fund any arbitrary transaction, no matter how complicated, using a fixed-length 20-byte hash that is short enough to scan from a QR code or easily copied and pasted."
<LarryRuane> purpose is, in case you are asking for a payment from someone with an old wallet, so the segwit address you'd like to give the person won't work ... so you can give the payer what looks exactly like a P2SH address
<LarryRuane> the nonsegwit node verifies that the redeem script hash is correct, then runs the redeem script, however, it's just OP_0 and a 20-byte-hash, so push those on the stack, and since top element is nonzero, done, success