Ejemplo n.º 1
1
Archivo: Wallet.py Proyecto: fanff/QRL
    def _read_wallet(self):
        self.address_bundle = []

        if not os.path.isfile(self.wallet_dat_filename):
            return

        try:
            with open(self.wallet_dat_filename, "rb") as infile:
                wallet_store = qrl_pb2.WalletStore()
                wallet_store.ParseFromString(bytes(infile.read()))

                self.address_bundle = []
                for a in wallet_store.wallets:
                    tmpxmss = XMSS(config.dev.xmss_tree_height, mnemonic2bin(a.mnemonic.strip()))
                    tmpxmss.set_index(a.xmss_index)
                    if a.address.encode() != tmpxmss.get_address():
                        logger.fatal("Mnemonic and address do not match.")
                        exit(1)
                    self.address_bundle.append(AddressBundle(tmpxmss.get_address(), tmpxmss))

        except Exception as e:
            logger.warning("It was not possible to open the wallet: %s", e)
Ejemplo n.º 2
0
    def _read_wallet(self):
        self.address_bundle = []

        if not os.path.isfile(self.wallet_dat_filename):
            upgraded = self._upgrade_old_wallet()
            if not upgraded:
                return

        try:
            logger.info('Retrieving wallet file')
            with open(self.wallet_dat_filename, "rb") as infile:
                wallet_store = qrl_pb2.WalletStore()
                wallet_store.ParseFromString(bytes(infile.read()))

                self.address_bundle = []
                for a in wallet_store.wallets:
                    tmpxmss = XMSS(config.dev.xmss_tree_height,
                                   mnemonic2bin(a.mnemonic.strip()))
                    tmpxmss.set_index(a.xmss_index)
                    if a.address != tmpxmss.get_address():
                        logger.fatal("Mnemonic and address do not match.")
                        exit(1)
                    self.address_bundle.append(
                        AddressBundle(tmpxmss.get_address().encode(), tmpxmss))

        except Exception as e:
            logger.warning("It was not possible to open the wallet: %s", e)
Ejemplo n.º 3
0
class TestCoinBase(TestCase):
    def __init__(self, *args, **kwargs):
        super(TestCoinBase, self).__init__(*args, **kwargs)
        self.alice = XMSS(4, seed='a' * 48)
        self.alice.set_index(11)

        self.mock_blockheader = Mock(spec=BlockHeader)
        self.mock_blockheader.stake_selector = self.alice.get_address().encode(
        )
        self.mock_blockheader.block_reward = 50
        self.mock_blockheader.fee_reward = 40
        self.mock_blockheader.prev_blockheaderhash = sha256(b'prev_headerhash')
        self.mock_blockheader.block_number = 1
        self.mock_blockheader.headerhash = sha256(b'headerhash')

        self.maxDiff = None

    def test_create(self):
        tx = CoinBase.create(self.mock_blockheader, self.alice)
        self.assertIsInstance(tx, CoinBase)

    def test_to_json(self):
        tx = CoinBase.create(self.mock_blockheader, self.alice)
        txjson = tx.to_json()
        print(txjson)
        self.assertEqual(json.loads(test_json_CoinBase), json.loads(txjson))

    def test_from_txdict(self):
        tx = CoinBase.create(self.mock_blockheader, self.alice)
        self.assertIsInstance(tx, CoinBase)

        # Test that common Transaction components were copied over.
        self.assertEqual(0, tx.nonce)
        self.assertEqual(
            b'Q223bc5e5b78edfd778b1bf72702061cc053010711ffeefb9d969318be5d7b86b021b73c2',
            tx.txfrom)
        self.assertEqual(
            '3c523f9cc26f800863c003524392806ff6df373acb4d47cc607b62365fe4ab77'
            'cf3018d321df7dcb653c9f7968673e43d12cc26e3461b5f425fd5d977400fea5',
            bin2hstr(tx.PK))
        self.assertEqual(11, tx.ots_key)
        self.assertEqual(b'', tx.signature)
        self.assertEqual(
            '1a1274bedfc53287853c3aea5b8a93d64f2e4dff23ddbf96e52c8033f0107154',
            bin2hstr(tx.pubhash))

        self.assertEqual(
            'a62a1ef7faedf82aa1f562ff08a8b3cc7b3c4d4f45ef6c7653bf074df2cda122',
            bin2hstr(tx.txhash))

        # Test that specific content was copied over.
        self.assertEqual(
            b'Q223bc5e5b78edfd778b1bf72702061cc053010711ffeefb9d969318be5d7b86b021b73c2',
            tx.txto)
        self.assertEqual(tx.amount, 90)
Ejemplo n.º 4
0
    def test_sign_verify(self):
        message = "This is a test"
        message_bin = str2bin(message)

        xmss_height = 10
        seed = bytearray([i for i in range(48)])
        xmss = XMSS(xmss_height, seed)

        pk = xmss.pk()

        xmss.set_index(1)

        for i in range(10):
            self.assertTrue(xmss.get_index() == i + 1)
            signature = xmss.SIGN(message_bin)
            self.assertTrue(XMSS.VERIFY(message_bin, signature, pk))
Ejemplo n.º 5
0
    def test_sign_verify(self):
        message = "This is a test"
        message_bin = str2bin(message)

        xmss_height = 10
        seed = bytearray([i for i in range(48)])
        xmss = XMSS(xmss_height, seed)

        pk = xmss.pk()

        xmss.set_index(1)

        for i in range(10):
            self.assertTrue(xmss.get_index() == i + 1)
            signature = xmss.SIGN(message_bin)
            self.assertTrue(XMSS.VERIFY(message_bin, signature, pk))
Ejemplo n.º 6
0
class TestVote(TestCase):
    def __init__(self, *args, **kwargs):
        super(TestVote, self).__init__(*args, **kwargs)
        self.alice = XMSS(4, seed='a' * 48)
        self.alice.set_index(11)

        self.addr_from = self.alice.get_address().encode()
        self.blocknumber = 10
        self.headerhash = sha256(b'headerhash')

        self.maxDiff = None

    def test_create(self):
        tx = Vote.create(self.addr_from, self.blocknumber, self.headerhash,
                         self.alice)
        self.assertIsInstance(tx, Vote)

    def test_to_json(self):
        tx = Vote.create(self.addr_from, self.blocknumber, self.headerhash,
                         self.alice)
        txjson = tx.to_json()
        print(txjson)
        self.assertEqual(json.loads(test_json_Vote), json.loads(txjson))

    def test_from_txdict(self):
        tx = Vote.create(self.addr_from, self.blocknumber, self.headerhash,
                         self.alice)
        self.assertIsInstance(tx, Vote)

        # Test that common Transaction components were copied over.
        self.assertEqual(0, tx.nonce)
        self.assertEqual(
            b'Q223bc5e5b78edfd778b1bf72702061cc053010711ffeefb9d969318be5d7b86b021b73c2',
            tx.txfrom)
        self.assertEqual(
            '3c523f9cc26f800863c003524392806ff6df373acb4d47cc607b62365fe4ab77'
            'cf3018d321df7dcb653c9f7968673e43d12cc26e3461b5f425fd5d977400fea5',
            bin2hstr(tx.PK))
        self.assertEqual(11, tx.ots_key)
        self.assertEqual(b'', tx.signature)
        self.assertEqual(
            '1a1274bedfc53287853c3aea5b8a93d64f2e4dff23ddbf96e52c8033f0107154',
            bin2hstr(tx.pubhash))

        self.assertEqual(
            'b77410e48e9d8ee140c8b49d6331152e090fe3acc5dcd7e4cd3b4ea6bf8c3839',
            bin2hstr(tx.txhash))
Ejemplo n.º 7
0
    def _read_wallet(self):
        self.address_bundle = None
        if not os.path.isfile(self.wallet_dat_filename):
            return

        try:
            logger.info('Retrieving wallet file')
            with open(self.wallet_dat_filename, "r") as infile:
                data = json.load(infile)
                self.address_bundle = []
                for a in data:
                    tmpxmss = XMSS(
                        config.dev.xmss_tree_height,
                        mnemonic2bin(a['mnemonic'].strip(), wordlist))
                    tmpxmss.set_index(a['index'])
                    self.address_bundle.append(
                        AddressBundle(tmpxmss.get_address(), tmpxmss))
        except Exception as e:
            logger.warning("It was not possible to open the wallet: %s", e)
Ejemplo n.º 8
0
    def _upgrade_old_wallet(self):
        wallet_old_dat_filename = os.path.join(config.user.wallet_path, config.dev.wallet_old_dat_filename)
        if not os.path.isfile(wallet_old_dat_filename):
            return False

        logger.info("Found old wallet format. Upgrading")
        try:
            logger.info('Retrieving wallet file')
            with open(wallet_old_dat_filename, "r") as infile:
                data = json.load(infile)
                self.address_bundle = []
                for a in data:
                    tmpxmss = XMSS(config.dev.xmss_tree_height, mnemonic2bin(a['mnemonic'].strip()))
                    tmpxmss.set_index(a['index'])
                    self.address_bundle.append(AddressBundle(tmpxmss.get_address().encode(), tmpxmss))
        except Exception as e:
            logger.warning("It was not possible to open the wallet: %s", e)

        logger.info("Saving in the new format")
        self.save_wallet()
Ejemplo n.º 9
0
class TestSimpleTransaction(TestCase):
    def __init__(self, *args, **kwargs):
        super(TestSimpleTransaction, self).__init__(*args, **kwargs)
        self.alice = XMSS(4, seed='a' * 48)
        self.bob = XMSS(4, seed='b' * 48)

        self.alice.set_index(10)
        self.maxDiff = None

    def test_create(self):
        # Alice sending coins to Bob
        tx = TransferTransaction.create(
            addr_from=self.alice.get_address().encode(),
            addr_to=self.bob.get_address().encode(),
            amount=100,
            fee=1,
            xmss_pk=self.alice.pk(),
            xmss_ots_index=self.alice.get_index())
        self.assertTrue(tx)

    def test_create_negative_amount(self):
        with self.assertRaises(ValueError):
            TransferTransaction.create(
                addr_from=self.alice.get_address().encode(),
                addr_to=self.bob.get_address().encode(),
                amount=-100,
                fee=1,
                xmss_pk=self.alice.pk(),
                xmss_ots_index=self.alice.get_index())

    def test_create_negative_fee(self):
        with self.assertRaises(ValueError):
            TransferTransaction.create(
                addr_from=self.alice.get_address().encode(),
                addr_to=self.bob.get_address().encode(),
                amount=-100,
                fee=-1,
                xmss_pk=self.alice.pk(),
                xmss_ots_index=self.alice.get_index())

    def test_to_json(self):
        tx = TransferTransaction.create(
            addr_from=self.alice.get_address().encode(),
            addr_to=self.bob.get_address().encode(),
            amount=100,
            fee=1,
            xmss_pk=self.alice.pk(),
            xmss_ots_index=self.alice.get_index())
        txjson = tx.to_json()

        self.assertEqual(json.loads(test_json_Simple), json.loads(txjson))

    def test_from_json(self):
        tx = Transaction.from_json(test_json_Simple)
        self.assertIsInstance(tx, TransferTransaction)
        self.assertEqual(tx.subtype, qrl_pb2.Transaction.TRANSFER)

        # Test that common Transaction components were copied over.
        self.assertEqual(0, tx.nonce)
        self.assertEqual(
            b'Q223bc5e5b78edfd778b1bf72702061cc053010711ffeefb9d969318be5d7b86b021b73c2',
            tx.txfrom)
        self.assertEqual(
            '3c523f9cc26f800863c003524392806ff6df373acb4d47cc607b62365fe4ab77'
            'cf3018d321df7dcb653c9f7968673e43d12cc26e3461b5f425fd5d977400fea5',
            bin2hstr(tx.PK))
        self.assertEqual(
            '986299314d1489f0c23d70b689639c9c0059588563582cb7b21439b61583a5c0',
            bin2hstr(tx.txhash))
        self.assertEqual(10, tx.ots_key)
        self.assertEqual(b'', tx.signature)
        self.assertEqual(
            'e2e3d8b08e65b25411af455eb9bb402827fa7b600fa0b36011d62e26899dfa05',
            bin2hstr(tx.pubhash))

        # Test that specific content was copied over.
        self.assertEqual(
            b'Qfd5d64455903b8e500a14cafb1c4ea95a1f97562aaaa24d83e5b9dc3861a47386ce9ad15',
            tx.txto)
        self.assertEqual(100, tx.amount)
        self.assertEqual(1, tx.fee)

    def test_validate_tx(self):
        # If we change amount, fee, txfrom, txto, (maybe include xmss stuff) txhash should change.
        tx = TransferTransaction.create(
            addr_from=self.alice.get_address().encode(),
            addr_to=self.bob.get_address().encode(),
            amount=100,
            fee=1,
            xmss_pk=self.alice.pk(),
            xmss_ots_index=self.alice.get_index())

        # We must sign the tx before validation will work.
        tx.sign(self.alice)

        # We have not touched the tx: validation should pass.
        self.assertTrue(tx.validate_or_raise())

    def test_state_validate_tx(self):
        # Test balance not enough
        # Test negative tx amounts
        pass
Ejemplo n.º 10
0
class TestStakeTransaction(TestCase):
    def __init__(self, *args, **kwargs):
        super(TestStakeTransaction, self).__init__(*args, **kwargs)
        self.alice = XMSS(4, seed='a' * 48)
        self.bob = XMSS(4, seed='b' * 48)

        self.alice.set_index(10)
        self.maxDiff = None

    def test_create(self):
        tx = StakeTransaction.create(activation_blocknumber=2,
                                     xmss=self.alice,
                                     slavePK=self.bob.pk(),
                                     hashchain_terminator=sha256(b'T1'))
        self.assertTrue(tx)

    def test_to_json(self):
        tx = StakeTransaction.create(activation_blocknumber=2,
                                     xmss=self.alice,
                                     slavePK=self.bob.pk(),
                                     hashchain_terminator=sha256(b'T1'))
        txjson = tx.to_json()
        self.assertEqual(json.loads(test_json_Stake), json.loads(txjson))

    def test_from_json(self):
        tx = Transaction.from_json(test_json_Stake)
        self.assertIsInstance(tx, StakeTransaction)

        # Test that common Transaction components were copied over.
        self.assertEqual(0, tx.nonce)
        self.assertEqual(
            b'Q223bc5e5b78edfd778b1bf72702061cc053010711ffeefb9d969318be5d7b86b021b73c2',
            tx.txfrom)
        self.assertEqual(
            '3c523f9cc26f800863c003524392806ff6df373acb4d47cc607b62365fe4ab77'
            'cf3018d321df7dcb653c9f7968673e43d12cc26e3461b5f425fd5d977400fea5',
            bin2hstr(tx.PK))
        self.assertEqual(
            '06b0fcaf2e2ca69299a8a2ce32f0c05cd14cd61e25a9e324ffad8abc5a88aa7f',
            bin2hstr(tx.txhash))
        self.assertEqual(10, tx.ots_key)
        self.assertEqual(b'', tx.signature)
        self.assertEqual(
            'e2e3d8b08e65b25411af455eb9bb402827fa7b600fa0b36011d62e26899dfa05',
            bin2hstr(tx.pubhash))

        # Test that specific content was copied over.
        self.assertEqual(2, tx.activation_blocknumber)
        self.assertEqual(
            '380793debf8f72e70ef7351ee5005df6c7ca2320ff49e0ead0c40b19c7bb1cc1'
            '496e19a482c06350bdc054e4ed52a24ec8c994c44f9341d01190a81ab093ade8',
            bin2hstr(tx.slave_public_key))
        self.assertEqual(
            '1f93603db53bfad5c92390f735d0cbb8617b4ab8214ae91c5664a3d1e9b009c8',
            bin2hstr(tx.hash))

    def test_validate_tx(self):
        tx = StakeTransaction.create(activation_blocknumber=2,
                                     xmss=self.alice,
                                     slavePK=self.bob.pk(),
                                     hashchain_terminator=sha256(b'T1'))

        # We must sign the tx before validation will work.
        tx.sign(self.alice)

        # We haven't touched the tx: validation should pass
        self.assertTrue(tx.validate_or_raise())

    def test_get_message_hash(self):
        tx = StakeTransaction.create(activation_blocknumber=2,
                                     xmss=self.alice,
                                     slavePK=self.bob.pk(),
                                     hashchain_terminator=sha256(b'T1'))

        # Currently, a Transaction's message is always blank (what is it used for?)
        self.assertEqual(
            '06b0fcaf2e2ca69299a8a2ce32f0c05cd14cd61e25a9e324ffad8abc5a88aa7f',
            bin2hstr(tuple(tx.get_message_hash())))
Ejemplo n.º 11
0
class TestTransferTokenTransaction(TestCase):
    def __init__(self, *args, **kwargs):
        super(TestTransferTokenTransaction, self).__init__(*args, **kwargs)
        self.alice = XMSS(4, seed='a' * 48)
        self.bob = XMSS(4, seed='b' * 48)

        self.alice.set_index(10)
        self.maxDiff = None

    def test_create(self):

        tx = TransferTokenTransaction.create(
            addr_from=self.alice.get_address().encode(),
            token_txhash=b'000000000000000',
            addr_to=self.bob.get_address().encode(),
            amount=200000,
            fee=1,
            xmss_pk=self.alice.pk(),
            xmss_ots_index=self.alice.get_index())
        self.assertTrue(tx)

    def test_to_json(self):
        tx = TransferTokenTransaction.create(
            addr_from=self.alice.get_address().encode(),
            token_txhash=b'000000000000000',
            addr_to=self.bob.get_address().encode(),
            amount=200000,
            fee=1,
            xmss_pk=self.alice.pk(),
            xmss_ots_index=self.alice.get_index())
        txjson = tx.to_json()

        self.assertEqual(json.loads(test_json_TransferToken),
                         json.loads(txjson))

    def test_from_json(self):
        tx = Transaction.from_json(test_json_TransferToken)
        self.assertIsInstance(tx, TransferTokenTransaction)
        self.assertEqual(tx.subtype, qrl_pb2.Transaction.TRANSFERTOKEN)

        # Test that common Transaction components were copied over.
        self.assertEqual(
            b'Q223bc5e5b78edfd778b1bf72702061cc053010711ffeefb9d969318be5d7b86b021b73c2',
            tx.txfrom)
        self.assertEqual(
            '3c523f9cc26f800863c003524392806ff6df373acb4d47cc607b62365fe4ab77'
            'cf3018d321df7dcb653c9f7968673e43d12cc26e3461b5f425fd5d977400fea5',
            bin2hstr(tx.PK))
        self.assertEqual(b'000000000000000', tx.token_txhash)
        self.assertEqual(200000, tx.amount)
        self.assertEqual(
            '712ec52c483d1e513b83fd4d1210fd943903ae88e0c8048058b06d4e28a8727b',
            bin2hstr(tx.txhash))
        self.assertEqual(10, tx.ots_key)
        self.assertEqual(b'', tx.signature)
        self.assertEqual(
            'e2e3d8b08e65b25411af455eb9bb402827fa7b600fa0b36011d62e26899dfa05',
            bin2hstr(tx.pubhash))

        self.assertEqual(1, tx.fee)

    def test_validate_tx(self):
        tx = TransferTokenTransaction.create(
            addr_from=self.alice.get_address().encode(),
            token_txhash=b'000000000000000',
            addr_to=self.bob.get_address().encode(),
            amount=200000,
            fee=1,
            xmss_pk=self.alice.pk(),
            xmss_ots_index=self.alice.get_index())

        # We must sign the tx before validation will work.
        tx.sign(self.alice)

        # We have not touched the tx: validation should pass.
        self.assertTrue(tx.validate_or_raise())

    def test_state_validate_tx(self):
        # Test balance not enough
        # Test negative tx amounts
        pass
Ejemplo n.º 12
0
class TestTokenTransaction(TestCase):
    def __init__(self, *args, **kwargs):
        super(TestTokenTransaction, self).__init__(*args, **kwargs)
        self.alice = XMSS(4, seed='a' * 48)
        self.bob = XMSS(4, seed='b' * 48)

        self.alice.set_index(10)
        self.maxDiff = None

    def test_create(self):
        # Alice creates Token
        initial_balances = list()
        initial_balances.append(
            qrl_pb2.AddressAmount(address=self.alice.get_address().encode(),
                                  amount=400000000))
        initial_balances.append(
            qrl_pb2.AddressAmount(address=self.bob.get_address().encode(),
                                  amount=200000000))
        tx = TokenTransaction.create(
            addr_from=self.alice.get_address().encode(),
            symbol=b'QRL',
            name=b'Quantum Resistant Ledger',
            owner=
            b'Q223bc5e5b78edfd778b1bf72702061cc053010711ffeefb9d969318be5d7b86b021b73c2',
            decimals=4,
            initial_balances=initial_balances,
            fee=1,
            xmss_pk=self.alice.pk(),
            xmss_ots_index=self.alice.get_index())
        self.assertTrue(tx)

    def test_create_negative_fee(self):
        with self.assertRaises(ValueError):
            TokenTransaction.create(
                addr_from=self.alice.get_address().encode(),
                symbol=b'QRL',
                name=b'Quantum Resistant Ledger',
                owner=
                b'Q223bc5e5b78edfd778b1bf72702061cc053010711ffeefb9d969318be5d7b86b021b73c2',
                decimals=4,
                initial_balances=[],
                fee=-1,
                xmss_pk=self.alice.pk(),
                xmss_ots_index=self.alice.get_index())

    def test_to_json(self):
        initial_balances = list()
        initial_balances.append(
            qrl_pb2.AddressAmount(address=self.alice.get_address().encode(),
                                  amount=400000000))
        initial_balances.append(
            qrl_pb2.AddressAmount(address=self.bob.get_address().encode(),
                                  amount=200000000))
        tx = TokenTransaction.create(
            addr_from=self.alice.get_address().encode(),
            symbol=b'QRL',
            name=b'Quantum Resistant Ledger',
            owner=
            b'Q223bc5e5b78edfd778b1bf72702061cc053010711ffeefb9d969318be5d7b86b021b73c2',
            decimals=4,
            initial_balances=initial_balances,
            fee=1,
            xmss_pk=self.alice.pk(),
            xmss_ots_index=self.alice.get_index())
        txjson = tx.to_json()

        self.assertEqual(json.loads(test_json_Token), json.loads(txjson))

    def test_from_json(self):
        tx = Transaction.from_json(test_json_Token)
        self.assertIsInstance(tx, TokenTransaction)
        self.assertEqual(tx.subtype, qrl_pb2.Transaction.TOKEN)

        # Test that common Transaction components were copied over.
        self.assertEqual(
            b'Q223bc5e5b78edfd778b1bf72702061cc053010711ffeefb9d969318be5d7b86b021b73c2',
            tx.txfrom)
        self.assertEqual(
            '3c523f9cc26f800863c003524392806ff6df373acb4d47cc607b62365fe4ab77'
            'cf3018d321df7dcb653c9f7968673e43d12cc26e3461b5f425fd5d977400fea5',
            bin2hstr(tx.PK))
        self.assertEqual(b'QRL', tx.symbol)
        self.assertEqual(b'Quantum Resistant Ledger', tx.name)
        self.assertEqual(
            b'Q223bc5e5b78edfd778b1bf72702061cc053010711ffeefb9d969318be5d7b86b021b73c2',
            tx.owner)
        self.assertEqual(
            'f6d115628207da9c1bffec208aea7fb196d39433062b18f43619106c43cff4e9',
            bin2hstr(tx.txhash))
        self.assertEqual(10, tx.ots_key)
        self.assertEqual(b'', tx.signature)
        self.assertEqual(
            'e2e3d8b08e65b25411af455eb9bb402827fa7b600fa0b36011d62e26899dfa05',
            bin2hstr(tx.pubhash))

        total_supply = 0
        for initial_balance in tx.initial_balances:
            total_supply += initial_balance.amount
        self.assertEqual(600000000, total_supply)

        self.assertEqual(1, tx.fee)

    def test_validate_tx(self):
        initial_balances = list()
        initial_balances.append(
            qrl_pb2.AddressAmount(address=self.alice.get_address().encode(),
                                  amount=400000000))
        initial_balances.append(
            qrl_pb2.AddressAmount(address=self.bob.get_address().encode(),
                                  amount=200000000))
        tx = TokenTransaction.create(
            addr_from=self.alice.get_address().encode(),
            symbol=b'QRL',
            name=b'Quantum Resistant Ledger',
            owner=
            b'Q223bc5e5b78edfd778b1bf72702061cc053010711ffeefb9d969318be5d7b86b021b73c2',
            decimals=4,
            initial_balances=initial_balances,
            fee=1,
            xmss_pk=self.alice.pk(),
            xmss_ots_index=self.alice.get_index())

        # We must sign the tx before validation will work.
        tx.sign(self.alice)

        # We have not touched the tx: validation should pass.
        self.assertTrue(tx.validate_or_raise())

    def test_state_validate_tx(self):
        # Test balance not enough
        # Test negative tx amounts
        pass