def construct_transaction(sender_privkey, sender, recipient, amount, utxo_list): # collect all outputs necessary to pay that amount of money outputs_to_spend = [] value_to_spend = 0 for outp in utxo_list: outputs_to_spend.append(outp) value_to_spend += outp.value if value_to_spend >= amount: break # convert all outputs we are going to use in the ouputs # create outputs: to the recipient and change for the sender(if needed) outputs = [Output(amount, construct_transaction_locking_script(recipient))] if value_to_spend > amount: outputs.append( Output(value_to_spend - amount, construct_transaction_locking_script(sender))) inputs_with_no_script = [ Input(outp.txid, outp.vout, "") for outp in outputs_to_spend ] inputs = [] for inp in inputs_with_no_script: inputs.append( Input( inp.txid, inp.vout, construct_transaction_unlocking_script(sender_privkey, inputs_with_no_script, outputs, 0, utxo_list))) return Transaction(inputs, outputs, locktime=0)
def test_forming_sw_transaction_with_bech32_recipient_address(self): sender_privkey = "936abdc0429eb4b38a045fcb8f531ff7cf3888c3a83797df5d033106c4ea6a20" sender_address = "1NERjvtBxL5ErAKhCC3mfgWbp3QMd8y6ba" recipient_address = "tb1qtpjzz4h24ghxxvc79c99vln7ycwe8stldvz9v6" utxo_list = [ Output( 5000000000, "76a914e8e4b375038b0a1a1dc70543eab7ea6ce279df4388ac", txid= "07c0efe33946c5f81b5a86d79eda89e47979d4796d5ec675a9fccde7c31c4f50", vout=1) ] formed_tx = construct_witness_transaction(sender_privkey, sender_address, recipient_address, 800, utxo_list) self.assertEqual(2, len(formed_tx.outputs)) outp1 = formed_tx.outputs[0] outp2 = formed_tx.outputs[1] self.assertTrue(outp1.value + outp2.value <= 5000000000) self.assertEqual(800, outp1.value) self.assertEqual(1, len(formed_tx.witness)) self.assertEqual("", formed_tx.inputs[0].scriptsig)
def test_forming_sw_transaction(self): sender_privkey = "936abdc0429eb4b38a045fcb8f531ff7cf3888c3a83797df5d033106c4ea6a20" sender_address = "1NERjvtBxL5ErAKhCC3mfgWbp3QMd8y6ba" recipient_address = "1K9moTCMoSrA9bNdYTgMt6ac1nim83xScU" utxo_list = [ Output( 5000000000, "76a914e8e4b375038b0a1a1dc70543eab7ea6ce279df4388ac", txid= "07c0efe33946c5f81b5a86d79eda89e47979d4796d5ec675a9fccde7c31c4f50", vout=1) ] formed_tx = construct_witness_transaction(sender_privkey, sender_address, recipient_address, 800, utxo_list) self.assertEqual(2, len(formed_tx.outputs)) outp1 = formed_tx.outputs[0] outp2 = formed_tx.outputs[1] self.assertTrue(outp1.value + outp2.value <= 5000000000) self.assertEqual(800, outp1.value) self.assertEqual("0014c71afd5d2303c987ce8a4882ccb5c06636aaa224", outp1.scriptpubkey) self.assertEqual(1, len(formed_tx.witness)) self.assertEqual("", formed_tx.inputs[0].scriptsig)
def test_contains(self): storage = UTXOStorage(self.storage_filepath) storage.delete_all_otputs() outp0 = Output("", 10, txid="07c0efe33946c5f81b5a86d79eda89e47979d4796d5ec675a9fccde7c31c4f50", vout=1) self.assertFalse(storage.contains_output(outp0)) storage.add_new_output(outp0) self.assertTrue(storage.contains_output(outp0))
def update_with_new_transaction(self, tx: Transaction): outputs = self.get_all_outputs() for i in tx.inputs: used_output = Output(0, "", i.txid, i.vout) # todo ? return false if there is no such output self.delete_ouput_if_exists(used_output) for i, o in zip(range(1, len(tx.outputs) + 1), tx.outputs): o.txid = tx.txid o.vout = i self.add_new_output(o) return True
def test_get_all_unspent_outputs_for_address(self): storage = UTXOStorage(self.storage_filepath) storage.delete_all_otputs() outp1 = Output( 900, "76a914cabf271134a5f9228132598c8b4e6ad4586532f888ac", txid="1423215db125380dd21051c0d22f31fd4be2a25794b8789796343f4015c1baff", vout=1 ) outp2 = Output( 4999999100, "76a914e8e4b375038b0a1a1dc70543eab7ea6ce279df4388ac", txid="1423215db125380dd21051c0d22f31fd4be2a25794b8789796343f4015c1baff", vout=2 ) storage.add_new_output(outp1) storage.add_new_output(outp2) outp_list = storage.get_all_unspent_outputs_for_address("1KV2VGQiTB1B5KPEyyEPvifcqfS6PUxdxj") self.assertTrue(outp1 in outp_list) self.assertFalse(outp2 in outp_list)
def test_updating_utxo_pool_with_tx(self): storage = UTXOStorage(self.storage_filepath) storage.delete_all_otputs() outp0 = Output("", 10, txid="07c0efe33946c5f81b5a86d79eda89e47979d4796d5ec675a9fccde7c31c4f50", vout=1) storage.add_new_output(outp0) outp1 = Output( 900, "76a914cabf271134a5f9228132598c8b4e6ad4586532f888ac", txid="1423215db125380dd21051c0d22f31fd4be2a25794b8789796343f4015c1baff", vout=1 ) outp2 = Output( 4999999100, "76a914e8e4b375038b0a1a1dc70543eab7ea6ce279df4388ac", txid="1423215db125380dd21051c0d22f31fd4be2a25794b8789796343f4015c1baff", vout=2 ) tx = Transaction( [ Input( "07c0efe33946c5f81b5a86d79eda89e47979d4796d5ec675a9fccde7c31c4f50", 1, "404bb493aa8509356c1295c65acd3a44c339729d865422a47cb15631cda545ee3fc2eb86b418a5bb90202040430b723fdbf8429ff232bfa521c25da09539644093410450e829ca678c60031a11b990fea865e03ba35d0579aa62750b918b98c4b935d803ecc57a4bb2fc2ab1193a87fca5386d71516aca89df267fc907bcb3b84d396a" ) ], [outp1, outp2], 0 ) storage.update_with_new_transaction(tx) outp_list = storage.get_all_outputs() self.assertFalse(outp0 in outp_list) self.assertTrue(outp1 in outp_list) self.assertTrue(outp2 in outp_list)
def test_raw_transaction_creation(self): inputs = [Input( "fc9e4f9c334d55c1dc535bd691a1c159b0f7314c54745522257a905e18a56779", 1, "" )] outputs = [Output( 2207563, "0014db4d1141d0048b1ed15839d0b7a4c488cd368b0e" )] witness = ["47304402206a2eb16b7b92051d0fa38c133e67684ed064effada1d7f925c842da401d4f22702201f196b10e6e4b4a9fff948e5c5d71ec5da53e90529c8dbd122bff2b1d21dc8a90121039b7bcd0824b9a9164f7ba098408e63e5b7e3cf90835cceb19868f54f8961a825"] tx = Transaction(inputs, outputs, locktime=0, witness=witness, version=2) raw_tx = "020000000001017967a5185e907a25225574544c31f7b059c1a191d65b53dcc1554d339c4f9efc0100000000ffffffff014baf210000000000160014db4d1141d0048b1ed15839d0b7a4c488cd368b0e016a47304402206a2eb16b7b92051d0fa38c133e67684ed064effada1d7f925c842da401d4f22702201f196b10e6e4b4a9fff948e5c5d71ec5da53e90529c8dbd122bff2b1d21dc8a90121039b7bcd0824b9a9164f7ba098408e63e5b7e3cf90835cceb19868f54f8961a82500000000" self.assertEqual(raw_tx, Serializer.serialize_transaction(tx))
def test_deserialize_sw_transaction(self): sender_privkey = "936abdc0429eb4b38a045fcb8f531ff7cf3888c3a83797df5d033106c4ea6a20" sender_address = "1NERjvtBxL5ErAKhCC3mfgWbp3QMd8y6ba" recipient_address = "1K9moTCMoSrA9bNdYTgMt6ac1nim83xScU" utxo_list = [ Output( 5000000000, "76a914e8e4b375038b0a1a1dc70543eab7ea6ce279df4388ac", txid="07c0efe33946c5f81b5a86d79eda89e47979d4796d5ec675a9fccde7c31c4f50", vout=1 ) ] formed_tx = construct_witness_transaction(sender_privkey, sender_address, recipient_address, 800, utxo_list) serialized = Serializer.serialize_sw_transaction(formed_tx) self.assertEqual(formed_tx, Deserializer.deserialize_transaction(serialized))