@ -1082,6 +1082,8 @@ class PSBTWalletMixin(object):
elif isinstance ( psbt_input . utxo , btc . CTransaction ) :
# human readable full transaction is *too* verbose:
outdict [ " utxo " ] = bintohex ( psbt_input . utxo . serialize ( ) )
if psbt_input . witness_utxo :
outdict [ " witness_utxo " ] = bintohex ( psbt_input . witness_utxo . serialize ( ) )
else :
assert False , " invalid PSBT Input utxo field. "
if psbt_input . sighash_type :
@ -1161,23 +1163,25 @@ class PSBTWalletMixin(object):
""" Given an input of a PSBT which is already finalized,
return its type as either " sw-legacy " or " sw " or False
if not one of these two types .
TODO : can be extented to other types .
TODO : can be extented to other types , does not currently
support any non - segwit input .
"""
assert isinstance ( psbt_input , btc . PSBT_Input )
# TODO: cleanly check that this PSBT Input is finalized.
if psbt_input . utxo . scriptPubKey . is_p2sh ( ) :
if not psbt_input . final_script_witness :
return False
if psbt_input . witness_utxo . scriptPubKey . is_p2sh ( ) :
# Note: p2sh does not prove the redeemscript;
# we check the finalscriptSig is p2wpkh:
fss = btc . CScript ( next ( btc . CScript (
psbt_input . final_script_sig ) . raw_iter ( ) ) [ 1 ] )
if fss . is_witness_v0_keyhash ( ) :
return " sw-legacy "
elif psbt_input . utxo . scriptPubKey . is_witness_v0_keyhash ( ) :
elif psbt_input . witness_ utxo. scriptPubKey . is_witness_v0_keyhash ( ) :
return " sw "
else :
return False
def create_psbt_from_tx ( self , tx , spent_outs = None ) :
def create_psbt_from_tx ( self , tx , spent_outs = None , force_witness_utxo = True ) :
""" Given a CMutableTransaction object, which should not currently
contain signatures , we create and return a new PSBT object of type
btc . PartiallySignedTransaction .
@ -1199,23 +1203,27 @@ class PSBTWalletMixin(object):
# as above, will not be signable in this case
continue
if isinstance ( spent_outs [ i ] , ( btc . CTransaction , btc . CTxOut ) ) :
# note that we trust the caller to choose Tx vs TxOut as according
# to non-witness/witness. Note also that for now this mixin does
# not attempt to provide unsigned-tx(second argument) for witness
# case.
txinput . set_utxo ( spent_outs [ i ] , None )
# note: if spent_outs[i] is in fact CTransaction, then
# the unsigned_tx must be provided (tx) in order to populate
# the witness_utxo field of this PSBT_Input (and if it isn't,
# this argument is ignored), but also, until the redeem script
# is populated, then for the p2sh case, the lib can't know
# whether it is witness, so we must force the witness_utxo here,
# unless this is switched off in the kwargs of this function:
txinput . set_utxo ( spent_outs [ i ] , tx ,
force_witness_utxo = force_witness_utxo )
else :
assert False , " invalid spent output type passed into PSBT creator "
# we now insert redeemscripts where that is possible and necessary:
for i , txinput in enumerate ( new_psbt . inputs ) :
if isinstance ( txinput . witness_utxo , btc . CTxOut ) :
# witness
if txinput . utxo . scriptPubKey . is_witness_scriptpubkey ( ) :
if txinput . witness_ utxo. scriptPubKey . is_witness_scriptpubkey ( ) :
# nothing needs inserting; the scriptSig is empty.
continue
elif txinput . utxo . scriptPubKey . is_p2sh ( ) :
elif txinput . witness_ utxo. scriptPubKey . is_p2sh ( ) :
try :
path = self . script_to_path ( txinput . utxo . scriptPubKey )
path = self . script_to_path ( txinput . witness_ utxo. scriptPubKey )
except AssertionError :
# this happens when an input is provided but it's not in
# this wallet; in this case, we cannot set the redeem script.