def make_transaction(name, data_hash, consensus_hash, payment_addr, blockchain_client, tx_fee=0, subsidize=False): """ Write a name update into the blockchain. Returns a JSON object with 'data' set to the nulldata and 'transaction_hash' set to the transaction hash on success. """ name = str(name) data_hash = str(data_hash) consensus_hash = str(consensus_hash) payment_addr = str(payment_addr) tx_fee = int(tx_fee) assert len(consensus_hash) == LENGTHS['consensus_hash'] * 2 assert is_name_valid(name) # sanity check pay_fee = True if subsidize: pay_fee = False inputs = get_unspents( payment_addr, blockchain_client ) nulldata = build(name, consensus_hash, data_hash=data_hash) outputs = make_outputs( nulldata, inputs, payment_addr, tx_fee, pay_fee=pay_fee ) return (inputs, outputs)
def make_transaction( namespace_id, register_addr, fee, consensus_hash, payment_addr, blockchain_client, tx_fee=0 ): """ Propagate a namespace. Arguments: namespace_id human-readable (i.e. base-40) name of the namespace register_addr the addr of the key that will reveal the namespace (mixed into the preorder to prevent name preimage attack races) private_key the Bitcoin address that created this namespace, and can populate it. """ namespace_id = str(namespace_id) register_addr = str(register_addr) fee = int(fee) consensus_hash = str(consensus_hash) payment_addr = str(payment_addr) tx_fee = int(tx_fee) assert is_namespace_valid(namespace_id) assert len(consensus_hash) == LENGTHS['consensus_hash'] * 2 script_pubkey = get_script_pubkey_from_addr( payment_addr ) nulldata = build( namespace_id, script_pubkey, register_addr, consensus_hash ) # get inputs and from address inputs = get_unspents( payment_addr, blockchain_client ) # build custom outputs here outputs = make_outputs(nulldata, inputs, payment_addr, fee, tx_fee ) return (inputs, outputs)
def analyze_private_key(private_key, blockchain_client): private_key_obj = get_private_key_obj(private_key) # determine the address associated with the supplied private key from_address = private_key_obj.public_key().address() # get the unspent outputs corresponding to the given address inputs = pybitcoin.get_unspents(from_address, blockchain_client) # return the inputs return private_key_obj, from_address, inputs
def broadcast(name, private_key, register_addr, blockchain_client, renewal_fee=None, blockchain_broadcaster=None, tx_only=False, user_public_key=None, subsidy_public_key=None, testset=False): # sanity check if subsidy_public_key is not None: # if subsidizing, we're only giving back a tx to be signed tx_only = True if subsidy_public_key is None and private_key is None: raise Exception("Missing both public and private key") if not tx_only and private_key is None: raise Exception("Need private key for broadcasting") if blockchain_broadcaster is None: blockchain_broadcaster = blockchain_client from_address = None change_inputs = None private_key_obj = None subsidized_renewal = False if subsidy_public_key is not None: # subsidizing pubk = BitcoinPublicKey( subsidy_public_key ) if user_public_key is not None and renewal_fee is not None: # renewing, and subsidizing the renewal from_address = BitcoinPublicKey( user_public_key ).address() subsidized_renewal = True else: # registering or renewing under the subsidy key from_address = pubk.address() change_inputs = get_unspents( from_address, blockchain_client ) elif private_key is not None: # ordering directly pubk = BitcoinPrivateKey( private_key ).public_key() public_key = pubk.to_hex() # get inputs and from address using private key private_key_obj, from_address, change_inputs = analyze_private_key(private_key, blockchain_client) nulldata = build(name, testset=testset) outputs = make_outputs(nulldata, change_inputs, register_addr, from_address, renewal_fee=renewal_fee, pay_fee=(not subsidized_renewal), format='hex') if tx_only: unsigned_tx = serialize_transaction( change_inputs, outputs ) return {"unsigned_tx": unsigned_tx} else: # serialize, sign, and broadcast the tx response = serialize_sign_and_broadcast(change_inputs, outputs, private_key_obj, blockchain_broadcaster) response.update({'data': nulldata}) return response
def broadcast(name_list, private_key, register_addr_list, consensus_hash, blockchain_client, fee, \ blockchain_broadcaster=None, subsidy_public_key=None, tx_only=False, testset=False): """ Builds and broadcasts a preorder transaction. @subsidy_public_key: if given, the public part of the subsidy key """ if subsidy_public_key is not None: # subsidizing, and only want the tx tx_only = True # sanity check if subsidy_public_key is None and private_key is None: raise Exception("Missing both client public and private key") if blockchain_broadcaster is None: blockchain_broadcaster = blockchain_client from_address = None # change address inputs = None private_key_obj = None script_pubkey = None # to be mixed into preorder hash if subsidy_public_key is not None: # subsidizing pubk = BitcoinPublicKey( subsidy_public_key ) from_address = BitcoinPublicKey( subsidy_public_key ).address() inputs = get_unspents( from_address, blockchain_client ) script_pubkey = get_script_pubkey( subsidy_public_key ) else: # ordering directly pubk = BitcoinPrivateKey( private_key ).public_key() public_key = pubk.to_hex() script_pubkey = get_script_pubkey( public_key ) # get inputs and from address using private key private_key_obj, from_address, inputs = analyze_private_key(private_key, blockchain_client) nulldata = build( name_list, script_pubkey, register_addr_list, consensus_hash, testset=testset) outputs = make_outputs(nulldata, inputs, from_address, fee, format='hex') if tx_only: unsigned_tx = serialize_transaction( inputs, outputs ) return {"unsigned_tx": unsigned_tx} else: # serialize, sign, and broadcast the tx response = serialize_sign_and_broadcast(inputs, outputs, private_key_obj, blockchain_client) response.update({'data': nulldata}) return response
def broadcast(name, data_hash, consensus_hash, private_key, blockchain_client, blockchain_broadcaster=None, tx_only=False, user_public_key=None, testset=False): """ Write a name update into the blockchain. Returns a JSON object with 'data' set to the nulldata and 'transaction_hash' set to the transaction hash on success. """ # sanity check pay_fee = True if user_public_key is not None: pay_fee = False tx_only = True if user_public_key is None and private_key is None: raise Exception("Missing both public and private key") if not tx_only and private_key is None: raise Exception("Need private key for broadcasting") if blockchain_broadcaster is None: blockchain_broadcaster = blockchain_client from_address = None inputs = None private_key_obj = None if user_public_key is not None: # subsidizing pubk = BitcoinPublicKey( user_public_key ) from_address = pubk.address() # get inputs from utxo provider inputs = get_unspents( from_address, blockchain_client ) elif private_key is not None: # ordering directly pubk = BitcoinPrivateKey( private_key ).public_key() public_key = pubk.to_hex() # get inputs and from address using private key private_key_obj, from_address, inputs = analyze_private_key(private_key, blockchain_client) nulldata = build(name, consensus_hash, data_hash=data_hash, testset=testset) outputs = make_outputs( nulldata, inputs, from_address, pay_fee=pay_fee ) if tx_only: unsigned_tx = serialize_transaction( inputs, outputs ) return {'unsigned_tx': unsigned_tx} else: signed_tx = tx_serialize_and_sign( inputs, outputs, private_key_obj ) response = broadcast_transaction( signed_tx, blockchain_broadcaster ) response.update({'data': nulldata}) return response
def broadcast(message_hash, private_key, blockchain_client, testset=False, blockchain_broadcaster=None, user_public_key=None, tx_only=False): # sanity check pay_fee = True if user_public_key is not None: pay_fee = False tx_only = True if user_public_key is None and private_key is None: raise Exception("Missing both public and private key") if not tx_only and private_key is None: raise Exception("Need private key for broadcasting") if len(message_hash) != 40: raise Exception("Invalid message hash: not 20 bytes") if not is_hex( message_hash ): raise Exception("Invalid message hash: not hex") if blockchain_broadcaster is None: blockchain_broadcaster = blockchain_client from_address = None inputs = None private_key_obj = None if user_public_key is not None: # subsidizing pubk = BitcoinPublicKey( user_public_key ) from_address = pubk.address() inputs = get_unspents( from_address, blockchain_client ) elif private_key is not None: # ordering directly pubk = BitcoinPrivateKey( private_key ).public_key() public_key = pubk.to_hex() private_key_obj, from_address, inputs = analyze_private_key(private_key, blockchain_client) nulldata = build(message_hash, testset=testset) outputs = make_outputs( nulldata, inputs, from_address, pay_fee=pay_fee ) if tx_only: unsigned_tx = serialize_transaction( inputs, outputs ) return {'unsigned_tx': unsigned_tx} else: signed_tx = tx_serialize_and_sign( inputs, outputs, private_key_obj ) response = broadcast_transaction( signed_tx, blockchain_broadcaster ) response.update({'data': nulldata}) return response
def broadcast(name, private_key, register_addr, consensus_hash, blockchain_client, fee, blockchain_broadcaster=None, tx_only=False, pay_fee=True, public_key=None, testset=False): """ Builds and broadcasts a preorder transaction. """ # sanity check if public_key is None and private_key is None: raise Exception("Missing both public and private key") if not tx_only and private_key is None: raise Exception("Need private key for broadcasting") if blockchain_broadcaster is None: blockchain_broadcaster = blockchain_client from_address = None inputs = None private_key_obj = None if private_key is not None: # ordering directly pubk = BitcoinPrivateKey( private_key ).public_key() public_key = pubk.to_hex() # get inputs and from address using private key private_key_obj, from_address, inputs = analyze_private_key(private_key, blockchain_client) elif public_key is not None: # subsidizing pubk = BitcoinPublicKey( public_key ) from_address = pubk.address() # get inputs from utxo provider inputs = get_unspents( from_address, blockchain_client ) script_pubkey = get_script_pubkey( public_key ) nulldata = build( name, script_pubkey, register_addr, consensus_hash, testset=testset) # build custom outputs here outputs = make_outputs(nulldata, inputs, from_address, fee, pay_fee=pay_fee, format='hex') if tx_only: unsigned_tx = serialize_transaction( inputs, outputs ) return {"unsigned_tx": unsigned_tx} else: # serialize, sign, and broadcast the tx response = serialize_sign_and_broadcast(inputs, outputs, private_key_obj, blockchain_client) response.update({'data': nulldata}) return response
def broadcast(name, private_key, blockchain_client, testset=False, blockchain_broadcaster=None, pay_fee=True, public_key=None, tx_only=False): # sanity check if public_key is None and private_key is None: raise Exception("Missing both public and private key") if not tx_only and private_key is None: raise Exception("Need private key for broadcasting") if blockchain_broadcaster is None: blockchain_broadcaster = blockchain_client from_address = None inputs = None private_key_obj = None if private_key is not None: # ordering directly pubk = BitcoinPrivateKey( private_key ).public_key() public_key = pubk.to_hex() # get inputs and from address using private key private_key_obj, from_address, inputs = analyze_private_key(private_key, blockchain_client) elif public_key is not None: # subsidizing pubk = BitcoinPublicKey( public_key ) from_address = pubk.address() # get inputs from utxo provider inputs = get_unspents( from_address, blockchain_client ) nulldata = build(name, testset=testset) outputs = make_op_return_outputs( nulldata, inputs, from_address, fee=DEFAULT_OP_RETURN_FEE, format='hex' ) if tx_only: unsigned_tx = serialize_transaction( inputs, outputs ) return {'unsigned_tx': unsigned_tx} else: signed_tx = tx_serialize_and_sign( inputs, outputs, private_key_obj ) response = broadcast_transaction( signed_tx, blockchain_broadcaster, format='hex') response.update({'data': nulldata}) return response
def make_transaction(name, payment_addr, blockchain_client, tx_fee=0, subsidize=False ): name = str(name) payment_addr = str(payment_addr) tx_fee = int(tx_fee) assert is_name_valid(name) # sanity check pay_fee = True if subsidize: pay_fee = False inputs = get_unspents( payment_addr, blockchain_client ) nulldata = build(name) outputs = make_outputs( nulldata, inputs, payment_addr, tx_fee, pay_fee=pay_fee ) return (inputs, outputs)
def make_transaction(name, recipient_address, update_hash, payment_addr, blockchain_client, tx_fee=0): name = str(name) recipient_address = str(recipient_address) update_hash = str(update_hash) payment_addr = str(payment_addr) tx_fee = int(tx_fee) assert is_name_valid(name) assert len(update_hash) == LENGTHS['update_hash'] * 2 nulldata = build(name) # convert update_hash from a hex string so it looks like an address update_hash_b58 = b58check_encode( unhexlify(update_hash) ) inputs = get_unspents( payment_addr, blockchain_client ) outputs = make_outputs(nulldata, inputs, recipient_address, payment_addr, update_hash_b58, tx_fee) return (inputs, outputs)
def make_transaction( namespace_id, reveal_addr, lifetime, coeff, base_cost, bucket_exponents, nonalpha_discount, no_vowel_discount, payment_addr, blockchain_client, tx_fee=0 ): """ Propagate a namespace. Arguments: namespace_id human-readable (i.e. base-40) name of the namespace reveal_addr address to own this namespace until it is ready lifetime: the number of blocks for which names will be valid (pass a negative value for "infinite") coeff: cost multipler base_cost: the base cost (i.e. cost of a 1-character name), in satoshis bucket_exponents: bucket cost exponents to which to raise the base cost nonalpha_discount: discount multipler for non-alpha-character names no_vowel_discount: discount multipler for no-vowel names """ namespace_id = str(namespace_id) reveal_addr = str(reveal_addr) lifetime = int(lifetime) coeff = int(coeff) base_cost = int(base_cost) nonalpha_discount = int(nonalpha_discount) no_vowel_discount = int(no_vowel_discount) payment_addr = str(payment_addr) tx_fee = int(tx_fee) bexp = [] for be in bucket_exponents: bexp.append(int(be)) bucket_exponents = bexp assert is_namespace_valid(namespace_id) nulldata = build( namespace_id, BLOCKSTACK_VERSION, reveal_addr, lifetime, coeff, base_cost, bucket_exponents, nonalpha_discount, no_vowel_discount ) # get inputs and from public key inputs = get_unspents( payment_addr, blockchain_client ) # build custom outputs here outputs = make_outputs(nulldata, inputs, reveal_addr, payment_addr, tx_fee) return (inputs, outputs)
def make_transaction( namespace_id, payment_addr, blockchain_client, tx_fee=0 ): """ Make the namespace ready transaction Raise ValueError if there are not enough inputs to make the transaction """ namespace_id = str(namespace_id) payment_addr = str(payment_addr) tx_fee = int(tx_fee) assert is_namespace_valid( namespace_id ) nulldata = build( namespace_id ) # get inputs and from public key inputs = get_unspents( payment_addr, blockchain_client ) # OP_RETURN outputs outputs = make_op_return_outputs( nulldata, inputs, payment_addr, fee=(DEFAULT_OP_RETURN_FEE + tx_fee), format='hex' ) return (inputs, outputs)
def make_transaction(message_hash, payment_addr, blockchain_client, tx_fee=0): message_hash = str(message_hash) payment_addr = str(payment_addr) tx_fee = int(tx_fee) # sanity check if len(message_hash) != 40: raise Exception("Invalid message hash: not 20 bytes") if not is_hex( message_hash ): raise Exception("Invalid message hash: not hex") inputs = None private_key_obj = None inputs = get_unspents( payment_addr, blockchain_client ) nulldata = build(message_hash) outputs = make_outputs( nulldata, inputs, payment_addr, tx_fee ) return (inputs, outputs)
def make_transaction(name, destination_address, keepdata, consensus_hash, payment_addr, blockchain_client, tx_fee=0, subsidize=False): name = str(name) destination_address = str(destination_address) consensus_hash = str(consensus_hash) payment_addr = str(payment_addr) tx_fee = int(tx_fee) assert len(consensus_hash) == LENGTHS['consensus_hash'] * 2 assert is_name_valid(name) # sanity check pay_fee = True if subsidize: pay_fee = False inputs = get_unspents( payment_addr, blockchain_client ) nulldata = build(name, keepdata, consensus_hash) outputs = make_outputs(nulldata, inputs, destination_address, payment_addr, tx_fee, pay_fee=pay_fee) return (inputs, outputs)
def get_utxos(address, config_path=CONFIG_PATH, utxo_client=None, min_confirmations=6): """ Given an address get unspent outputs (UTXOs) Return array of UTXOs, empty array if none available """ if utxo_client is None: utxo_client = get_utxo_provider_client(config_path=config_path) data = [] try: data = pybitcoin.get_unspents(address, utxo_client) except Exception as e: log.exception(e) log.debug("Error in getting UTXOs from UTXO provider: %s" % e) # filter minimum confirmations ret = [] for d in data: if not d.has_key('confirmations') or d['confirmations'] >= min_confirmations: ret.append(d) return ret
def make_transaction(name, payment_addr, register_addr, blockchain_client, tx_fee=0, renewal_fee=None): payment_addr = str(payment_addr) register_addr = str(register_addr) name = str(name) tx_fee = int(tx_fee) assert is_name_valid(name) if renewal_fee is not None: renewal_fee = int(renewal_fee) change_inputs = None subsidized_renewal = False change_inputs = get_unspents( payment_addr, blockchain_client ) if renewal_fee is not None: assert payment_addr == register_addr, "%s != %s" % (payment_addr, register_addr) subsidized_renewal = True nulldata = build(name) outputs = make_outputs(nulldata, change_inputs, register_addr, payment_addr, tx_fee, renewal_fee=renewal_fee, pay_fee=(not subsidized_renewal) ) return (change_inputs, outputs)
def get_unspents(addr): """ Get the list of unspent outputs for an address. """ global utxo_client return pybitcoin.get_unspents(addr, utxo_client)
def broadcast(name, private_key, register_addr, blockchain_client, renewal_fee=None, blockchain_broadcaster=None, tx_only=False, pay_fee=True, public_key=None, testset=False): # sanity check if public_key is None and private_key is None: raise Exception("Missing both public and private key") if not tx_only and private_key is None: raise Exception("Need private key for broadcasting") if blockchain_broadcaster is None: blockchain_broadcaster = blockchain_client from_address = None inputs = None private_key_obj = None if private_key is not None: # ordering directly pubk = BitcoinPrivateKey(private_key).public_key() public_key = pubk.to_hex() # get inputs and from address using private key private_key_obj, from_address, inputs = analyze_private_key( private_key, blockchain_client) elif public_key is not None: # subsidizing pubk = BitcoinPublicKey(public_key) from_address = pubk.address() # get inputs from utxo provider inputs = get_unspents(from_address, blockchain_client) nulldata = build(name, testset=testset) # build custom outputs here outputs = make_outputs(nulldata, inputs, register_addr, from_address, renewal_fee=renewal_fee, pay_fee=pay_fee, format='hex') if tx_only: unsigned_tx = serialize_transaction(inputs, outputs) return {"unsigned_tx": unsigned_tx} else: # serialize, sign, and broadcast the tx response = serialize_sign_and_broadcast(inputs, outputs, private_key_obj, blockchain_broadcaster) response.update({'data': nulldata}) return response
def broadcast(name, private_key, register_addr, consensus_hash, blockchain_client, fee, blockchain_broadcaster=None, subsidy_public_key=None, tx_only=False, testset=False): """ Builds and broadcasts a preorder transaction. @subsidy_public_key: if given, the public part of the subsidy key """ if subsidy_public_key is not None: # subsidizing, and only want the tx tx_only = True # sanity check if subsidy_public_key is None and private_key is None: raise Exception("Missing both client public and private key") if blockchain_broadcaster is None: blockchain_broadcaster = blockchain_client from_address = None # change address inputs = None private_key_obj = None script_pubkey = None # to be mixed into preorder hash if subsidy_public_key is not None: # subsidizing pubk = BitcoinPublicKey(subsidy_public_key) from_address = BitcoinPublicKey(subsidy_public_key).address() inputs = get_unspents(from_address, blockchain_client) script_pubkey = get_script_pubkey(subsidy_public_key) else: # ordering directly pubk = BitcoinPrivateKey(private_key).public_key() public_key = pubk.to_hex() script_pubkey = get_script_pubkey(public_key) # get inputs and from address using private key private_key_obj, from_address, inputs = analyze_private_key( private_key, blockchain_client) nulldata = build(name, script_pubkey, register_addr, consensus_hash, testset=testset) outputs = make_outputs(nulldata, inputs, from_address, fee, format='hex') if tx_only: unsigned_tx = serialize_transaction(inputs, outputs) return {"unsigned_tx": unsigned_tx} else: # serialize, sign, and broadcast the tx response = serialize_sign_and_broadcast(inputs, outputs, private_key_obj, blockchain_broadcaster) response.update({'data': nulldata}) return response
def get_unspents( addr ): """ Get the list of unspent outputs for an address. """ global utxo_client return pybitcoin.get_unspents( addr, utxo_client )