def create_payment_tx(self, deposit_tx, redeem_script, merchant_public_key, customer_public_key, amount, fee): # Find P2SH output index in deposit_tx deposit_utxo_index = deposit_tx.output_index_for_address( redeem_script.hash160()) # Look up deposit amount deposit_amount = deposit_tx.outputs[deposit_utxo_index].value - fee # Build unsigned payment transaction script_sig = Script() inp = TransactionInput(deposit_tx.hash, deposit_utxo_index, script_sig, 0xffffffff) out1 = TransactionOutput( amount, Script.build_p2pkh(merchant_public_key.hash160())) out2 = TransactionOutput( deposit_amount - amount, Script.build_p2pkh(customer_public_key.hash160())) payment_tx = Transaction(1, [inp], [out1, out2], 0x0) # Sign payment transaction public_key = redeem_script.customer_public_key private_key = self.get_private_for_public(public_key) sig = payment_tx.get_signature_for_input(0, Transaction.SIG_HASH_ALL, private_key, redeem_script)[0] # Update input script sig script_sig = Script([ sig.to_der() + utils.pack_compact_int(Transaction.SIG_HASH_ALL), 'OP_1', bytes(redeem_script) ]) payment_tx.inputs[0].script = script_sig return payment_tx
def write_ew_message(msg): """Write a message to the blockchain.""" print("write_ew_message({})" % msg) # Create a bitcoin script object with our message if len(msg) > 72: raise Exception('Message is too long and may not be accepted.') msg = "EW " + msg message_script = Script('OP_RETURN 0x{}'.format(utils.bytes_to_str(msg.encode()))) # Define the fee we're willing to pay for the tx tx_fee = 11000 # Get the first UTXO from our set that can cover the fee utxo = None for utxo_addr, utxos in wallet.get_utxos().items(): for u in utxos: if u.value > tx_fee: utxo = u break if utxo: break if not utxo: raise Exception('No UTXOs available to pay for the transaction.') # Build the transaction inputs (there is only one, but Transaction expects a list) inputs = [TransactionInput(outpoint=utxo.transaction_hash, outpoint_index=utxo.outpoint_index, script=utxo.script, sequence_num=0xffffffff)] outputs = [] # Build one output with our custom message script outputs.append(TransactionOutput(value=0, script=message_script)) # Build another output to pay the UTXO money back to one of our addresses _, change_key_hash = utils.address_to_key_hash(wallet._accounts[0].get_next_address(True)) outputs.append(TransactionOutput(value=utxo.value - tx_fee, script=Script.build_p2pkh(change_key_hash))) # Build an unsigned transaction object txn = Transaction(version=Transaction.DEFAULT_TRANSACTION_VERSION, inputs=inputs, outputs=outputs, lock_time=0 ) # Sign the transaction with the correct private key private_key = wallet.get_private_key(utxo_addr) txn.sign_input(input_index=0, hash_type=Transaction.SIG_HASH_ALL, private_key=private_key, sub_script=utxo.script ) # Broadcast the transaction tx = wallet.broadcast_transaction(txn.to_hex()) return tx
def create_deposit_tx(self, hash160): """Return a mocked deposit transaction.""" utxo_script_sig = Script.build_p2pkh( self._private_key.public_key.hash160()) inp = TransactionInput(outpoint=Hash('0' * 64), outpoint_index=0, script=utxo_script_sig, sequence_num=0xffffffff) out = TransactionOutput(value=120000, script=Script.build_p2sh(hash160)) txn = Transaction(version=Transaction.DEFAULT_TRANSACTION_VERSION, inputs=[inp], outputs=[out], lock_time=0) txn.sign_input(input_index=0, hash_type=Transaction.SIG_HASH_ALL, private_key=self._private_key, sub_script=utxo_script_sig) return txn