def parse_script_sig(bytes): try: decoded = [x for x in script_GetOp(bytes)] except Exception: # coinbase transactions raise an exception print_error("cannot find address in input script", bytes.encode('hex')) return match = [opcodes.OP_PUSHDATA4] if match_decoded(decoded, match): item = decoded[0][1] if item[0] == chr(0): redeemScript = item.encode('hex') return 'p2wpkh-p2sh', hash160_to_p2sh( hash_160(redeemScript.decode('hex'))), None else: return 'p2pk', None, None # non-generated TxIn transactions push a signature # (seventy-something bytes) and then their public key # (65 bytes) onto the stack: match = [opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4] if match_decoded(decoded, match): sig = decoded[0][1].encode('hex') pubkey = decoded[1][1].encode('hex') address = public_key_to_p2pkh(pubkey.decode('hex')) return 'p2pkh', address, pubkey # p2sh transaction, m of n match = [opcodes.OP_0] + [opcodes.OP_PUSHDATA4] * (len(decoded) - 1) if not match_decoded(decoded, match): print_error("cannot find address in input script", bytes.encode('hex')) return x_sig = [x[1].encode('hex') for x in decoded[1:-1]] dec2 = [x for x in script_GetOp(decoded[-1][1])] m = dec2[0][0] - opcodes.OP_1 + 1 n = dec2[-2][0] - opcodes.OP_1 + 1 op_m = opcodes.OP_1 + m - 1 op_n = opcodes.OP_1 + n - 1 match_multisig = [op_m] + [opcodes.OP_PUSHDATA4] * n + [ op_n, opcodes.OP_CHECKMULTISIG ] if not match_decoded(dec2, match_multisig): print_error("cannot find address in input script", bytes.encode('hex')) return x_pubkeys = map(lambda x: x[1].encode('hex'), dec2[1:-2]) pubkeys = [xpubkey_to_pubkey(x) for x in x_pubkeys] redeemScript = multisig_script(pubkeys, m) # write result in d return 'p2sh', hash160_to_p2sh(hash_160( redeemScript.decode('hex'))), redeemScript
def bip32_public_derivation(xpub, branch, sequence): xtype, depth, fingerprint, child_number, c, cK = deserialize_xpub(xpub) assert sequence.startswith(branch) sequence = sequence[len(branch):] parent_cK = None i = 0 for n in sequence.split('/'): if n == '': continue i = int(n) parent_cK = cK cK, c = CKD_pub(cK, c, i) depth += 1 fingerprint = hash_160(parent_cK)[0:4] child_number = ("%08X" % i).decode('hex').encode('utf-8') return serialize_xpub(xtype, c, cK, depth, fingerprint, child_number)
def bip32_private_derivation(xprv, branch, sequence): assert sequence.startswith(branch) if branch == sequence: return xprv, xpub_from_xprv(xprv) xtype, depth, fingerprint, child_number, c, k = deserialize_xprv(xprv) sequence = sequence[len(branch):] parent_k = None i = 0 for n in sequence.split('/'): if n == '': continue i = int(n[:-1]) + BIP32_PRIME if n[-1] == "'" else int(n) parent_k = k k, c = CKD_priv(k, c, i) depth += 1 _, parent_cK = get_pubkeys_from_secret(parent_k) fingerprint = hash_160(parent_cK)[0:4] child_number = ("%08X" % i).decode('hex').encode('utf-8') K, cK = get_pubkeys_from_secret(k) xpub = serialize_xpub(xtype, c, cK, depth, fingerprint, child_number) xprv = serialize_xprv(xtype, c, k, depth, fingerprint, child_number) return xprv, xpub
def serialize_preimage(self, i): """ get to be sign content :param i: :return: """ version = write_uint32(self.tx_ver).encode('hex') hash_type = write_uint32(1).encode('hex') locktime = write_uint32(self.tx_locktime).encode('hex') input_list = self._input_list output_list = self._output_list txin = input_list[i] if txin.is_segwit_input(): hash_prevouts = double_sha256( ''.join(txin.serialize_outpoint() for txin in input_list).decode('hex')).encode( 'hex') hash_sequence = double_sha256( ''.join(write_uint32(txin.in_sequence) for txin in input_list).decode( 'hex')).encode('hex') hash_outputs = double_sha256( ''.join(o.serialize_output() for o in output_list).decode('hex')).encode('hex') outpoint = txin.serialize_outpoint() pubkey = txin.in_dict['pubkeys'][0] pkh = hash_160(pubkey.decode('hex')).encode('hex') # redeem_script = '00' + push_script(pkh) script_code = push_script('76a9' + push_script(pkh) + '88ac') # script_hash = hash_160(redeem_script.decode('hex')).encode('hex') # script_pub_key = 'a9' + push_script(script_hash) + '87' amount = write_uint64(txin.in_value) sequence = write_uint32(txin.in_sequence) preimage = version + hash_prevouts + hash_sequence + outpoint + script_code + amount + sequence + hash_outputs + locktime + hash_type else: txins = int_to_hex(len(input_list)) + ''.join( txin.serialize_input_preimage(k) for k, txin in enumerate(input_list)) txouts = int_to_hex(len(output_list)) + ''.join( o.serialize_output() for o in output_list) preimage = version + txins + txouts + locktime + hash_type return preimage
def parse_type_script_sig(bytes): decoded = [x for x in script_GetOp(bytes)] match = [opcodes.OP_PUSHDATA4] if match_decoded(decoded, match): item = decoded[0][1] if item[0] == chr(0): return 'p2wpkh-p2sh' else: return 'p2pk' match = [opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4] if match_decoded(decoded, match): return 'p2pkh' # p2sh transaction, m of n match = [opcodes.OP_0] + [opcodes.OP_PUSHDATA4] * (len(decoded) - 1) if not match_decoded(decoded, match): print_error("cannot find address in input script", bytes.encode('hex')) return x_sig = [x[1].encode('hex') for x in decoded[1:-1]] dec2 = [x for x in script_GetOp(decoded[-1][1])] m = dec2[0][0] - opcodes.OP_1 + 1 n = dec2[-2][0] - opcodes.OP_1 + 1 op_m = opcodes.OP_1 + m - 1 op_n = opcodes.OP_1 + n - 1 match_multisig = [op_m] + [opcodes.OP_PUSHDATA4] * n + [ op_n, opcodes.OP_CHECKMULTISIG ] if not match_decoded(dec2, match_multisig): print_error("cannot find address in input script", bytes.encode('hex')) return x_pubkeys = map(lambda x: x[1].encode('hex'), dec2[1:-2]) pubkeys = [xpubkey_to_pubkey(x) for x in x_pubkeys] redeemScript = multisig_script(pubkeys, m) # write result in d return 'p2sh', hash160_to_p2sh(hash_160( redeemScript.decode('hex'))), redeemScript
def segwit_script(pubkey): pkh = hash_160(pubkey.decode('hex')).encode('hex') return '00' + push_script(pkh)
def parse_scriptSig(self, bytes): d = {} try: decoded = [x for x in script_GetOp(bytes)] except Exception: # coinbase transactions raise an exception # print_error("cannot find address in input script", bytes.encode('hex')) return match = [opcodes.OP_PUSHDATA4] if self.match_decoded(decoded, match): item = decoded[0][1] if item[0] == chr(0): redeemScript = item.encode('hex') d['address'] = hash160_to_p2sh( hash_160(redeemScript.decode('hex'))) d['type'] = 'p2wpkh-p2sh' d['redeemScript'] = redeemScript d['x_pubkeys'] = ["(witness)"] d['pubkeys'] = ["(witness)"] d['signatures'] = ['(witness)'] d['num_sig'] = 1 else: # payto_pubkey d['type'] = 'p2pk' d['address'] = "(pubkey)" d['signatures'] = [item.encode('hex')] d['num_sig'] = 1 d['x_pubkeys'] = ["(pubkey)"] d['pubkeys'] = ["(pubkey)"] return # non-generated TxIn transactions push a signature # (seventy-something bytes) and then their public key # (65 bytes) onto the stack: match = [opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4] if self.match_decoded(decoded, match): sig = decoded[0][1].encode('hex') x_pubkey = decoded[1][1].encode('hex') try: signatures = parse_sig([sig]) pubkey, address = xpubkey_to_address(x_pubkey) except: import traceback traceback.print_exc(file=sys.stdout) # print_error("cannot find address in input script", bytes.encode('hex')) return d['type'] = 'p2pkh' d['signatures'] = signatures d['x_pubkeys'] = [x_pubkey] d['num_sig'] = 1 d['pubkeys'] = [pubkey] d['address'] = address return # p2sh transaction, m of n match = [opcodes.OP_0] + [opcodes.OP_PUSHDATA4] * (len(decoded) - 1) if not self.match_decoded(decoded, match): # print_error("cannot find address in input script", bytes.encode('hex')) return x_sig = [x[1].encode('hex') for x in decoded[1:-1]] dec2 = [x for x in script_GetOp(decoded[-1][1])] m = dec2[0][0] - opcodes.OP_1 + 1 n = dec2[-2][0] - opcodes.OP_1 + 1 op_m = opcodes.OP_1 + m - 1 op_n = opcodes.OP_1 + n - 1 match_multisig = [op_m] + [opcodes.OP_PUSHDATA4] * n + [ op_n, opcodes.OP_CHECKMULTISIG ] if not self.match_decoded(dec2, match_multisig): # print_error("cannot find address in input script", bytes.encode('hex')) return x_pubkeys = map(lambda x: x[1].encode('hex'), dec2[1:-2]) pubkeys = [xpubkey_to_pubkey(x) for x in x_pubkeys] redeemScript = multisig_script(pubkeys, m) # write result in d d['type'] = 'p2sh' d['num_sig'] = m d['signatures'] = parse_sig(x_sig) d['x_pubkeys'] = x_pubkeys d['pubkeys'] = pubkeys d['redeemScript'] = redeemScript d['address'] = hash160_to_p2sh(hash_160(redeemScript.decode('hex')))