def get_address(self, index=None): """ @index is the child index Returns: master/root address by default or child address for given @index """ if index is None: hex_privkey = self.get_privkey() return get_address_from_privkey(hex_privkey) hex_privkey = self.get_privkey(index) return get_address_from_privkey(hex_privkey)
def generate_bitcoin_keypairs(number_of_addresses=50): """ This function: 1) generates new bitcoin keypairs 2) saves encrypted private keys private keys are encrypted with SECRET_KEY """ if registrar_addresses.find().count() >= number_of_addresses: log.debug("Already have enough addresses") return no_of_new_addresses = number_of_addresses - registrar_addresses.find().count() for count in range(1, no_of_new_addresses + 1): privkey = BitcoinPrivateKey() hex_privkey = privkey.to_hex() encrypted_privkey = aes_encrypt(hex_privkey, SECRET_KEY) address = get_address_from_privkey(hex_privkey) log.debug("Creating new address (count, address): (%s, %s):" % (count, address)) new_entry = {} new_entry['encrypted_privkey'] = encrypted_privkey new_entry['address'] = address registrar_addresses.save(new_entry)
def get_child_address(self, index=0): """ @index is the child index Returns: child address for given @index """ if self.child_addresses is not None: return self.child_addresses[index] hex_privkey = self.get_child_privkey(index) return get_address_from_privkey(hex_privkey)
def send_multi_payment(payment_privkey, list_of_addresses, payment_per_address): payment_address = get_address_from_privkey(payment_privkey) if dontuseAddress(payment_address): log.debug("Payment address %s not ready" % payment_address) return None inputs = [{'address': payment_address}] payment_in_satoshis = btc_to_satoshis(float(payment_per_address)) outputs = [] for address in list_of_addresses: outputs.append({'address': address, 'value': int(payment_in_satoshis)}) unsigned_tx = create_unsigned_tx(inputs=inputs, outputs=outputs, api_key=BLOCKCYPHER_TOKEN) # iterate through unsigned_tx['tx']['inputs'] to find each address in order # need to include duplicates as many times as they may appear privkey_list = [] pubkey_list = [] for input in unsigned_tx['tx']['inputs']: privkey_list.append(payment_privkey) pubkey_list.append(get_pubkey_from_privkey(payment_privkey)) tx_signatures = make_tx_signatures(txs_to_sign=unsigned_tx['tosign'], privkey_list=privkey_list, pubkey_list=pubkey_list) resp = broadcast_signed_transaction(unsigned_tx=unsigned_tx, signatures=tx_signatures, pubkeys=pubkey_list) if 'tx' in resp: return resp['tx']['hash'] else: return None
def send_multi_payment(payment_privkey, list_of_addresses, payment_per_address): payment_address = get_address_from_privkey(payment_privkey) if dontuseAddress(payment_address): log.debug("Payment address %s not ready" % payment_address) return None inputs = [{'address': payment_address}] payment_in_satoshis = btc_to_satoshis(float(payment_per_address)) outputs = [] for address in list_of_addresses: outputs.append({'address': address, 'value': int(payment_in_satoshis)}) unsigned_tx = create_unsigned_tx(inputs=inputs, outputs=outputs, api_key=BLOCKCYPHER_TOKEN) # iterate through unsigned_tx['tx']['inputs'] to find each address in order # need to include duplicates as many times as they may appear privkey_list = [] pubkey_list = [] for input in unsigned_tx['tx']['inputs']: privkey_list.append(payment_privkey) pubkey_list.append(get_pubkey_from_privkey(payment_privkey)) tx_signatures = make_tx_signatures(txs_to_sign=unsigned_tx['tosign'], privkey_list=privkey_list, pubkey_list=pubkey_list) resp = broadcast_signed_transaction(unsigned_tx=unsigned_tx, signatures=tx_signatures, pubkeys=pubkey_list, api_key=BLOCKCYPHER_TOKEN) if 'tx' in resp: return resp['tx']['hash'] else: return None
def send_payment(hex_privkey, to_address, btc_amount): payment_address = get_address_from_privkey(hex_privkey) if dontuseAddress(payment_address): log.debug("Payment address %s not ready" % payment_address) return None to_satoshis = btc_to_satoshis(btc_amount) fee_satoshis = btc_to_satoshis(TX_FEE) signed_tx = make_send_to_address_tx(to_address, to_satoshis, hex_privkey, blockchain_client=blockcypher_client, fee=fee_satoshis) resp = pushtx(tx_hex=signed_tx, api_key=BLOCKCYPHER_TOKEN) if 'tx' in resp: return resp['tx']['hash'] else: log.debug("ERROR: broadcasting tx") return resp
def test_registrar_users(): """ Test if registrar has access to correct private keys """ for entry in registrar_users.find(): fqu = entry['username'] + ".id" data = c.get_name_blockchain_record(fqu) if 'error' in data: log.debug("Error while processing: (%s, %s)" % (fqu, data)) continue if entry['btc_address'] != data['address']: log.debug("registrar doesn't own: %s" % fqu) continue privkey = aes_decrypt(entry['encrypted_privkey'], SECRET_KEY) if get_address_from_privkey(privkey) == entry['btc_address']: log.debug("Correct pvtkey: %s" % fqu) else: log.debug("ERROR: wrong pvtkey: %s")
def preorder(fqu, payment_address, owner_address, payment_privkey=None): """ Preorder a fqu (step #1) @fqu: fully qualified name e.g., muneeb.id @payment_address: used for making the payment @owner_address: will own the fqu Returns True/False and stores tx_hash in queue """ # hack to ensure local, until we update client from blockstack_client import client as bs_client # start session using blockstack_client bs_client.session(server_host=BLOCKSTACKD_IP, server_port=BLOCKSTACKD_PORT, set_global=True) # stale preorder will get removed from preorder_queue if alreadyinQueue(register_queue, fqu): log.debug("Already in register queue: %s" % fqu) return False if alreadyinQueue(preorder_queue, fqu): log.debug("Already in preorder queue: %s" % fqu) return False if recipientNotReady(owner_address): log.debug("Address %s owns too many names already." % owner_address) return False if payment_privkey is None: payment_privkey = wallet.get_privkey_from_address(payment_address) else: payment_address = get_address_from_privkey(payment_privkey) if dontuseAddress(payment_address): log.debug("Payment address not ready: %s" % payment_address) return False elif underfundedAddress(payment_address): log.debug("Payment address under funded: %s" % payment_address) return False log.debug("Preordering (%s, %s, %s)" % (fqu, payment_address, owner_address)) resp = {} try: resp = bs_client.preorder(fqu, payment_privkey, owner_address) except Exception as e: log.debug(e) if 'tx_hash' in resp: add_to_queue(preorder_queue, fqu, payment_address=payment_address, tx_hash=resp['tx_hash'], owner_address=owner_address) else: log.debug("Error preordering: %s" % fqu) log.debug(pprint(resp)) raise ValueError('Error preordering') return False return True
def register(fqu, payment_address=None, owner_address=None, payment_privkey=None, auto_preorder=True): """ Register a previously preordered fqu (step #2) @fqu: fully qualified name e.g., muneeb.id @auto_preorder: automatically preorder, if true Uses from preorder queue: @payment_address: used for making the payment @owner_address: will own the fqu (must be same as preorder owner_address) Returns True/False and stores tx_hash in queue """ # check register_queue first # stale preorder will get removed from preorder_queue if alreadyinQueue(register_queue, fqu): log.debug("Already in register queue: %s" % fqu) return False if not alreadyinQueue(preorder_queue, fqu): if auto_preorder: return preorder(fqu, payment_address, owner_address) else: log.debug("No preorder sent yet: %s" % fqu) return False if nameRegistered(fqu): log.debug("Already registered %s" % fqu) return False preorder_entry = preorder_queue.find_one({"fqu": fqu}) preorder_tx = preorder_entry['tx_hash'] tx_confirmations = get_tx_confirmations(preorder_tx) if tx_confirmations < PREORDER_CONFIRMATIONS: log.debug("Waiting on preorder confirmations: (%s, %s)" % (preorder_tx, tx_confirmations)) return False if payment_privkey is None: # use the correct owner_address from preorder operation try: owner_address = preorder_entry['owner_address'] payment_address = preorder_entry['payment_address'] except: log.debug("Error getting preorder addresses") return False payment_privkey = wallet.get_privkey_from_address(payment_address) else: payment_address = get_address_from_privkey(payment_privkey) if dontuseAddress(payment_address): log.debug("Payment address not ready: %s" % payment_address) return False elif underfundedAddress(payment_address): log.debug("Payment address under funded: %s" % payment_address) return False log.debug("Registering (%s, %s, %s)" % (fqu, payment_address, owner_address)) resp = {} try: # do_register( fqu, payment_privkey, owner_address, utxo_client, tx_broadcaster, resp = do_register(fqu, payment_privkey, owner_address, utxo_client, tx_broadcaster) except Exception as e: log.debug(e) if 'transaction_hash' in resp: add_to_queue(register_queue, fqu, payment_address=payment_address, tx_hash=resp['transaction_hash'], owner_address=owner_address) else: log.debug("Error registering: %s" % fqu) log.debug(pprint(resp)) return False return True
def preorder(fqu, payment_address, owner_address, payment_privkey=None): """ Preorder a fqu (step #1) @fqu: fully qualified name e.g., muneeb.id @payment_address: used for making the payment @owner_address: will own the fqu Returns True/False and stores tx_hash in queue """ # stale preorder will get removed from preorder_queue if alreadyinQueue(register_queue, fqu): log.debug("Already in register queue: %s" % fqu) return False if alreadyinQueue(preorder_queue, fqu): log.debug("Already in preorder queue: %s" % fqu) return False if recipientNotReady(owner_address): log.debug("Address %s owns too many names already." % owner_address) return False if payment_privkey is None: payment_privkey = wallet.get_privkey_from_address(payment_address) else: payment_address = get_address_from_privkey(payment_privkey) if dontuseAddress(payment_address): log.debug("Payment address not ready: %s" % payment_address) return False elif underfundedAddress(payment_address): log.debug("Payment address under funded: %s" % payment_address) return False log.debug("Preordering (%s, %s, %s)" % (fqu, payment_address, owner_address)) resp = {} cost_info = get_name_cost(fqu) cost = cost_info['satoshis'] try: # do_preorder( fqu, payment_privkey, owner_address, cost, utxo_client, tx_broadcaster) resp = do_preorder(fqu, payment_privkey, owner_address, cost, utxo_client, tx_broadcaster) except Exception as e: log.debug(e) if 'transaction_hash' in resp: add_to_queue(preorder_queue, fqu, payment_address=payment_address, tx_hash=resp['transaction_hash'], owner_address=owner_address) else: log.debug("Error preordering: %s" % fqu) log.debug(pprint(resp)) raise ValueError('Error preordering') return False return True
def subsidized_update(fqu, profile, owner_privkey, payment_address, payment_privkey=None): """ Update a previously registered fqu, using a different payment address @fqu: fully qualified name e.g., muneeb.id @profile: new profile json, hash(profile) goes to blockchain @owner_privkey: privkey of owner address, to sign update @payment_address: the address which is paying for the cost Returns True/False and stores tx_hash in queue """ if alreadyinQueue(update_queue, fqu): log.debug("Already in update queue: %s" % fqu) return False if not nameRegistered(fqu): log.debug("Not yet registered %s" % fqu) return False profile_hash = get_hash(profile) blockchain_record = get_blockchain_record(fqu) owner_address = blockchain_record['address'] check_address = get_address_from_privkey(owner_privkey) if check_address != owner_address: log.debug("Given privkey/address doesn't own this name.") return False if dontuseAddress(payment_address): log.debug("Payment address not ready: %s" % payment_address) return False elif underfundedAddress(payment_address): log.debug("Payment address under funded: %s" % payment_address) return False owner_public_key = get_pubkey_from_privkey(owner_privkey) if payment_privkey is None: payment_privkey = wallet.get_privkey_from_address(payment_address) log.debug("Updating (%s, %s)" % (fqu, profile_hash)) log.debug("<owner, payment> (%s, %s)" % (owner_address, payment_address)) resp = {} try: # do_update( fqu, zonefile_hash, owner_privkey, payment_privkey, utxo_client, tx_broadcaster resp = do_update(fqu, profile_hash, owner_privkey, payment_privkey, utxo_client, tx_broadcaster) except Exception as e: log.debug(e) if 'transaction_hash' in resp: add_to_queue(update_queue, fqu, profile=profile, profile_hash=profile_hash, owner_address=owner_address, tx_hash=resp['transaction_hash']) else: log.debug("Error updating: %s" % fqu) log.debug(resp) return False return True
def get_master_address(self): hex_privkey = self.get_master_privkey() return get_address_from_privkey(hex_privkey)
def subsidized_transfer(fqu, transfer_address, owner_privkey, payment_address, payment_privkey=None): """ Transfer a previously registered fqu, using a different payment address @fqu: fully qualified name e.g., muneeb.id @transfer_address: new owner address @owner_privkey: privkey of current owner address, to sign tx @payment_address: the address which is paying for the cost Returns True/False and stores tx_hash in queue """ if alreadyinQueue(transfer_queue, fqu): log.debug("Already in transfer queue: %s" % fqu) return False if not nameRegistered(fqu): log.debug("Not yet registered %s" % fqu) return False if ownerName(fqu, transfer_address): log.debug("Already transferred %s" % fqu) return True if recipientNotReady(transfer_address): log.debug("Address %s owns too many names already." % transfer_address) return False blockchain_record = get_blockchain_record(fqu) owner_address = blockchain_record['address'] check_address = get_address_from_privkey(owner_privkey) if check_address != owner_address: log.debug("Given privkey/address doesn't own this name.") return False if dontuseAddress(payment_address): log.debug("Payment address not ready: %s" % payment_address) return False elif underfundedAddress(payment_address): log.debug("Payment address under funded: %s" % payment_address) return False owner_public_key = get_pubkey_from_privkey(owner_privkey) if payment_privkey is None: payment_privkey = wallet.get_privkey_from_address(payment_address) log.debug("Transferring (%s, %s)" % (fqu, transfer_address)) log.debug("<owner, payment> (%s, %s)" % (owner_address, payment_address)) resp = {} try: # do_transfer( fqu, transfer_address, keep_data, owner_privkey, payment_privkey, utxo_client, tx_broadcaster resp = do_transfer(fqu, transfer_address, True, owner_privkey, payment_privkey, utxo_client, tx_broadcaster) except Exception as e: log.debug(e) if 'transaction_hash' in resp: add_to_queue(transfer_queue, fqu, owner_address=owner_address, transfer_address=transfer_address, tx_hash=resp['transaction_hash']) else: log.debug("Error transferring: %s" % fqu) log.debug(resp) return False return True
def subsidized_transfer(fqu, transfer_address, owner_privkey, payment_address, payment_privkey=None): """ Transfer a previously registered fqu, using a different payment address @fqu: fully qualified name e.g., muneeb.id @transfer_address: new owner address @owner_privkey: privkey of current owner address, to sign tx @payment_address: the address which is paying for the cost Returns True/False and stores tx_hash in queue """ # hack to ensure local, until we update client from blockstack_client import client as bs_client # start session using blockstack_client bs_client.session(server_host=BLOCKSTACKD_IP, server_port=BLOCKSTACKD_PORT, set_global=True) if alreadyinQueue(transfer_queue, fqu): log.debug("Already in transfer queue: %s" % fqu) return False if not nameRegistered(fqu): log.debug("Not yet registered %s" % fqu) return False if ownerName(fqu, transfer_address): log.debug("Already transferred %s" % fqu) return True if recipientNotReady(transfer_address): log.debug("Address %s owns too many names already." % transfer_address) return False blockchain_record = get_blockchain_record(fqu) owner_address = blockchain_record['address'] check_address = get_address_from_privkey(owner_privkey) if check_address != owner_address: log.debug("Given privkey/address doens't own this name.") return False if dontuseAddress(payment_address): log.debug("Payment address not ready: %s" % payment_address) return False elif underfundedAddress(payment_address): log.debug("Payment address under funded: %s" % payment_address) return False owner_public_key = get_pubkey_from_privkey(owner_privkey) if payment_privkey is None: payment_privkey = wallet.get_privkey_from_address(payment_address) log.debug("Transferring (%s, %s)" % (fqu, transfer_address)) log.debug("<owner, payment> (%s, %s)" % (owner_address, payment_address)) resp = {} try: # format for transfer RPC call is: # (name, address, keep_data, public_key, subsidy_key) resp = bs_client.transfer_subsidized(fqu, transfer_address, True, public_key=owner_public_key, subsidy_key=payment_privkey) except Exception as e: log.debug(e) if 'subsidized_tx' in resp: unsigned_tx = resp['subsidized_tx'] else: log.debug("Error transferring: %s" % fqu) log.debug(pprint(resp)) return False broadcast_resp = send_subsidized(owner_privkey, unsigned_tx) if 'tx_hash' in broadcast_resp: add_to_queue(transfer_queue, fqu, owner_address=owner_address, transfer_address=transfer_address, tx_hash=broadcast_resp['tx_hash']) else: log.debug("Error transferring: %s" % fqu) log.debug(broadcast_resp) return False return True
def subsidized_update(fqu, profile, owner_privkey, payment_address, payment_privkey=None): """ Update a previously registered fqu, using a different payment address @fqu: fully qualified name e.g., muneeb.id @profile: new profile json, hash(profile) goes to blockchain @owner_privkey: privkey of owner address, to sign update @payment_address: the address which is paying for the cost Returns True/False and stores tx_hash in queue """ # hack to ensure local, until we update client from blockstack_client import client as bs_client # start session using blockstack_client bs_client.session(server_host=BLOCKSTACKD_IP, server_port=BLOCKSTACKD_PORT, set_global=True) if alreadyinQueue(update_queue, fqu): log.debug("Already in update queue: %s" % fqu) return False if not nameRegistered(fqu): log.debug("Not yet registered %s" % fqu) return False profile_hash = get_hash(profile) blockchain_record = get_blockchain_record(fqu) owner_address = blockchain_record['address'] check_address = get_address_from_privkey(owner_privkey) if check_address != owner_address: log.debug("Given privkey/address doens't own this name.") return False if dontuseAddress(payment_address): log.debug("Payment address not ready: %s" % payment_address) return False elif underfundedAddress(payment_address): log.debug("Payment address under funded: %s" % payment_address) return False owner_public_key = get_pubkey_from_privkey(owner_privkey) if payment_privkey is None: payment_privkey = wallet.get_privkey_from_address(payment_address) log.debug("Updating (%s, %s)" % (fqu, profile_hash)) log.debug("<owner, payment> (%s, %s)" % (owner_address, payment_address)) resp = {} try: resp = bs_client.update_subsidized(fqu, profile_hash, public_key=owner_public_key, subsidy_key=payment_privkey) except Exception as e: log.debug(e) if 'subsidized_tx' in resp: unsigned_tx = resp['subsidized_tx'] else: log.debug("Error updating: %s" % fqu) log.debug(resp) return False broadcast_resp = send_subsidized(owner_privkey, unsigned_tx) if 'tx_hash' in broadcast_resp: add_to_queue(update_queue, fqu, profile=profile, profile_hash=profile_hash, owner_address=owner_address, tx_hash=broadcast_resp['tx_hash']) else: log.debug("Error updating: %s" % fqu) log.debug(broadcast_resp) return False return True