Пример #1
0
 def test_create_negative_fee(self, m_logger):
     with self.assertRaises(ValueError):
         TokenTransaction.create(symbol=b'xrd',
                                 name=b'Quantum Resistant Ledger',
                                 owner=self.alice.address,
                                 decimals=4,
                                 initial_balances=[],
                                 fee=-1,
                                 xmss_pk=self.alice.pk)
Пример #2
0
    def relay_token_txn_by_slave(self, symbol: str, name: str,
                                 owner_qaddress: str, decimals: int,
                                 qaddresses: list, amounts: list, fee: int,
                                 master_qaddress):
        self.authenticate()

        if len(qaddresses) != len(amounts):
            raise Exception("Number of Addresses & Amounts Mismatch")

        index, group_index, slave_index, slave_xmss = self.get_slave_xmss(
            master_qaddress)
        if slave_index == -1:
            raise Exception("No Slave Found")

        initial_balances = []
        for idx, qaddress in enumerate(qaddresses):
            initial_balances.append(
                xrd_pb2.AddressAmount(
                    address=self.qaddress_to_address(qaddress),
                    amount=amounts[idx]))
        tx = TokenTransaction.create(
            symbol=symbol.encode(),
            name=name.encode(),
            owner=self.qaddress_to_address(owner_qaddress),
            decimals=decimals,
            initial_balances=initial_balances,
            fee=fee,
            xmss_pk=slave_xmss.pk,
            master_addr=self.qaddress_to_address(master_qaddress))

        self.sign_and_push_transaction(tx, slave_xmss, index, group_index,
                                       slave_index)

        return self.to_plain_transaction(tx.pbdata)
Пример #3
0
 def test_broadcast_tx(self, m_reactor, m_logger):
     # broadcast_tx() should handle all Transaction Types
     self.factory.broadcast_tx(MessageTransaction())
     self.factory.broadcast_tx(TransferTransaction())
     self.factory.broadcast_tx(TokenTransaction())
     self.factory.broadcast_tx(TransferTokenTransaction())
     self.factory.broadcast_tx(SlaveTransaction())
     with self.assertRaises(ValueError):
         m_tx = Mock(autospec=TransferTransaction, txhash=bhstr2bin('deadbeef'))
         self.factory.broadcast_tx(m_tx)
    def test_apply_state_changes_owner_not_in_address_state(self):
        """
        In this case, Alice didn't give herself any tokens. How generous! She gave them all to Bob.
        """
        initial_balances = [
            xrd_pb2.AddressAmount(address=self.bob.address, amount=1000)
        ]
        self.params["initial_balances"] = initial_balances

        tx = TokenTransaction.create(**self.params)
        tx.sign(self.alice)

        # Signing the TX also generates the txhash, which we need to generate the AddressState properly.
        addresses_state = dict(self.addresses_state)
        state_container = StateContainer(addresses_state=addresses_state,
                                         tokens=Indexer(b'token', None),
                                         slaves=Indexer(b'slave', None),
                                         lattice_pk=Indexer(
                                             b'lattice_pk', None),
                                         multi_sig_spend_txs=dict(),
                                         votes_stats=dict(),
                                         block_number=1,
                                         total_coin_supply=1000,
                                         current_dev_config=config.dev,
                                         write_access=True,
                                         my_db=self.state._db,
                                         batch=None)
        tx.apply(self.state, state_container)

        self.assertEqual(addresses_state[self.alice.address].balance, 99)
        self.assertEqual(addresses_state[self.bob.address].balance, 0)

        self.assertEqual(2, len(state_container.paginated_tx_hash.key_value))

        storage_key = state_container.paginated_tx_hash.generate_key(
            self.alice.address, 1)
        self.assertIn(storage_key, state_container.paginated_tx_hash.key_value)
        self.assertEqual(
            [tx.txhash],
            state_container.paginated_tx_hash.key_value[storage_key])

        storage_key = state_container.paginated_tx_hash.generate_key(
            self.bob.address, 1)
        self.assertIn(storage_key, state_container.paginated_tx_hash.key_value)
        self.assertEqual(
            [tx.txhash],
            state_container.paginated_tx_hash.key_value[storage_key])

        self.assertEqual(1, len(state_container.tokens.data))
        self.assertIn((self.bob.address, tx.txhash),
                      state_container.tokens.data)
        self.assertEqual(
            1000,
            state_container.tokens.data[(self.bob.address, tx.txhash)].balance)
Пример #5
0
    def test_affected_address(self, m_logger):
        tx = TokenTransaction.create(**self.params)
        # Default params should result in 2 affected addresses
        result = set()
        tx.set_affected_address(result)
        self.assertEqual(2, len(result))

        # If the slave is a recipient of tokens, he should be included too.
        slave = get_slave_xmss()
        result = set()
        self.initial_balances_valid.append(xrd_pb2.AddressAmount(address=slave.address, amount=1000))
        tx = TokenTransaction.create(symbol=b'xrd',
                                     name=b'Quantum Resistant Ledger',
                                     owner=self.alice.address,
                                     decimals=15,
                                     initial_balances=self.initial_balances_valid,
                                     fee=1,
                                     xmss_pk=self.alice.pk)
        tx.set_affected_address(result)
        self.assertEqual(3, len(result))
Пример #6
0
 def create_token_txn(symbol: bytes,
                      name: bytes,
                      owner: bytes,
                      decimals: int,
                      initial_balances,
                      fee: int,
                      xmss_pk: bytes,
                      master_addr: bytes):
     return TokenTransaction.create(symbol,
                                    name,
                                    owner,
                                    decimals,
                                    initial_balances,
                                    fee,
                                    xmss_pk,
                                    master_addr)
Пример #7
0
    def test_to_json(self, m_logger):
        initial_balances = list()
        initial_balances.append(xrd_pb2.AddressAmount(address=self.alice.address,
                                                      amount=400000000))
        initial_balances.append(xrd_pb2.AddressAmount(address=self.bob.address,
                                                      amount=200000000))
        tx = TokenTransaction.create(symbol=b'xrd',
                                     name=b'Quantum Resistant Ledger',
                                     owner=b'\x01\x03\x17F=\xcdX\x1bg\x9bGT\xf4ld%\x12T\x89\xa2\x82h\x94\xe3\xc4*Y\x0e\xfbh\x06E\x0c\xe6\xbfRql',
                                     decimals=4,
                                     initial_balances=initial_balances,
                                     fee=1,
                                     xmss_pk=self.alice.pk)
        txjson = tx.to_json()

        self.assertEqual(json.loads(test_json_Token), json.loads(txjson))
Пример #8
0
def get_token_transaction(xmss1,
                          xmss2,
                          amount1=400000000,
                          amount2=200000000,
                          fee=1) -> TokenTransaction:
    initial_balances = list()
    initial_balances.append(
        xrd_pb2.AddressAmount(address=xmss1.address, amount=amount1))
    initial_balances.append(
        xrd_pb2.AddressAmount(address=xmss2.address, amount=amount2))

    return TokenTransaction.create(symbol=b'xrd',
                                   name=b'Quantum Resistant Ledger',
                                   owner=xmss1.address,
                                   decimals=4,
                                   initial_balances=initial_balances,
                                   fee=fee,
                                   xmss_pk=xmss1.pk)
    def test_validate_tx(self):
        initial_balances = [
            xrd_pb2.AddressAmount(address=self.alice.address, amount=1000),
            xrd_pb2.AddressAmount(address=self.bob.address, amount=1000)
        ]
        slave = get_slave_xmss()
        self.params["initial_balances"] = initial_balances
        self.params["xmss_pk"] = slave.pk
        self.params["master_addr"] = self.alice.address
        tx = TokenTransaction.create(**self.params)
        tx.sign(slave)

        self.assertTrue(tx.validate_or_raise())

        tx._data.transaction_hash = b'abc'

        # Should fail, as we have modified with invalid transaction_hash
        with self.assertRaises(ValueError):
            tx.validate_or_raise()
    def test_apply_token_txn(self):
        """
        Alice creates a token. Obviously, she gives herself some of this token.
        But she also gives Bob some tokens too.
        """
        initial_balances = [
            xrd_pb2.AddressAmount(address=self.alice.address, amount=1000),
            xrd_pb2.AddressAmount(address=self.bob.address, amount=2000)
        ]
        self.params["initial_balances"] = initial_balances

        tx = TokenTransaction.create(**self.params)
        tx.sign(self.alice)
        addresses_state = dict(self.addresses_state)
        state_container = StateContainer(addresses_state=addresses_state,
                                         tokens=Indexer(b'token', None),
                                         slaves=Indexer(b'slave', None),
                                         lattice_pk=Indexer(
                                             b'lattice_pk', None),
                                         multi_sig_spend_txs=dict(),
                                         votes_stats=dict(),
                                         block_number=1,
                                         total_coin_supply=1000,
                                         current_dev_config=config.dev,
                                         write_access=True,
                                         my_db=self.state._db,
                                         batch=None)

        # According to the State, Alice has 100 coins, and Bob has 0 coins.
        # After applying the Transaction, Alice and Bob should have 1000 tokens, and Alice's balance should be 99.
        # AddressState.transaction_hashes now also reference the TokenTransaction that created the Tokens.
        self.assertFalse(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, 0))
        tx.apply(self.state, state_container)
        self.assertTrue(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, 0))
        self.assertEqual(addresses_state[self.alice.address].balance, 99)
        self.assertEqual(addresses_state[self.bob.address].balance, 0)

        self.assertEqual(2, len(state_container.paginated_tx_hash.key_value))

        storage_key = state_container.paginated_tx_hash.generate_key(
            self.alice.address, 1)
        self.assertIn(storage_key, state_container.paginated_tx_hash.key_value)
        self.assertEqual(
            [tx.txhash],
            state_container.paginated_tx_hash.key_value[storage_key])

        storage_key = state_container.paginated_tx_hash.generate_key(
            self.bob.address, 1)
        self.assertIn(storage_key, state_container.paginated_tx_hash.key_value)
        self.assertEqual(
            [tx.txhash],
            state_container.paginated_tx_hash.key_value[storage_key])

        self.assertEqual(2, len(state_container.tokens.data))
        self.assertIn((self.alice.address, tx.txhash),
                      state_container.tokens.data)
        self.assertEqual(
            1000, state_container.tokens.data[(self.alice.address,
                                               tx.txhash)].balance)
        self.assertIn((self.bob.address, tx.txhash),
                      state_container.tokens.data)
        self.assertEqual(
            2000,
            state_container.tokens.data[(self.bob.address, tx.txhash)].balance)
    def test_revert_token_txn_signed_by_slave_xmss(self):
        """
        Alice creates a token, gives herself and Bob some tokens.
        But she uses a XMSS slave to sign it.
        Can we undo it?
        """
        initial_balances = [
            xrd_pb2.AddressAmount(address=self.alice.address, amount=1000),
            xrd_pb2.AddressAmount(address=self.bob.address, amount=2000)
        ]
        slave = get_slave_xmss()
        self.params["initial_balances"] = initial_balances
        self.params["xmss_pk"] = slave.pk
        self.params["master_addr"] = self.alice.address
        tx = TokenTransaction.create(**self.params)
        tx.sign(slave)

        # Now that we have the Slave XMSS address, we should add it to AddressState so that apply_state_changes()
        # can do something with it
        addresses_state = dict(self.addresses_state)
        addresses_state[slave.address] = OptimizedAddressState.get_default(
            slave.address)
        addresses_state[slave.address].pbdata.nonce = 1

        # Also, update the AddressStates manually!
        addresses_state[self.alice.address].pbdata.balance = 100
        addresses_state[self.bob.address].pbdata.balance = 0
        state_container = StateContainer(addresses_state=addresses_state,
                                         tokens=Indexer(b'token', None),
                                         slaves=Indexer(b'slave', None),
                                         lattice_pk=Indexer(
                                             b'lattice_pk', None),
                                         multi_sig_spend_txs=dict(),
                                         votes_stats=dict(),
                                         block_number=1,
                                         total_coin_supply=1000,
                                         current_dev_config=config.dev,
                                         write_access=True,
                                         my_db=self.state._db,
                                         batch=None)
        state_container.paginated_bitfield.set_ots_key(addresses_state,
                                                       slave.address, 0)

        self.assertTrue(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                slave.address, 0))
        tx.apply(self.state, state_container)
        tx.revert(self.state, state_container)
        self.assertFalse(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                slave.address, 0))

        self.assertEqual(addresses_state[self.alice.address].balance, 100)
        self.assertEqual(3, len(state_container.paginated_tx_hash.key_value))

        storage_key = state_container.paginated_tx_hash.generate_key(
            self.alice.address, 1)
        self.assertIn(storage_key, state_container.paginated_tx_hash.key_value)
        self.assertEqual(
            [], state_container.paginated_tx_hash.key_value[storage_key])

        storage_key = state_container.paginated_tx_hash.generate_key(
            self.bob.address, 1)
        self.assertIn(storage_key, state_container.paginated_tx_hash.key_value)
        self.assertEqual(
            [], state_container.paginated_tx_hash.key_value[storage_key])

        storage_key = state_container.paginated_tx_hash.generate_key(
            slave.address, 1)
        self.assertIn(storage_key, state_container.paginated_tx_hash.key_value)
        self.assertEqual(
            [], state_container.paginated_tx_hash.key_value[storage_key])

        self.assertEqual(2, len(state_container.tokens.data))
        self.assertIn((self.alice.address, tx.txhash),
                      state_container.tokens.data)
        self.assertEqual(
            0, state_container.tokens.data[(self.alice.address,
                                            tx.txhash)].balance)
        self.assertIn((self.bob.address, tx.txhash),
                      state_container.tokens.data)
        self.assertEqual(
            0,
            state_container.tokens.data[(self.bob.address, tx.txhash)].balance)
        self.assertFalse(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, 0))
        self.assertFalse(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.bob.address, 0))
    def test_revert_token_txn_owner_not_in_address_state(self):
        """
        In this case, Alice didn't give herself any tokens. How generous! She gave them all to Bob.
        But we want to revert this.
        """
        initial_balances = [
            xrd_pb2.AddressAmount(address=self.bob.address, amount=1000)
        ]
        self.params["initial_balances"] = initial_balances

        tx = TokenTransaction.create(**self.params)
        tx.sign(self.alice)

        addresses_state = dict(self.addresses_state)
        addresses_state[self.alice.address].pbdata.balance = 100
        state_container = StateContainer(addresses_state=addresses_state,
                                         tokens=Indexer(b'token', None),
                                         slaves=Indexer(b'slave', None),
                                         lattice_pk=Indexer(
                                             b'lattice_pk', None),
                                         multi_sig_spend_txs=dict(),
                                         votes_stats=dict(),
                                         block_number=1,
                                         total_coin_supply=1000,
                                         current_dev_config=config.dev,
                                         write_access=True,
                                         my_db=self.state._db,
                                         batch=None)

        state_container.paginated_bitfield.set_ots_key(addresses_state,
                                                       self.alice.address, 0)

        self.assertTrue(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, 0))
        tx.apply(self.state, state_container)
        tx.revert(self.state, state_container)
        self.assertFalse(
            state_container.paginated_bitfield.load_bitfield_and_ots_key_reuse(
                self.alice.address, 0))

        self.assertEqual(addresses_state[self.alice.address].balance, 100)
        self.assertEqual(addresses_state[self.bob.address].balance, 0)

        self.assertEqual(2, len(state_container.paginated_tx_hash.key_value))

        storage_key = state_container.paginated_tx_hash.generate_key(
            self.alice.address, 1)
        self.assertIn(storage_key, state_container.paginated_tx_hash.key_value)
        self.assertEqual(
            [], state_container.paginated_tx_hash.key_value[storage_key])

        storage_key = state_container.paginated_tx_hash.generate_key(
            self.bob.address, 1)
        self.assertIn(storage_key, state_container.paginated_tx_hash.key_value)
        self.assertEqual(
            [], state_container.paginated_tx_hash.key_value[storage_key])

        self.assertEqual(1, len(state_container.tokens.data))
        self.assertIn((self.bob.address, tx.txhash),
                      state_container.tokens.data)
        self.assertEqual(
            0,
            state_container.tokens.data[(self.bob.address, tx.txhash)].balance)
    def test_revert_token_txn(self):
        """
        Same setup as in test_apply_state_changes(). This time though, the changes have already been applied,
        and we would like to roll them back.
        """
        initial_balances = [
            xrd_pb2.AddressAmount(address=self.alice.address, amount=1000),
            xrd_pb2.AddressAmount(address=self.bob.address, amount=2000)
        ]
        self.params["initial_balances"] = initial_balances

        tx = TokenTransaction.create(**self.params)
        tx.sign(self.alice)
        # Apply the changes!
        tx = TokenTransaction.create(**self.params)
        tx.sign(self.alice)
        addresses_state = dict(self.addresses_state)
        addresses_state[self.alice.address].pbdata.balance = 100
        state_container = StateContainer(addresses_state=addresses_state,
                                         tokens=Indexer(b'token', None),
                                         slaves=Indexer(b'slave', None),
                                         lattice_pk=Indexer(
                                             b'lattice_pk', None),
                                         multi_sig_spend_txs=dict(),
                                         votes_stats=dict(),
                                         block_number=1,
                                         total_coin_supply=1000,
                                         current_dev_config=config.dev,
                                         write_access=True,
                                         my_db=self.state._db,
                                         batch=None)

        # After applying the Transaction, it should be as if Alice had never created the tokens in the first place.
        tx.apply(self.state, state_container)
        tx.revert(self.state, state_container)

        self.assertEqual(addresses_state[self.alice.address].balance, 100)
        self.assertEqual(addresses_state[self.bob.address].balance, 0)

        self.assertEqual(2, len(state_container.paginated_tx_hash.key_value))

        storage_key = state_container.paginated_tx_hash.generate_key(
            self.alice.address, 1)
        self.assertIn(storage_key, state_container.paginated_tx_hash.key_value)
        self.assertEqual(
            [], state_container.paginated_tx_hash.key_value[storage_key])

        storage_key = state_container.paginated_tx_hash.generate_key(
            self.bob.address, 1)
        self.assertIn(storage_key, state_container.paginated_tx_hash.key_value)
        self.assertEqual(
            [], state_container.paginated_tx_hash.key_value[storage_key])

        self.assertEqual(2, len(state_container.tokens.data))
        self.assertIn((self.alice.address, tx.txhash),
                      state_container.tokens.data)
        self.assertEqual(
            0, state_container.tokens.data[(self.alice.address,
                                            tx.txhash)].balance)
        self.assertIn((self.bob.address, tx.txhash),
                      state_container.tokens.data)
        self.assertEqual(
            0,
            state_container.tokens.data[(self.bob.address, tx.txhash)].balance)
        self.assertEqual(0, addresses_state[self.alice.address].nonce)
Пример #14
0
 def make_tx(self, **kwargs):
     self.params.update(kwargs)
     tx = TokenTransaction.create(**self.params)
     return tx
Пример #15
0
    def test_validate_extended(self, m_validate_slave, m_logger):
        """
        TokenTransaction._validate_extended checks for:
        1. valid master/slave
        2. from address is valid
        3. owner address is valid
        4. addresses that own the initial balances are valid
        5. that the AddressState has enough coins to pay the Transaction fee (because no coins are being transferred)
        6. OTS key reuse
        """
        alice_address_state = OptimizedAddressState.get_default(self.alice.address)
        alice_address_state.pbdata.balance = 100

        tx = TokenTransaction.create(**self.params)
        tx.sign(self.alice)
        addresses_state = {
            alice_address_state.address: alice_address_state
        }
        state_container = StateContainer(addresses_state=addresses_state,
                                         tokens=Indexer(b'token', None),
                                         slaves=Indexer(b'slave', None),
                                         lattice_pk=Indexer(b'lattice_pk', None),
                                         multi_sig_spend_txs=dict(),
                                         votes_stats=dict(),
                                         block_number=1,
                                         total_coin_supply=1000,
                                         current_dev_config=config.dev,
                                         write_access=True,
                                         my_db=self.state._db,
                                         batch=None)
        result = tx._validate_extended(state_container)
        self.assertTrue(result)

        m_validate_slave.return_value = False
        result = tx.validate_all(state_container)
        self.assertFalse(result)
        m_validate_slave.return_value = True

        with patch('xrd.core.txs.TokenTransaction.TokenTransaction.addr_from',
                   new_callable=PropertyMock) as m_addr_from:
            m_addr_from.return_value = b'Invalid Address'
            result = tx._validate_extended(state_container)
            self.assertFalse(result)

        with patch('xrd.core.txs.TokenTransaction.TokenTransaction.owner', new_callable=PropertyMock) as m_owner:
            m_owner.return_value = b'Invalid Address'
            result = tx._validate_extended(state_container)
            self.assertFalse(result)

        with patch('xrd.core.txs.TokenTransaction.TokenTransaction.initial_balances',
                   new_callable=PropertyMock) as m_address_balance:
            m_address_balance.return_value = [xrd_pb2.AddressAmount(address=b'Invalid Address 1', amount=1000),
                                              xrd_pb2.AddressAmount(address=b'Invalid Address 2', amount=1000)]
            result = tx._validate_extended(state_container)
            self.assertFalse(result)

        alice_address_state.pbdata.balance = 0
        result = tx._validate_extended(state_container)
        self.assertFalse(result)
        alice_address_state.pbdata.balance = 100

        addresses_state = {
            self.alice.address: alice_address_state
        }
        # addr_from_pk has used this OTS key before
        state_container.paginated_bitfield.set_ots_key(addresses_state, alice_address_state.address, tx.ots_key)
        result = tx.validate_all(state_container)
        self.assertFalse(result)

        # Token symbol too long
        tx = self.make_tx(symbol=b'xrdSxrdSxrd')
        tx.sign(self.alice)
        self.assertFalse(tx._validate_extended(state_container))

        # Token name too long
        tx = self.make_tx(name=b'Quantum Resistant LedgerQuantum')
        tx.sign(self.alice)
        self.assertFalse(tx._validate_extended(state_container))

        # Token symbol missing
        with self.assertRaises(ValueError):
            tx = self.make_tx(symbol=b'')
            tx.sign(self.alice)
            self.assertFalse(tx._validate_extended(state_container))

        # Token name missing
        with self.assertRaises(ValueError):
            tx = self.make_tx(name=b'')
            tx.sign(self.alice)
            tx._validate_extended(state_container)

        # Empty initial_balances
        with self.assertRaises(ValueError):
            tx = self.make_tx(initial_balances=[])
            tx.sign(self.alice)
            self.assertFalse(tx._validate_extended(state_container))

        # Invalid initial balances... 0!
        with self.assertRaises(ValueError):
            initial_balances_0_0 = [xrd_pb2.AddressAmount(address=self.alice.address, amount=0),
                                    xrd_pb2.AddressAmount(address=self.bob.address, amount=0)]
            tx = self.make_tx(initial_balances=initial_balances_0_0)
            tx.sign(self.alice)
            self.assertFalse(tx._validate_extended(state_container))

        # Fee is -1
        with patch('xrd.core.txs.TokenTransaction.TokenTransaction.fee', new_callable=PropertyMock) as m_fee:
            m_fee.return_value = -1
            with self.assertRaises(ValueError):
                tx = self.make_tx()
                tx.sign(self.alice)
Пример #16
0
def tx_token(ctx, src, master, symbol, name, owner, decimals, fee, ots_key_index):
    """
    Create Token Transaction, that results into the formation of new token if accepted.
    """

    initial_balances = []

    if decimals > 19:
        click.echo("The number of decimal cannot exceed 19 under any possible configuration")
        quit(1)

    while True:
        address = click.prompt('Address ', default='')
        if address == '':
            break
        amount = int(click.prompt('Amount ')) * (10 ** int(decimals))
        initial_balances.append(xrd_pb2.AddressAmount(address=parse_qaddress(address),
                                                      amount=amount))

    try:
        _, src_xmss = _select_wallet(ctx, src)
        if not src_xmss:
            click.echo("A local wallet is required to sign the transaction")
            quit(1)

        address_src_pk = src_xmss.pk

        ots_key_index = validate_ots_index(ots_key_index, src_xmss)
        src_xmss.set_ots_index(ots_key_index)

        address_owner = parse_qaddress(owner)
        master_addr = None
        if master:
            master_addr = parse_qaddress(master)
        # FIXME: This could be problematic. Check
        fee_shor = _quanta_to_shor(fee)

        if len(name) > config.dev.max_token_name_length:
            raise Exception("Token name must be shorter than {} chars".format(config.dev.max_token_name_length))
        if len(symbol) > config.dev.max_token_symbol_length:
            raise Exception("Token symbol must be shorter than {} chars".format(config.dev.max_token_symbol_length))

    except KeyboardInterrupt:
        click.echo("Terminated by user")
        quit(1)
    except Exception as e:
        click.echo("Error validating arguments: {}".format(e))
        quit(1)

    try:
        stub = ctx.obj.get_stub_public_api()
        tx = TokenTransaction.create(symbol=symbol.encode(),
                                     name=name.encode(),
                                     owner=address_owner,
                                     decimals=decimals,
                                     initial_balances=initial_balances,
                                     fee=fee_shor,
                                     xmss_pk=address_src_pk,
                                     master_addr=master_addr)

        tx.sign(src_xmss)

        push_transaction_req = xrd_pb2.PushTransactionReq(transaction_signed=tx.pbdata)
        push_transaction_resp = stub.PushTransaction(push_transaction_req, timeout=CONNECTION_TIMEOUT)

        print(push_transaction_resp.error_code)
    except Exception as e:
        print("Error {}".format(str(e)))