def tx_transfertoken(ctx, src, master, token_txhash, dst, amounts, decimals, fee, ots_key_index): """ Create Token Transaction, that results into the formation of new token if accepted. """ if not ctx.obj.remote: click.echo('This command is unsupported for local wallets') return 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 src_xmss.set_ots_index(int(ots_key_index)) addresses_dst = [] for addr in dst.split(' '): addresses_dst.append(_parse_qaddress(addr)) shor_amounts = [] for amount in amounts.split(' '): shor_amounts.append(int(float(amount) * (10**int(decimals)))) if len(addresses_dst) != len(shor_amounts): raise Exception( "{} destination addresses specified but only {} amounts given". format(len(addresses_dst), len(shor_amounts))) bin_token_txhash = _parse_hexblob(token_txhash) master_addr = _parse_qaddress(master) # FIXME: This could be problematic. Check fee_shor = _shorize(fee) 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 = TransferTokenTransaction.create(token_txhash=bin_token_txhash, addrs_to=addresses_dst, amounts=shor_amounts, fee=fee_shor, xmss_pk=address_src_pk, master_addr=master_addr) tx.sign(src_xmss) pushTransactionReq = qrl_pb2.PushTransactionReq( transaction_signed=tx.pbdata) pushTransactionResp = stub.PushTransaction(pushTransactionReq, timeout=5) print(pushTransactionResp.error_code) except Exception as e: print("Error {}".format(str(e)))
def test_remove_transfer_token_metadata(self): with set_qrl_dir('no_data'): with State() as state: alice_xmss = get_alice_xmss() bob_xmss = get_bob_xmss() token_transaction = get_token_transaction(alice_xmss, bob_xmss) state.create_token_metadata(token_transaction) transfer_token = TransferTokenTransaction.create( token_txhash=token_transaction.txhash, addrs_to=[alice_xmss.address], amounts=[100000000], fee=1, xmss_pk=bob_xmss.pk) transfer_token.sign(alice_xmss) state.update_token_metadata(transfer_token) token_metadata = state.get_token_metadata( transfer_token.token_txhash) self.assertIn(transfer_token.txhash, token_metadata.transfer_token_tx_hashes) state.remove_transfer_token_metadata(transfer_token) token_metadata = state.get_token_metadata( transfer_token.token_txhash) self.assertNotIn(transfer_token.txhash, token_metadata.transfer_token_tx_hashes)
def test_create(self): tx = TransferTokenTransaction.create(token_txhash=b'000000000000000', addrs_to=[self.bob.address], amounts=[200000], fee=1, xmss_pk=self.alice.pk) self.assertTrue(tx)
def test_update_token_metadata(self): with set_data_dir('no_data'): with State() as state: alice_xmss = get_alice_xmss() bob_xmss = get_bob_xmss() token_transaction = get_token_transaction(alice_xmss, bob_xmss) state.create_token_metadata(token_transaction) transfer_token_transaction = TransferTokenTransaction.create( addr_from=bob_xmss.address, token_txhash=token_transaction.txhash, addrs_to=[alice_xmss.address], amounts=[100000000], fee=1, xmss_pk=bob_xmss.pk) state.update_token_metadata(transfer_token_transaction) token_metadata = state.get_token_metadata( token_transaction.txhash) self.assertEqual(len(token_metadata.transfer_token_tx_hashes), 2) self.assertEqual(token_metadata.transfer_token_tx_hashes[0], token_transaction.txhash) self.assertEqual(token_metadata.transfer_token_tx_hashes[1], transfer_token_transaction.txhash)
def test_to_json(self): tx = TransferTokenTransaction.create(token_txhash=b'000000000000000', addrs_to=[self.bob.address], amounts=[200000], fee=1, xmss_pk=self.alice.pk) txjson = tx.to_json() self.assertEqual(json.loads(test_json_TransferToken), json.loads(txjson))
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_validate_tx(self): tx = TransferTokenTransaction.create(token_txhash=b'000000000000000', addrs_to=[self.bob.address], amounts=[200000], fee=1, xmss_pk=self.alice.pk) # 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 tx_transfertoken(ctx, src, master, token_txhash, dst, amounts, decimals, fee, ots_key_index): """ Create Token Transaction, that results into the formation of new token if accepted. """ if not ctx.obj.remote: click.echo('This command is unsupported for local wallets') return 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 src_xmss.set_ots_index(int(ots_key_index)) addresses_dst = [] for addr in dst.split(' '): addresses_dst.append(bytes(hstr2bin(addr[1:]))) shor_amounts = [] for amount in amounts.split(' '): shor_amounts.append(int(float(amount) * (10**int(decimals)))) bin_token_txhash = bytes(hstr2bin(token_txhash)) # FIXME: This could be problematic. Check fee_shor = int(fee * 1.e9) except KeyboardInterrupt as e: click.echo("Error validating arguments") quit(1) try: channel = grpc.insecure_channel(ctx.obj.node_public_address) stub = qrl_pb2_grpc.PublicAPIStub(channel) tx = TransferTokenTransaction.create(token_txhash=bin_token_txhash, addrs_to=addresses_dst, amounts=amounts, fee=fee_shor, xmss_pk=address_src_pk, master_addr=master.encode()) tx.sign(src_xmss) pushTransactionReq = qrl_pb2.PushTransactionReq( transaction_signed=tx.pbdata) pushTransactionResp = stub.PushTransaction(pushTransactionReq, timeout=5) print(pushTransactionResp.error_code) except Exception as e: print("Error {}".format(str(e)))
def create_transfer_token_txn(addrs_to: list, token_txhash: bytes, amounts: list, fee: int, xmss_pk: bytes, master_addr: bytes): return TransferTokenTransaction.create(token_txhash, addrs_to, amounts, fee, xmss_pk, master_addr)
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 create_transfer_token_txn(addr_from: bytes, addr_to: bytes, token_txhash: bytes, amount: int, fee: int, xmss_pk: bytes, xmss_ots_index: int): return TransferTokenTransaction.create(addr_from, token_txhash, addr_to, amount, fee, xmss_pk, xmss_ots_index)
def create_transfer_token_txn(addr_from: bytes, addr_to: bytes, token_txhash: bytes, amount: int, fee: int, xmss_pk: bytes, xmss_ots_index: int): return TransferTokenTransaction.create(addr_from, token_txhash, addr_to, amount, fee, xmss_pk, xmss_ots_index)
def tx_transfertoken(ctx, src, token_txhash, dst, amount, decimals, fee, ots_key_index): """ Create Token Transaction, that results into the formation of new token if accepted. """ if not ctx.obj.remote: click.echo('This command is unsupported for local wallets') return try: address_src, 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() src_xmss.set_index(int(ots_key_index)) address_src_otsidx = src_xmss.get_index() address_dst = dst.encode() bin_token_txhash = bytes(hstr2bin(token_txhash)) # FIXME: This could be problematic. Check amount = int(amount * (10**int(decimals))) fee_shor = int(fee * 1.e8) except KeyboardInterrupt as e: click.echo("Error validating arguments") quit(1) try: channel = grpc.insecure_channel(ctx.obj.node_public_address) stub = qrl_pb2_grpc.PublicAPIStub(channel) tx = TransferTokenTransaction.create(addr_from=address_src, token_txhash=bin_token_txhash, addr_to=address_dst, amount=amount, fee=fee_shor, xmss_pk=address_src_pk, xmss_ots_index=address_src_otsidx) tx.sign(src_xmss) pushTransactionReq = qrl_pb2.PushTransactionReq( transaction_signed=tx.pbdata) pushTransactionResp = stub.PushTransaction(pushTransactionReq, timeout=5) print(pushTransactionResp.some_response) except Exception as e: print("Error {}".format(str(e)))
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 tx_transfertoken(ctx, src, token_txhash, dst, amount, decimals, fee, ots_key_index): """ Create Token Transaction, that results into the formation of new token if accepted. """ if not ctx.obj.remote: click.echo('This command is unsupported for local wallets') return try: address_src, 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() src_xmss.set_index(int(ots_key_index)) address_src_otsidx = src_xmss.get_index() address_dst = dst.encode() bin_token_txhash = bytes(hstr2bin(token_txhash)) # FIXME: This could be problematic. Check amount = int(amount * (10**int(decimals))) fee_shor = int(fee * 1.e9) except KeyboardInterrupt as e: click.echo("Error validating arguments") quit(1) try: channel = grpc.insecure_channel(ctx.obj.node_public_address) stub = qrl_pb2_grpc.PublicAPIStub(channel) tx = TransferTokenTransaction.create(addr_from=address_src, token_txhash=bin_token_txhash, addr_to=address_dst, amount=amount, fee=fee_shor, xmss_pk=address_src_pk, xmss_ots_index=address_src_otsidx) tx.sign(src_xmss) pushTransactionReq = qrl_pb2.PushTransactionReq(transaction_signed=tx.pbdata) pushTransactionResp = stub.PushTransaction(pushTransactionReq, timeout=5) print(pushTransactionResp.some_response) except Exception as e: print("Error {}".format(str(e)))
def create_unsigned_tx(self, transaction): if transaction.type == qrl_pb2.Transaction.TRANSFER: return TransferTransaction.create(transaction.addr_from, transaction.Transfer.addr_to, transaction.Transfer.amount, transaction.Transfer.fee, transaction.xmss_pk, transaction.xmss_ots_index) elif transaction.type == qrl_pb2.Transaction.LATTICE: return LatticePublicKey.create(transaction.addr_from, transaction.LatticePublicKey.kyber_pk, transaction.LatticePublicKey.tesla_pk, transaction.xmss_pk, transaction.xmss_ots_index) elif transaction.type == qrl_pb2.Transaction.MESSAGE: return MessageTransaction.create(transaction.addr_from, transaction.Message.message_hash, transaction.Message.fee, transaction.xmss_pk, transaction.xmss_ots_index) elif transaction.type == qrl_pb2.Transaction.TOKEN: return TokenTransaction.create(transaction.addr_from, transaction.Token.symbol, transaction.Token.name, transaction.Token.owner, transaction.Token.decimals, transaction.Token.initial_balances, transaction.Token.fee, transaction.xmss_pk, transaction.xmss_ots_index) elif transaction.type == qrl_pb2.Transaction.TRANSFERTOKEN: return TransferTokenTransaction.create(transaction.addr_from, transaction.TransferToken.token_txhash, transaction.TransferToken.addr_to, transaction.TransferToken.amount, transaction.TransferToken.fee, transaction.xmss_pk, transaction.xmss_ots_index) else: return None
def test_update_token_metadata(self): with set_data_dir('no_data'): with State() as state: alice_xmss = get_alice_xmss() bob_xmss = get_bob_xmss() token_transaction = get_token_transaction(alice_xmss, bob_xmss) state.create_token_metadata(token_transaction) transfer_token_transaction = TransferTokenTransaction.create(addr_from=bob_xmss.get_address(), token_txhash=token_transaction.txhash, addr_to=alice_xmss.get_address(), amount=100000000, fee=1, xmss_pk=bob_xmss.pk(), xmss_ots_index=bob_xmss.get_index()) state.update_token_metadata(transfer_token_transaction) token_metadata = state.get_token_metadata(token_transaction.txhash) self.assertEqual(len(token_metadata.transfer_token_tx_hashes), 2) self.assertEqual(token_metadata.transfer_token_tx_hashes[0], token_transaction.txhash) self.assertEqual(token_metadata.transfer_token_tx_hashes[1], transfer_token_transaction.txhash)
def test_add_4(self): destroy_state() with State() as state: with set_wallet_dir("test_wallet"): chain = Chain(state) buffered_chain = BufferedChain(chain) alice_xmss = get_alice_xmss() slave_xmss = XMSS(alice_xmss.height, alice_xmss.get_seed()) random_xmss1 = get_random_xmss() random_xmss2 = get_random_xmss() staking_address = bytes(alice_xmss.get_address().encode()) # FIXME: Replace this with a call to create a hash_chain h0 = sha256(b'hashchain_seed') h1 = sha256(h0) h2 = sha256(h1) h3 = sha256(h2) h4 = sha256(h3) with mocked_genesis() as custom_genesis: custom_genesis.genesis_balance.extend([ qrl_pb2.GenesisBalance( address=alice_xmss.get_address(), balance=700000000000000) ]) res = buffered_chain.add_block(block=GenesisBlock()) self.assertTrue(res) stake_transaction = StakeTransaction.create( activation_blocknumber=1, xmss=alice_xmss, slavePK=slave_xmss.pk(), hashchain_terminator=h4) stake_transaction._data.nonce = 1 # FIXME: The test needs private access.. This is an API issue stake_transaction.sign(alice_xmss) vote = Vote.create( addr_from=alice_xmss.get_address().encode(), blocknumber=0, headerhash=GenesisBlock().headerhash, xmss=slave_xmss) vote.sign(slave_xmss) buffered_chain.add_vote(vote) vote_metadata = buffered_chain.get_consensus(0) chain.pstate.stake_validators_tracker.add_sv( balance=700000000000000, stake_txn=stake_transaction, blocknumber=1) sv = chain.pstate.stake_validators_tracker.sv_dict[ staking_address] self.assertEqual(0, sv.nonce) # Token Transaction to create a token for test token_transaction = get_token_transaction( random_xmss1, random_xmss2) token_transaction._data.nonce = 1 token_transaction.sign(random_xmss1) # Transfer Token Transaction transfer_token1 = TransferTokenTransaction.create( addr_from=random_xmss1.get_address().encode(), token_txhash=token_transaction.txhash, addr_to=alice_xmss.get_address().encode(), amount=100000000, fee=1, xmss_pk=random_xmss1.pk(), xmss_ots_index=random_xmss1.get_index()) transfer_token1._data.nonce = 2 transfer_token1.sign(random_xmss1) transfer_token2 = TransferTokenTransaction.create( addr_from=random_xmss2.get_address().encode(), token_txhash=token_transaction.txhash, addr_to=alice_xmss.get_address().encode(), amount=200000000, fee=1, xmss_pk=random_xmss2.pk(), xmss_ots_index=random_xmss2.get_index()) transfer_token2._data.nonce = 1 transfer_token2.sign(random_xmss2) # Transfer Coin Transaction transfer_transaction = TransferTransaction.create( addr_from=random_xmss1.get_address().encode(), addr_to=random_xmss2.get_address().encode(), amount=10, fee=1, xmss_pk=random_xmss1.pk(), xmss_ots_index=random_xmss1.get_index()) transfer_transaction._data.nonce = 3 transfer_transaction.sign(random_xmss1) tmp_block1 = Block.create( staking_address=staking_address, block_number=1, reveal_hash=h3, prevblock_headerhash=GenesisBlock().headerhash, transactions=[stake_transaction, token_transaction], duplicate_transactions=OrderedDict(), vote=vote_metadata, signing_xmss=slave_xmss, nonce=1) res = buffered_chain.add_block(block=tmp_block1) self.assertTrue(res) # Need to move forward the time to align with block times with mock.patch('qrl.core.ntp.getTime') as time_mock: time_mock.return_value = tmp_block1.timestamp + config.dev.minimum_minting_delay vote = Vote.create( addr_from=alice_xmss.get_address().encode(), blocknumber=1, headerhash=tmp_block1.headerhash, xmss=slave_xmss) vote.sign(slave_xmss) buffered_chain.add_vote(vote) vote_metadata = buffered_chain.get_consensus(1) tmp_block2 = Block.create( staking_address=staking_address, block_number=2, reveal_hash=h2, prevblock_headerhash=tmp_block1.headerhash, transactions=[ transfer_token1, transfer_token2, transfer_transaction ], duplicate_transactions=OrderedDict(), vote=vote_metadata, signing_xmss=slave_xmss, nonce=2) res = buffered_chain.add_block(block=tmp_block2) self.assertTrue(res) # Need to move forward the time to align with block times with mock.patch('qrl.core.ntp.getTime') as time_mock: time_mock.return_value = tmp_block2.timestamp + config.dev.minimum_minting_delay vote = Vote.create( addr_from=alice_xmss.get_address().encode(), blocknumber=2, headerhash=tmp_block2.headerhash, xmss=slave_xmss) vote.sign(slave_xmss) buffered_chain.add_vote(vote) vote_metadata = buffered_chain.get_consensus(2) tmp_block3 = Block.create( staking_address=staking_address, block_number=3, reveal_hash=h1, prevblock_headerhash=tmp_block2.headerhash, transactions=[], duplicate_transactions=OrderedDict(), vote=vote_metadata, signing_xmss=slave_xmss, nonce=3) res = buffered_chain.add_block(block=tmp_block3) self.assertTrue(res) chain = buffered_chain._chain random_xmss1_state = chain.pstate._get_address_state( random_xmss1.get_address().encode()) random_xmss2_state = chain.pstate._get_address_state( random_xmss2.get_address().encode()) self.assertEqual( random_xmss1_state.tokens[bin2hstr( token_transaction.txhash).encode()], 400000000) self.assertEqual( random_xmss2_state.tokens[bin2hstr( token_transaction.txhash).encode()], 200000000) # Need to move forward the time to align with block times with mock.patch('qrl.core.ntp.getTime') as time_mock: time_mock.return_value = tmp_block3.timestamp + config.dev.minimum_minting_delay vote = Vote.create( addr_from=alice_xmss.get_address().encode(), blocknumber=3, headerhash=tmp_block3.headerhash, xmss=slave_xmss) vote.sign(slave_xmss) buffered_chain.add_vote(vote) vote_metadata = buffered_chain.get_consensus(3) tmp_block4 = Block.create( staking_address=staking_address, block_number=4, reveal_hash=h0, prevblock_headerhash=tmp_block3.headerhash, transactions=[], duplicate_transactions=OrderedDict(), vote=vote_metadata, signing_xmss=slave_xmss, nonce=4) res = buffered_chain.add_block(block=tmp_block4) self.assertTrue(res) token_metadata = buffered_chain.get_token_metadata( token_transaction.txhash) self.assertEqual(token_metadata.token_txhash, token_transaction.txhash) self.assertEqual( len(token_metadata.transfer_token_tx_hashes), 3) self.assertEqual( token_metadata.transfer_token_tx_hashes[0], token_transaction.txhash) random_xmss1_state = chain.pstate._get_address_state( random_xmss1.get_address().encode()) random_xmss2_state = chain.pstate._get_address_state( random_xmss2.get_address().encode()) alice_state = chain.pstate._get_address_state( alice_xmss.get_address().encode()) self.assertEqual( random_xmss1_state.tokens[bin2hstr( token_transaction.txhash).encode()], 300000000) self.assertEqual( random_xmss2_state.tokens[bin2hstr( token_transaction.txhash).encode()], 0) self.assertEqual( alice_state.tokens[bin2hstr( token_transaction.txhash).encode()], 300000000) self.assertEqual(random_xmss1_state.balance, config.dev.default_account_balance - 13) self.assertEqual(random_xmss2_state.balance, config.dev.default_account_balance + 9)