def sign_transaction(self, prepared_tx): with FinalizableSigner(self.secret_manager) as signer: signed_tx = signer.sign_transaction(prepared_tx) # log the actual byte count tx_byte_count = tx_utils.get_byte_count(signed_tx) logging.info('The actual transaction size is %d bytes', tx_byte_count) signed_hextx = signed_tx.as_hex() logging.info('Signed hextx=%s', signed_hextx) return signed_tx
def issue_on_blockchain(self): """ Issue the certificates on the Bitcoin blockchain :param revocation_address: :return: """ self.tree.make_tree() op_return_value_bytes = unhexlify(self.tree.get_merkle_root()) op_return_value = hexlify(op_return_value_bytes) spendables = self.connector.get_unspent_outputs(self.issuing_address) if not spendables: error_message = 'No money to spend at address {}'.format(self.issuing_address) logging.error(error_message) raise InsufficientFundsError(error_message) last_input = spendables[-1] tx = self.transaction_handler.create_transaction(last_input, op_return_value_bytes) hex_tx = hexlify(tx.serialize()) logging.info('Unsigned hextx=%s', hex_tx) prepared_tx = tx_utils.prepare_tx_for_signing(hex_tx, [last_input]) with FinalizableSigner(self.secure_signer) as signer: signed_tx = signer.sign_transaction(prepared_tx) # log the actual byte count tx_byte_count = tx_utils.get_byte_count(signed_tx) logging.info('The actual transaction size is %d bytes', tx_byte_count) signed_hextx = signed_tx.as_hex() logging.info('Signed hextx=%s', signed_hextx) # verify transaction before broadcasting tx_utils.verify_transaction(signed_hextx, op_return_value) # send tx and persist txid tx_id = self.connector.broadcast_tx(signed_tx) if tx_id: logging.info('Broadcast transaction with txid %s', tx_id) else: logging.warning( 'could not broadcast transaction but you can manually do it! signed hextx=%s', signed_hextx) return tx_id
def issue_on_blockchain(self, revocation_address): """ Issue the certificates on the Bitcoin blockchain :param revocation_address: :return: """ transactions_data = self.create_transactions(revocation_address) for transaction_data in transactions_data: unsigned_tx_file_name = transaction_data.batch_metadata.unsigned_tx_file_name signed_tx_file_name = transaction_data.batch_metadata.unsent_tx_file_name sent_tx_file_name = transaction_data.batch_metadata.sent_tx_file_name # persist the transaction in case broadcasting fails hex_tx = hexlify(transaction_data.tx.serialize()) with open(unsigned_tx_file_name, 'w') as out_file: out_file.write(hex_tx) # sign transaction and persist result signed_tx = self.signer.sign_tx(hex_tx, transaction_data.tx_input, self.netcode) # log the actual byte count tx_byte_count = tx_utils.get_byte_count(signed_tx) logging.info('The actual transaction size is %d bytes', tx_byte_count) signed_hextx = signed_tx.as_hex() with open(signed_tx_file_name, 'w') as out_file: out_file.write(signed_hextx) # verify transaction before broadcasting tx_utils.verify_transaction(signed_hextx, transaction_data.op_return_value) # send tx and persist txid tx_id = self.connector.broadcast_tx(signed_tx) if tx_id: logging.info('Broadcast transaction with txid %s', tx_id) else: logging.warning( 'could not broadcast transaction but you can manually do it! signed hextx=%s', signed_hextx) self.persist_tx(sent_tx_file_name, tx_id)
def issue_on_blockchain(self): """ Issue the certificates on the Bitcoin blockchain :param revocation_address: :return: """ self.tree.make_tree() op_return_value_bytes = unhexlify(self.tree.get_merkle_root()) op_return_value = hexlify(op_return_value_bytes) for attempt_number in range(0, self.max_retry): try: if self.prepared_inputs: inputs = self.prepared_inputs else: spendables = self.connector.get_unspent_outputs( self.secure_signer.issuing_address) if not spendables: error_message = 'No money to spend at address {}'.format( self.secure_signer.issuing_address) logging.error(error_message) raise InsufficientFundsError(error_message) cost = self.transaction_handler.estimate_cost_for_certificate_batch( ) current_total = 0 inputs = [] random.shuffle(spendables) for s in spendables: inputs.append(s) current_total += s.coin_value if current_total > cost: break tx = self.transaction_handler.create_transaction( inputs, op_return_value_bytes) hex_tx = hexlify(tx.serialize()) logging.info('Unsigned hextx=%s', hex_tx) prepared_tx = tx_utils.prepare_tx_for_signing(hex_tx, inputs) with FinalizableSigner(self.secure_signer) as signer: signed_tx = signer.sign_transaction(prepared_tx) # log the actual byte count tx_byte_count = tx_utils.get_byte_count(signed_tx) logging.info('The actual transaction size is %d bytes', tx_byte_count) signed_hextx = signed_tx.as_hex() logging.info('Signed hextx=%s', signed_hextx) # verify transaction before broadcasting tx_utils.verify_transaction(signed_hextx, op_return_value) # send tx and persist txid tx_id = self.connector.broadcast_tx(signed_tx) logging.info('Broadcast transaction with txid %s', tx_id) return tx_id except BroadcastError: logging.warning( 'Failed broadcast reattempts. Trying to recreate transaction. This is attempt number %d', attempt_number) logging.error( 'All attempts to broadcast failed. Try rerunning issuer.') raise BroadcastError( 'All attempts to broadcast failed. Try rerunning issuer.')