3131 CTransaction ,
3232 ExtendedKey ,
3333 hash256 ,
34+ is_p2pk ,
35+ is_p2pkh ,
36+ is_p2sh ,
37+ is_p2wpkh ,
38+ is_p2wsh ,
39+ is_witness ,
3440 ser_sig_der ,
3541 ser_sig_compact ,
42+ ser_string ,
3643 ser_compact_size ,
3744)
3845from ..base58 import (
@@ -365,18 +372,39 @@ def sign_tx(self, tx):
365372 sighash_tuples = []
366373 for txin , psbt_in , i_num in zip (blank_tx .vin , tx .inputs , range (len (blank_tx .vin ))):
367374 sighash = b""
375+ utxo = None
376+ if psbt_in .witness_utxo :
377+ utxo = psbt_in .witness_utxo
368378 if psbt_in .non_witness_utxo :
379+ if txin .prevout .hash != psbt_in .non_witness_utxo .sha256 :
380+ raise BadArgumentError ('Input {} has a non_witness_utxo with the wrong hash' .format (i_num ))
369381 utxo = psbt_in .non_witness_utxo .vout [txin .prevout .n ]
382+ if utxo is None :
383+ continue
384+ scriptcode = utxo .scriptPubKey
385+
386+ # Check if P2SH
387+ p2sh = False
388+ if is_p2sh (scriptcode ):
389+ # Look up redeemscript
390+ if len (psbt_in .redeem_script ) == 0 :
391+ continue
392+ scriptcode = psbt_in .redeem_script
393+ p2sh = True
394+
395+ is_wit , _ , _ = is_witness (scriptcode )
396+
397+ # Check if P2WSH
398+ if is_p2wsh (scriptcode ):
399+ # Look up witnessscript
400+ if len (psbt_in .witness_script ) == 0 :
401+ continue
402+ scriptcode = psbt_in .witness_script
370403
371- # Check if P2SH
372- if utxo .is_p2sh ():
373- # Look up redeemscript
374- redeemscript = psbt_in .redeem_script
404+ if not is_wit :
405+ if p2sh or is_p2pkh (scriptcode ) or is_p2pk (scriptcode ):
375406 # Add to blank_tx
376- txin .scriptSig = redeemscript
377- # Check if P2PKH
378- elif utxo .is_p2pkh () or utxo .is_p2pk ():
379- txin .scriptSig = psbt_in .non_witness_utxo .vout [txin .prevout .n ].scriptPubKey
407+ txin .scriptSig = scriptcode
380408 # We don't know what this is, skip it
381409 else :
382410 continue
@@ -388,7 +416,7 @@ def sign_tx(self, tx):
388416 # Hash it
389417 sighash += hash256 (ser_tx )
390418 txin .scriptSig = b""
391- elif psbt_in . witness_utxo :
419+ else :
392420 # Calculate hashPrevouts and hashSequence
393421 prevouts_preimage = b""
394422 sequence_preimage = b""
@@ -404,33 +432,18 @@ def sign_tx(self, tx):
404432 outputs_preimage += output .serialize ()
405433 hashOutputs = hash256 (outputs_preimage )
406434
407- # Get the scriptCode
408- scriptCode = b""
409- witness_program = b""
410- if psbt_in .witness_utxo .is_p2sh ():
411- # Look up redeemscript
412- redeemscript = psbt_in .redeem_script
413- witness_program = redeemscript
414- else :
415- witness_program = psbt_in .witness_utxo .scriptPubKey
416-
417- # Check if witness_program is script hash
418- if len (witness_program ) == 34 and witness_program [0 ] == 0x00 and witness_program [1 ] == 0x20 :
419- # look up witnessscript and set as scriptCode
420- witnessscript = psbt_in .witness_script
421- scriptCode += ser_compact_size (len (witnessscript )) + witnessscript
422- else :
423- scriptCode += b"\x19 \x76 \xa9 \x14 "
424- scriptCode += witness_program [2 :]
425- scriptCode += b"\x88 \xac "
435+ # Check if scriptcode is p2wpkh
436+ if is_p2wpkh (scriptcode ):
437+ _ , _ , wit_prog = is_witness (scriptcode )
438+ scriptcode = b"\x76 \xa9 \x14 " + wit_prog + b"\x88 \xac "
426439
427440 # Make sighash preimage
428441 preimage = b""
429442 preimage += struct .pack ("<i" , blank_tx .nVersion )
430443 preimage += hashPrevouts
431444 preimage += hashSequence
432445 preimage += txin .prevout .serialize ()
433- preimage += scriptCode
446+ preimage += ser_string ( scriptcode )
434447 preimage += struct .pack ("<q" , psbt_in .witness_utxo .nValue )
435448 preimage += struct .pack ("<I" , txin .nSequence )
436449 preimage += hashOutputs
0 commit comments