def create_payment_transaction(from_tx, amount, to, node_private):
     tx = PaymentTransaction()
     tx.from_tx = from_tx
     tx.amount = amount
     tx.to = to
     tx.pubkey = Private.publickey(node_private)
     tx.signature = Private.sign(tx.get_hash(), node_private)
     return tx
    def parse(raw_data):
        deserializer = Deserializer(raw_data)
        tx_type = deserializer.parse_u8()
        if tx_type == Type.PUBLIC:
            tx = PublicKeyTransaction()
        elif tx_type == Type.RANDOM:
            tx = SplitRandomTransaction()
        elif tx_type == Type.PRIVATE:
            tx = PrivateKeyTransaction()
        elif tx_type == Type.COMMIT:
            tx = CommitRandomTransaction()
        elif tx_type == Type.REVEAL:
            tx = RevealRandomTransaction()

        elif tx_type == Type.STAKEHOLD:
            tx = StakeHoldTransaction()
        elif tx_type == Type.STAKERELEASE:
            tx = StakeReleaseTransaction()
        elif tx_type == Type.PENALTY:
            tx = PenaltyTransaction()

        elif tx_type == Type.NEGATIVE_GOSSIP:
            tx = NegativeGossipTransaction()
        elif tx_type == Type.POSITIVE_GOSSIP:
            tx = PositiveGossipTransaction()
        elif tx_type == Type.PENALTY_GOSSIP:
            tx = PenaltyGossipTransaction()

        elif tx_type == Type.PAYMENT:
            tx = PaymentTransaction()
        else:
            assert False, "Cannot parse unknown transaction type"
        tx.parse(deserializer.data)
        return tx
 def create_payment(input, number, outputs, amounts):
     tx = PaymentTransaction()
     tx.input = input
     tx.number = number
     tx.outputs = outputs
     tx.amounts = amounts
     return tx
    def test_add_outputs(self):
        output1 = os.urandom(32)
        output2 = os.urandom(32)
        payment = PaymentTransaction()
        payment.input = COINBASE_IDENTIFIER
        payment.number = 1
        payment.outputs = [output1, output2]
        payment.amounts = [123, 999]

        payment_hash = payment.get_hash()

        utxo = Utxo()
        utxo.add(payment)

        self.assertIn(payment_hash, utxo.utxo)
        self.assertEqual(len(utxo.utxo[payment_hash]), 2)
        self.assertEqual(utxo.utxo[payment_hash][0], 123)
        self.assertEqual(utxo.utxo[payment_hash][1], 999)
    def test_ignore_coinbase(self):
        block_reward = TransactionFactory.create_block_reward(
            os.urandom(32), 0)

        payment = PaymentTransaction()
        payment.input = block_reward.get_hash()
        payment.number = 0
        payment.outputs = [os.urandom(32), os.urandom(32)]
        payment.amounts = [129, 23423]

        spent, unspent = Resolver.resolve([[block_reward, payment]])

        #nothing spent since block reward just creates outputs
        self.assertEqual(len(spent), 0)

        #block reward was split in two ouputs by payment transaction
        self.assertEqual(len(unspent), 2)
        self.assertIn(Entry(payment.get_hash(), 0), unspent)
        self.assertIn(Entry(payment.get_hash(), 1), unspent)
    def test_spend_input(self):
        prev_tx = os.urandom(32)
        utxo = Utxo()
        utxo.utxo[prev_tx] = { 0 : 300 } # predefine utxo

        payment = PaymentTransaction()
        payment.input = prev_tx
        payment.number = 0
        payment.outputs = [os.urandom(32), os.urandom(32)]
        payment.amounts = [149, 151]

        utxo.add(payment) # spend it

        payment_hash = payment.get_hash()

        self.assertNotIn(prev_tx, utxo.utxo)
        self.assertIn(payment_hash, utxo.utxo)
        self.assertEqual(utxo.utxo[payment_hash][0], 149)
        self.assertEqual(utxo.utxo[payment_hash][1], 151)
    def test_conflict(self):
        input1 = os.urandom(32)
        payment1 = PaymentTransaction()
        payment1.input = input1
        payment1.number = 0
        payment1.outputs = [os.urandom(32), os.urandom(32)]
        payment1.amounts = [123, 999]

        payment1_hash = payment1.get_hash()

        # trying to spend the same input
        payment2 = PaymentTransaction()
        payment2.input = input1
        payment2.number = 0
        payment2.outputs = [os.urandom(32), os.urandom(32)]
        payment2.amounts = [1, 1]

        spent, unspent = Resolver.resolve(
            [[payment1, payment2]]
        )  #TODO is it okay that conflicting transactions are in the same block

        #zero input of random transaction should be marked as spent
        self.assertEqual(len(spent), 1)
        self.assertEqual(spent[0].tx, input1)
        self.assertEqual(spent[0].number, 0)

        #transaction spending the same output is rejected
        self.assertEqual(len(unspent), 2)
        self.assertIn(Entry(payment1_hash, 0), unspent)
        self.assertIn(Entry(payment1_hash, 1), unspent)
    def test_simple(self):
        input1 = os.urandom(32)
        payment1 = PaymentTransaction()
        payment1.input = input1
        payment1.number = 0
        payment1.outputs = [os.urandom(32), os.urandom(32)]
        payment1.amounts = [123, 999]

        payment1_hash = payment1.get_hash()

        output3 = os.urandom(32)
        output4 = os.urandom(32)
        payment2 = PaymentTransaction()
        payment2.input = payment1_hash
        payment2.number = 0
        payment2.outputs = [output3, output4]
        payment2.amounts = [555, 234]

        payment2_hash = payment2.get_hash()

        spent, unspent = Resolver.resolve([[payment1], [payment2]])

        #zero input of random transaction should be marked as spent
        self.assertEqual(len(spent), 1)
        self.assertEqual(spent[0].tx, input1)
        self.assertEqual(spent[0].number, 0)

        #zero output of payment1 tx is spent by payment2, so only 3 unspent outputs left here
        self.assertEqual(len(unspent), 3)
        self.assertIn(Entry(payment1_hash, 1), unspent)
        self.assertIn(Entry(payment2_hash, 0), unspent)
        self.assertIn(Entry(payment2_hash, 1), unspent)
    def test_payment_pack_unpack(self):
        original = PaymentTransaction()
        original.input = os.urandom(32)
        original.number = 1
        original.outputs = [os.urandom(32), os.urandom(32)]
        original.amounts = [123, 999]

        raw = original.pack()
        restored = PaymentTransaction()
        restored.parse(raw)

        self.assertEqual(original.get_hash(), restored.get_hash())