tserialize value of incomplete inputs in the witness field. fix p2wsh-in-p2sh deserialization - electrum - Electrum Bitcoin wallet HTML git clone https://git.parazyd.org/electrum DIR Log DIR Files DIR Refs DIR Submodules --- DIR commit c12c1685d7ef3d9598a7eddd48d3876cd3cff871 DIR parent fcea2a065d50c852a8e74911ef9de6c1fec028f9 HTML Author: ThomasV <thomasv@electrum.org> Date: Mon, 18 Sep 2017 09:41:19 +0200 serialize value of incomplete inputs in the witness field. fix p2wsh-in-p2sh deserialization Diffstat: M lib/transaction.py | 40 +++++++++++++------------------ 1 file changed, 17 insertions(+), 23 deletions(-) --- DIR diff --git a/lib/transaction.py b/lib/transaction.py t@@ -305,11 +305,8 @@ def parse_scriptSig(d, _bytes): if match_decoded(decoded, match): item = decoded[0][1] if item[0] == 0: - redeemScript = bh2u(item) d['address'] = bitcoin.hash160_to_p2sh(bitcoin.hash_160(item)) - d['type'] = 'p2wpkh-p2sh' - d['redeemScript'] = redeemScript - d['num_sig'] = 1 + d['type'] = 'p2wpkh-p2sh' if len(item) == 21 else 'p2wsh-p2sh' else: # payto_pubkey d['type'] = 'p2pk' t@@ -421,20 +418,19 @@ def parse_input(vds): d['type'] = 'unknown' d['num_sig'] = 0 if scriptSig: - if scriptSig[0] == 255: - d['value'] = struct.unpack_from('<Q', scriptSig, 1)[0] - scriptSig = scriptSig[9:] - if scriptSig: - d['scriptSig'] = bh2u(scriptSig) - parse_scriptSig(d, scriptSig) - else: - d['scriptSig'] = '' + d['scriptSig'] = bh2u(scriptSig) + parse_scriptSig(d, scriptSig) + else: + d['scriptSig'] = '' return d def parse_witness(vds, txin): n = vds.read_compact_size() + if n == 0: + txin['value'] = vds.read_uint64() + n = vds.read_compact_size() w = list(bh2u(vds.read_bytes(vds.read_compact_size())) for i in range(n)) if n > 2: txin['num_sig'] = n - 2 t@@ -497,9 +493,7 @@ def p2wpkh_nested_script(pubkey): return '00' + push_script(pkh) def p2wsh_nested_script(witness_script): - print('wit', witness_script) wsh = bh2u(sha256(bfh(witness_script))) - print(len(wsh)//2) return '00' + push_script(wsh) t@@ -650,13 +644,15 @@ class Transaction: def serialize_witness(self, txin): pubkeys, sig_list = self.get_siglist(txin) if txin['type'] in ['p2wpkh', 'p2wpkh-p2sh']: - n = 2 - return var_int(n) + push_script(sig_list[0]) + push_script(pubkeys[0]) + witness = var_int(2) + push_script(sig_list[0]) + push_script(pubkeys[0]) elif txin['type'] in ['p2wsh', 'p2wsh-p2sh']: n = len(sig_list) + 2 - # fixme: witness script must be decided by wallet witness_script = multisig_script(pubkeys, txin['num_sig']) - return var_int(n) + '00' + ''.join(var_int(len(x)//2) + x for x in sig_list) + var_int(len(witness_script)//2) + witness_script + witness = var_int(n) + '00' + ''.join(var_int(len(x)//2) + x for x in sig_list) + var_int(len(witness_script)//2) + witness_script + else: + raise BaseException('wrong txin type') + value_field = '' if self.is_txin_complete(txin) else var_int(0) + int_to_hex(txin['value'], 8) + return value_field + witness @classmethod def is_segwit_input(self, txin): t@@ -669,8 +665,6 @@ class Transaction: return txin['scriptSig'] pubkeys, sig_list = self.get_siglist(txin, estimate_size) script = ''.join(push_script(x) for x in sig_list) - if self.is_segwit_input(txin): - segwit_value = '' if self.is_txin_complete(txin) or estimate_size else 'ff' + int_to_hex(txin['value'], 8) if _type == 'p2pk': pass elif _type == 'p2sh': t@@ -681,14 +675,14 @@ class Transaction: elif _type == 'p2pkh': script += push_script(pubkeys[0]) elif _type in ['p2wpkh', 'p2wsh']: - return segwit_value + return '' elif _type == 'p2wpkh-p2sh': scriptSig = p2wpkh_nested_script(pubkeys[0]) - return segwit_value + push_script(scriptSig) + return push_script(scriptSig) elif _type == 'p2wsh-p2sh': witness_script = self.get_preimage_script(txin) scriptSig = p2wsh_nested_script(witness_script) - return segwit_value + push_script(scriptSig) + return push_script(scriptSig) elif _type == 'address': script += push_script(pubkeys[0]) elif _type == 'unknown':