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.")
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
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