예제 #1
0
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)
예제 #4
0
    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))
예제 #5
0
 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
예제 #6
0
    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)
예제 #7
0
    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)
예제 #8
0
    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))
예제 #9
0
    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))