Пример #1
0
def pubkeyhash_to_pubkey(pubkeyhash, provided_pubkeys=None):
    # Search provided pubkeys.
    if provided_pubkeys:
        if type(provided_pubkeys) != list:
            provided_pubkeys = [provided_pubkeys]
        for pubkey in provided_pubkeys:
            if pubkeyhash == script.pubkey_to_pubkeyhash(util.unhexlify(pubkey)):
                return pubkey

    # Search blockchain.
    raw_transactions = searchrawtransactions(pubkeyhash, unconfirmed=True)
    for tx in raw_transactions:
        for vin in tx['vin']:
            if 'coinbase' not in vin:
                scriptsig = vin['scriptSig']
                asm = scriptsig['asm'].split(' ')
                if len(asm) >= 2:
                    # catch unhexlify errs for when asm[1] isn't a pubkey (eg; for P2SH)
                    try:
                        pubkey = asm[1]
                        if pubkeyhash == script.pubkey_to_pubkeyhash(util.unhexlify(pubkey)):
                            return pubkey
                    except binascii.Error:
                        pass

    raise UnknownPubKeyError('Public key was neither provided nor published in blockchain.')
Пример #2
0
def pubkeyhash_to_pubkey(pubkeyhash, provided_pubkeys=None):
    # Search provided pubkeys.
    if provided_pubkeys:
        if type(provided_pubkeys) != list:
            provided_pubkeys = [provided_pubkeys]
        for pubkey in provided_pubkeys:
            if pubkeyhash == script.pubkey_to_pubkeyhash(
                    util.unhexlify(pubkey)):
                return pubkey

    # Search blockchain.
    raw_transactions = search_raw_transactions(pubkeyhash, unconfirmed=True)
    for tx in raw_transactions:
        for vin in tx['vin']:
            if 'coinbase' not in vin:
                scriptsig = vin['scriptSig']
                asm = scriptsig['asm'].split(' ')
                if len(asm) >= 2:
                    # catch unhexlify errs for when asm[1] isn't a pubkey (eg; for P2SH)
                    try:
                        pubkey = asm[1]
                        if pubkeyhash == script.pubkey_to_pubkeyhash(
                                util.unhexlify(pubkey)):
                            return pubkey
                    except binascii.Error:
                        pass

    raise UnknownPubKeyError(
        'Public key was neither provided nor published in blockchain.')
Пример #3
0
def decode_data_redeem_script(redeemScript):
    script_len = len(redeemScript)

    if script_len == 41 and \
        redeemScript[0] == bitcoinlib.core.script.OP_DROP and \
        redeemScript[35] == bitcoinlib.core.script.OP_CHECKSIGVERIFY and \
        redeemScript[37] == bitcoinlib.core.script.OP_DROP and \
        redeemScript[38] == bitcoinlib.core.script.OP_DEPTH and \
        redeemScript[39] == bitcoinlib.core.script.OP_0 and \
        redeemScript[40] == bitcoinlib.core.script.OP_EQUAL:
            # - OP_DROP [push] [33-byte pubkey] OP_CHECKSIGVERIFY [n] OP_DROP OP_DEPTH 0 OP_EQUAL
            pubkey = redeemScript[2:35]
            source = script.pubkey_to_pubkeyhash(pubkey)
            redeem_script_is_valid = True
    elif script_len > 41 and \
        redeemScript[0] == bitcoinlib.core.script.OP_DROP and \
        redeemScript[script_len-4] == bitcoinlib.core.script.OP_DROP and \
        redeemScript[script_len-3] == bitcoinlib.core.script.OP_DEPTH and \
        redeemScript[script_len-2] == bitcoinlib.core.script.OP_0 and \
        redeemScript[script_len-1] == bitcoinlib.core.script.OP_EQUAL:
            # - OP_DROP {arbitrary multisig script} [n] OP_DROP OP_DEPTH 0 OP_EQUAL
            pubkey = None
            source = None
            redeem_script_is_valid = True
    else:
        pubkey = None
        source = None
        redeem_script_is_valid = False

    return pubkey, source, redeem_script_is_valid
Пример #4
0
def pubkeyhash_to_pubkey(pubkeyhash, provided_pubkeys=None):
    # Search provided pubkeys.
    if provided_pubkeys:
        if type(provided_pubkeys) != list:
            provided_pubkeys = [provided_pubkeys]
        for pubkey in provided_pubkeys:
            if pubkeyhash == script.pubkey_to_pubkeyhash(util.unhexlify(pubkey)):
                return pubkey

    # Search blockchain.
    raw_transactions = searchrawtransactions(pubkeyhash, unconfirmed=True)
    for tx in raw_transactions:
        for vin in tx['vin']:
            scriptsig = vin['scriptSig']
            asm = scriptsig['asm'].split(' ')
            if len(asm) >= 2:
                pubkey = asm[1]
                if pubkeyhash == script.pubkey_to_pubkeyhash(util.unhexlify(pubkey)):
                    return pubkey

    raise UnknownPubKeyError('Public key was neither provided nor published in blockchain.')
Пример #5
0
def pubkeyhash_to_pubkey(pubkeyhash, provided_pubkeys=None):
    # Search provided pubkeys.
    if provided_pubkeys:
        if type(provided_pubkeys) != list:
            provided_pubkeys = [provided_pubkeys]
        for pubkey in provided_pubkeys:
            if pubkeyhash == script.pubkey_to_pubkeyhash(
                    util.unhexlify(pubkey)):
                return pubkey

    # Search blockchain.
    raw_transactions = searchrawtransactions(pubkeyhash)
    for tx in raw_transactions:
        for vin in tx['vin']:
            scriptsig = vin['scriptSig']
            asm = scriptsig['asm'].split(' ')
            pubkey = asm[1]
            if pubkeyhash == script.pubkey_to_pubkeyhash(
                    util.unhexlify(pubkey)):
                return pubkey

    # Public key for address neither provided nor published in the blockchain.
    return None
Пример #6
0
def get_pubkey_monosig(pubkeyhash, pubkey_resolver=input_pubkey):
    if wallet.is_valid(pubkeyhash):

        # If in wallet, get from wallet.
        logging.debug('Looking for public key for `{}` in wallet.'.format(pubkeyhash))
        if wallet.is_mine(pubkeyhash):
            pubkey = wallet.get_pubkey(pubkeyhash)
            if pubkey:
                return pubkey
        logging.debug('Public key for `{}` not found in wallet.'.format(pubkeyhash))

        # If in blockchain (and not in wallet), get from blockchain.
        logging.debug('Looking for public key for `{}` in blockchain.'.format(pubkeyhash))
        try:
            pubkey = util.api('search_pubkey', {'pubkeyhash': pubkeyhash, 'provided_pubkeys': None})
        except util.RPCError as e:
            pubkey = None
        if pubkey:
            return pubkey
        logging.debug('Public key for `{}` not found in blockchain.'.format(pubkeyhash))

        # If not in wallet and not in blockchain, get from user.
        answer = pubkey_resolver(pubkeyhash)
        if not answer:
            return None

        # Public Key or Private Key?
        is_fully_valid_pubkey = True
        try:
            is_fully_valid_pubkey = script.is_fully_valid(binascii.unhexlify(answer))
        except binascii.Error:
            is_fully_valid_pubkey = False
        if is_fully_valid_pubkey:
            logging.debug('Answer was a fully valid public key.')
            pubkey = answer
        else:
            logging.debug('Answer was not a fully valid public key. Assuming answer was a private key.')
            private_key = answer
            try:
                pubkey = script.private_key_to_public_key(private_key)
            except script.AltcoinSupportError:
                raise InputError('invalid private key')
        if pubkeyhash != script.pubkey_to_pubkeyhash(binascii.unhexlify(bytes(pubkey, 'utf-8'))):
            raise InputError('provided public or private key does not match the source address')

        return pubkey

    return None
Пример #7
0
def get_pubkey_monosig(pubkeyhash, pubkey_resolver=input_pubkey):
    if wallet.is_valid(pubkeyhash):

        # If in wallet, get from wallet.
        logging.debug("Looking for public key for `{}` in wallet.".format(pubkeyhash))
        if wallet.is_mine(pubkeyhash):
            pubkey = wallet.get_pubkey(pubkeyhash)
            if pubkey:
                return pubkey
        logging.debug("Public key for `{}` not found in wallet.".format(pubkeyhash))

        # If in blockchain (and not in wallet), get from blockchain.
        logging.debug("Looking for public key for `{}` in blockchain.".format(pubkeyhash))
        try:
            pubkey = util.api("search_pubkey", {"pubkeyhash": pubkeyhash, "provided_pubkeys": None})
        except util.RPCError as e:
            pubkey = None
        if pubkey:
            return pubkey
        logging.debug("Public key for `{}` not found in blockchain.".format(pubkeyhash))

        # If not in wallet and not in blockchain, get from user.
        answer = pubkey_resolver(pubkeyhash)
        if not answer:
            return None

        # Public Key or Private Key?
        is_fully_valid_pubkey = True
        try:
            is_fully_valid_pubkey = script.is_fully_valid(binascii.unhexlify(answer))
        except binascii.Error:
            is_fully_valid_pubkey = False
        if is_fully_valid_pubkey:
            logging.debug("Answer was a fully valid public key.")
            pubkey = answer
        else:
            logging.debug("Answer was not a fully valid public key. Assuming answer was a private key.")
            private_key = answer
            try:
                pubkey = script.private_key_to_public_key(private_key)
            except script.AltcoinSupportError:
                raise InputError("invalid private key")
        if pubkeyhash != script.pubkey_to_pubkeyhash(binascii.unhexlify(bytes(pubkey, "utf-8"))):
            raise InputError("provided public or private key does not match the source address")

        return pubkey

    return None
Пример #8
0
    def decode_checkmultisig(asm):
        pubkeys, signatures_required = script.get_checkmultisig(asm)
        chunk = b''
        for pubkey in pubkeys[:-1]:     # (No data in last pubkey.)
            chunk += pubkey[1:-1]       # Skip sign byte and nonce byte.
        chunk = arc4_decrypt(chunk)
        if chunk[1:len(config.PREFIX) + 1] == config.PREFIX:        # Data
            # Padding byte in each output (instead of just in the last one) so that encoding methods may be mixed. Also, it’s just not very much data.
            chunk_length = chunk[0]
            chunk = chunk[1:chunk_length + 1]
            destination, data = None, chunk[len(config.PREFIX):]
        else:                                                       # Destination
            pubkeyhashes = [script.pubkey_to_pubkeyhash(pubkey) for pubkey in pubkeys]
            destination, data = script.construct_array(signatures_required, pubkeyhashes, len(pubkeyhashes)), None

        return destination, data
Пример #9
0
    def decode_checkmultisig(asm):
        pubkeys, signatures_required = script.get_checkmultisig(asm)
        chunk = b''
        for pubkey in pubkeys[:-1]:  # (No data in last pubkey.)
            chunk += pubkey[1:-1]  # Skip sign byte and nonce byte.
        chunk = arc4_decrypt(chunk)
        if chunk[1:len(config.PREFIX) + 1] == config.PREFIX:  # Data
            # Padding byte in each output (instead of just in the last one) so that encoding methods may be mixed. Also, it’s just not very much data.
            chunk_length = chunk[0]
            chunk = chunk[1:chunk_length + 1]
            destination, data = None, chunk[len(config.PREFIX):]
        else:  # Destination
            pubkeyhashes = [
                script.pubkey_to_pubkeyhash(pubkey) for pubkey in pubkeys
            ]
            destination, data = script.construct_array(signatures_required,
                                                       pubkeyhashes,
                                                       len(pubkeyhashes)), None

        return destination, data
Пример #10
0
def decode_data_redeem_script(redeemScript, p2sh_is_segwit=False):
    script_len = len(redeemScript)
    found_data = b''

    if script_len == 41 and \
        redeemScript[0] == bitcoinlib.core.script.OP_DROP and \
        redeemScript[35] == bitcoinlib.core.script.OP_CHECKSIGVERIFY and \
        redeemScript[37] == bitcoinlib.core.script.OP_DROP and \
        redeemScript[38] == bitcoinlib.core.script.OP_DEPTH and \
        redeemScript[39] == bitcoinlib.core.script.OP_0 and \
        redeemScript[40] == bitcoinlib.core.script.OP_EQUAL:
        # - OP_DROP [push] [33-byte pubkey] OP_CHECKSIGVERIFY [n] OP_DROP OP_DEPTH 0 OP_EQUAL
        pubkey = redeemScript[2:35]
        if p2sh_is_segwit:
            source = script.pubkey_to_p2whash(pubkey)
        else:
            source = script.pubkey_to_pubkeyhash(pubkey)
        redeem_script_is_valid = True
    elif script_len > 41 and \
        redeemScript[0] == bitcoinlib.core.script.OP_DROP and \
        redeemScript[script_len-4] == bitcoinlib.core.script.OP_DROP and \
        redeemScript[script_len-3] == bitcoinlib.core.script.OP_DEPTH and \
        redeemScript[script_len-2] == bitcoinlib.core.script.OP_0 and \
        redeemScript[script_len-1] == bitcoinlib.core.script.OP_EQUAL:
        # - OP_DROP {arbitrary multisig script} [n] OP_DROP OP_DEPTH 0 OP_EQUAL
        pubkey = None
        source = None
        redeem_script_is_valid = True
    else:
        pubkey = None
        source = None
        redeem_script_is_valid = False

        try:
            opcode = bitcoinlib.core.script.CScriptOp(redeemScript[0])
            if opcode > bitcoinlib.core.script.OP_0 and opcode < bitcoinlib.core.script.OP_PUSHDATA1 or \
                opcode in (bitcoinlib.core.script.OP_PUSHDATA1, bitcoinlib.core.script.OP_PUSHDATA2, bitcoinlib.core.script.OP_PUSHDATA4):

                pos = 0
                pos, found_data = decode_data_push(redeemScript, 0)

                if redeemScript[pos] == bitcoinlib.core.script.OP_DROP:
                    pos += 1
                    valid_sig = False
                    opcode = redeemScript[pos]
                    if type(opcode) != type(''):
                        if opcode >= bitcoinlib.core.script.OP_2 and opcode <= bitcoinlib.core.script.OP_15:
                            # it's multisig
                            req_sigs = opcode - bitcoinlib.core.script.OP_1 + 1
                            pos += 1
                            pubkey = None
                            num_sigs = 0
                            found_sigs = False
                            while not found_sigs:
                                pos, npubkey = decode_data_push(
                                    redeemScript, pos)
                                num_sigs += 1
                                if redeemScript[
                                        pos] - bitcoinlib.core.script.OP_1 + 1 == num_sigs:
                                    found_sigs = True

                            pos += 1
                            valid_sig = redeemScript[
                                pos] == bitcoinlib.core.script.OP_CHECKMULTISIGVERIFY
                        else:
                            # it's p2pkh
                            pos, pubkey = decode_data_push(redeemScript, pos)
                            source = script.pubkey_to_pubkeyhash(pubkey)

                            valid_sig = redeemScript[
                                pos] == bitcoinlib.core.script.OP_CHECKSIGVERIFY
                        pos += 1

                        if valid_sig:
                            redeem_script_is_valid = redeemScript[pos + 1] == bitcoinlib.core.script.OP_DROP and \
                                redeemScript[pos + 2] == bitcoinlib.core.script.OP_DEPTH and \
                                redeemScript[pos + 3] == 0 and \
                                redeemScript[pos + 4] == bitcoinlib.core.script.OP_EQUAL
        except Exception as e:
            pass  #traceback.print_exc()

    return pubkey, source, redeem_script_is_valid, found_data