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( qrl_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_addr: 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 = qrl_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)))
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)
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 = [qrl_pb2.AddressAmount(address=self.alice.address, amount=1000), qrl_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))