def createmultisig(self, num, pubkeys): """Create multisig address""" assert isinstance(pubkeys, list), (type(num), type(pubkeys)) redeem_script = transaction.multisig_script(pubkeys, num) address = bitcoin.hash160_to_p2sh(hash_160( redeem_script.decode('hex'))) return {'address': address, 'redeemScript': redeem_script}
def get_address_from_output_script(bytes): decoded = [ x for x in script_GetOp(bytes) ] # The Genesis Block, self-payments, and pay-by-IP-address payments look like: # 65 BYTES:... CHECKSIG match = [ opcodes.OP_PUSHDATA4, opcodes.OP_CHECKSIG ] if match_decoded(decoded, match): return TYPE_PUBKEY, decoded[0][1].encode('hex') # Pay-by-Bitcoin-address TxOuts look like: # DUP HASH160 20 BYTES:... EQUALVERIFY CHECKSIG match = [ opcodes.OP_DUP, opcodes.OP_HASH160, opcodes.OP_PUSHDATA4, opcodes.OP_EQUALVERIFY, opcodes.OP_CHECKSIG ] if match_decoded(decoded, match): return TYPE_ADDRESS, hash160_to_p2pkh(decoded[2][1]) # p2sh match = [ opcodes.OP_HASH160, opcodes.OP_PUSHDATA4, opcodes.OP_EQUAL ] if match_decoded(decoded, match): return TYPE_ADDRESS, hash160_to_p2sh(decoded[1][1]) return TYPE_SCRIPT, bytes
def parse_scriptSig(d, 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') d['address'] = bitcoin.hash160_to_p2sh( bitcoin.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 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 BaseException: 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 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 = [safe_parse_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')))
def createmultisig(self, num, pubkeys): """Create multisig address""" assert isinstance(pubkeys, list), (type(num), type(pubkeys)) redeem_script = transaction.multisig_script(pubkeys, num) address = bitcoin.hash160_to_p2sh(hash_160(redeem_script.decode('hex'))) return {'address':address, 'redeemScript':redeem_script}
def parse_scriptSig(d, _bytes): try: decoded = [ x for x in script_GetOp(_bytes) ] except Exception as e: # coinbase transactions raise an exception print_error("parse_scriptSig: cannot find address in input script (coinbase?)", bh2u(_bytes)) return match = [ opcodes.OP_PUSHDATA4 ] if match_decoded(decoded, match): item = decoded[0][1] if item[0] == 0: # segwit embedded into p2sh # witness version 0 d['address'] = bitcoin.hash160_to_p2sh(bitcoin.hash_160(item)) if len(item) == 22: d['type'] = 'p2wpkh-p2sh' elif len(item) == 34: d['type'] = 'p2wsh-p2sh' else: print_error("unrecognized txin type", bh2u(item)) elif opcodes.OP_1 <= item[0] <= opcodes.OP_16: # segwit embedded into p2sh # witness version 1-16 pass else: # assert item[0] == 0x30 # pay-to-pubkey d['type'] = 'p2pk' d['address'] = "(pubkey)" d['signatures'] = [bh2u(item)] d['num_sig'] = 1 d['x_pubkeys'] = ["(pubkey)"] d['pubkeys'] = ["(pubkey)"] return # p2pkh TxIn transactions push a signature # (71-73 bytes) and then their public key # (33 or 65 bytes) onto the stack: match = [ opcodes.OP_PUSHDATA4, opcodes.OP_PUSHDATA4 ] if match_decoded(decoded, match): sig = bh2u(decoded[0][1]) x_pubkey = bh2u(decoded[1][1]) try: signatures = parse_sig([sig]) pubkey, address = xpubkey_to_address(x_pubkey) except: print_error("parse_scriptSig: cannot find address in input script (p2pkh?)", bh2u(_bytes)) 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 match_decoded(decoded, match): x_sig = [bh2u(x[1]) for x in decoded[1:-1]] redeem_script_unsanitized = decoded[-1][1] # for partial multisig txn, this has x_pubkeys try: m, n, x_pubkeys, pubkeys, redeem_script = parse_redeemScript_multisig(redeem_script_unsanitized) except NotRecognizedRedeemScript: print_error("parse_scriptSig: cannot find address in input script (p2sh?)", bh2u(_bytes)) # we could still guess: # d['address'] = hash160_to_p2sh(hash_160(decoded[-1][1])) return # 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['redeem_script'] = redeem_script d['address'] = hash160_to_p2sh(hash_160(bfh(redeem_script))) return print_error("parse_scriptSig: cannot find address in input script (unknown)", bh2u(_bytes))
def parse_scriptSig(d, 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 # payto_pubkey match = [ opcodes.OP_PUSHDATA4 ] if match_decoded(decoded, match): sig = decoded[0][1].encode('hex') d['address'] = "(pubkey)" d['signatures'] = [sig] 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 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['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 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_address(x)[0] for x in x_pubkeys] redeemScript = Transaction.multisig_script(pubkeys, m) # write result in d 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')))