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 tx_push(ctx, txblob): """ Sends a signed transaction blob to a node """ tx = None try: txbin = parse_hexblob(txblob) pbdata = qrl_pb2.Transaction() pbdata.ParseFromString(txbin) tx = Transaction.from_pbdata(pbdata) except Exception as e: click.echo("tx blob is not valid") quit(1) tmp_json = tx.to_json() # FIXME: binary fields are represented in base64. Improve output print(tmp_json) if len(tx.signature) == 0: click.echo('Signature missing') quit(1) stub = ctx.obj.get_stub_public_api() pushTransactionReq = qrl_pb2.PushTransactionReq( transaction_signed=tx.pbdata) pushTransactionResp = stub.PushTransaction(pushTransactionReq, timeout=CONNECTION_TIMEOUT) print(pushTransactionResp.error_code)
def transfer(destinations, fee, mixin, unlock_time): if len(destinations) > config.dev.transaction_multi_output_limit: raise Exception('Payment Failed: Amount exceeds the allowed limit') addrs_to = [] amounts = [] for tx in destinations: addrs_to.append(bytes(hstr2bin(tx['address'][1:]))) # Skipping 'Q' amounts.append(tx['amount']) stub = get_public_stub() xmss = get_unused_payment_xmss(stub) if not xmss: raise Exception('Payment Failed: No Unused Payment XMSS found') tx = TransferTransaction.create(addrs_to=addrs_to, amounts=amounts, fee=fee, xmss_pk=xmss.pk, master_addr=payment_slaves[0]) tx.sign(xmss) response = stub.PushTransaction(request=qrl_pb2.PushTransactionReq( transaction_signed=tx.pbdata)) if response.error_code != 3: raise Exception('Transaction Submission Failed, Response Code: %s', response.error_code) response = {'tx_hash': bin2hstr(tx.txhash)} return response
def transfer(destinations, fee, mixin, unlock_time): if len(destinations) > config.dev.transaction_multi_output_limit: return None addrs_to = [] amounts = [] for tx in destinations: addrs_to.append(bytes(hstr2bin(tx['address'][1:]))) # Skipping 'Q' amounts.append(tx['amount']) stub = get_public_stub() xmss = get_unused_payment_xmss(stub) if not xmss: return None tx = TransferTransaction.create(addrs_to=addrs_to, amounts=amounts, fee=fee, xmss_pk=xmss.pk, master_addr=payment_slaves[0]) tx.sign(xmss) response = stub.PushTransaction(request=qrl_pb2.PushTransactionReq( transaction_signed=tx.pbdata)) if response.error_code != 3: return None response = {'tx_hash': bin2hstr(tx.txhash)} return response
def tx_multi_sig_create(ctx, src, master, threshold, fee, ots_key_index): """ Creates Multi Sig Create Transaction, that results into the formation of new multi_sig_address if accepted. """ signatories = [] weights = [] while True: address = click.prompt('Address of Signatory ', default='') if address == '': break weight = int(click.prompt('Weight ')) signatories.append(parse_qaddress(address)) weights.append(weight) 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) master_addr = None if master: master_addr = parse_qaddress(master) # FIXME: This could be problematic. Check fee_shor = _quanta_to_shor(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 = MultiSigCreate.create(signatories=signatories, weights=weights, threshold=threshold, 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) print('Multi sig Address Q{}'.format( bin2hstr(MultiSigAddressState.generate_multi_sig_address( tx.txhash)))) except Exception as e: print("Error {}".format(str(e)))
def sign_and_push_transaction(self, tx, xmss, index, group_index=None, slave_index=None, enable_save=True): logger.info("Signing %s transaction by %s | OTS index %s", tx.type, xmss.qaddress, xmss.ots_index) tx.sign(xmss) if not tx.validate(True): raise Exception("Invalid Transaction") if enable_save: if slave_index == None: # noqa self._wallet.set_ots_index( index, xmss.ots_index ) # Move to next OTS index before broadcasting txn else: self._wallet.set_slave_ots_index(index, group_index, slave_index, xmss.ots_index) push_transaction_req = qrl_pb2.PushTransactionReq( transaction_signed=tx.pbdata) push_transaction_resp = self._public_stub.PushTransaction( push_transaction_req, timeout=CONNECTION_TIMEOUT) if push_transaction_resp.error_code != qrl_pb2.PushTransactionResp.SUBMITTED: raise Exception(push_transaction_resp.error_description)
def tx_token(ctx, src, symbol, name, owner, 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 initial_balances = [] 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=address.encode(), amount=amount)) 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_owner = owner.encode() # FIXME: This could be problematic. Check 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 = TokenTransaction.create(addr_from=address_src, symbol=symbol.encode(), name=name.encode(), owner=address_owner, decimals=decimals, initial_balances=initial_balances, 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 tx_transfertoken(ctx, src, master, token_txhash, dsts, amounts, decimals, fee, ots_key_index): """ Create Transfer Token Transaction, which moves tokens from src to dst. """ if decimals > 19: click.echo( "The number of decimal cannot exceed 19 under any configuration") quit(1) try: addresses_dst, shor_amounts = _parse_dsts_amounts( dsts, amounts, token_decimals=decimals) bin_token_txhash = parse_hexblob(token_txhash) master_addr = None if master: master_addr = parse_qaddress(master) # FIXME: This could be problematic. Check fee_shor = _quanta_to_shor(fee) _, 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) 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) 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 _push_transaction(self, tx, xmss): tx.sign(xmss) if not tx.validate(True): return None push_transaction_req = qrl_pb2.PushTransactionReq( transaction_signed=tx.pbdata) push_transaction_resp = self._public_stub.PushTransaction( push_transaction_req, timeout=CONNECTION_TIMEOUT) if push_transaction_resp.error_code != qrl_pb2.PushTransactionResp.SUBMITTED: raise Exception(push_transaction_resp.error_description)
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 tx_transfer(ctx, src, master, dst, amounts, fee, ots_key_index): """ Transfer coins from src to dst """ 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(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) * 1.e9)) fee_shor = int(fee * 1.e9) except Exception: click.echo("Error validating arguments") quit(1) try: channel = grpc.insecure_channel(ctx.obj.node_public_address) stub = qrl_pb2_grpc.PublicAPIStub(channel) transferCoinsReq = qrl_pb2.TransferCoinsReq( addresses_to=addresses_dst, amounts=shor_amounts, fee=fee_shor, xmss_pk=address_src_pk, master_addr=master.encode()) transferCoinsResp = stub.TransferCoins(transferCoinsReq, timeout=5) tx = Transaction.from_pbdata( transferCoinsResp.extended_transaction_unsigned.tx) tx.sign(src_xmss) pushTransactionReq = qrl_pb2.PushTransactionReq( transaction_signed=tx.pbdata) pushTransactionResp = stub.PushTransaction(pushTransactionReq, timeout=5) print(pushTransactionResp) except Exception as e: print("Error {}".format(str(e)))
def valid_payment_permission(public_stub, master_address_state, payment_xmss, json_slave_txn): access_type = master_address_state.get_slave_permission(payment_xmss.pk) if access_type == -1: tx = Transaction.from_json(json_slave_txn) public_stub.PushTransaction(request=qrl_pb2.PushTransactionReq(transaction_signed=tx.pbdata)) return None if access_type == 0: return True return False
def test_transferCoins_push_unsigned(self): with set_qrl_dir('wallet_ver1'): with State() as db_state: p2p_factory = Mock(spec=P2PFactory) p2p_factory.pow = Mock(spec=POW) chain_manager = ChainManager(db_state) qrlnode = QRLNode(db_state, mining_address=b'') qrlnode.set_chain_manager(chain_manager) qrlnode._p2pfactory = p2p_factory qrlnode._pow = p2p_factory.pow qrlnode._peer_addresses = ['127.0.0.1', '192.168.1.1'] service = PublicAPIService(qrlnode) context = Mock(spec=ServicerContext) alice = get_alice_xmss() bob = get_bob_xmss() request = qrl_pb2.TransferCoinsReq( addresses_to=[bob.address], amounts=[101], fee=12, xmss_pk=alice.pk ) response = service.TransferCoins(request=request, context=context) context.set_code.assert_not_called() context.set_details.assert_not_called() self.assertIsNotNone(response) self.assertIsNotNone(response.extended_transaction_unsigned) self.assertEqual('transfer', response.extended_transaction_unsigned.tx.WhichOneof('transactionType')) self.assertEqual(12, response.extended_transaction_unsigned.tx.fee) self.assertEqual(alice.pk, response.extended_transaction_unsigned.tx.public_key) self.assertEqual(0, response.extended_transaction_unsigned.tx.nonce) self.assertEqual(b'', response.extended_transaction_unsigned.tx.signature) self.assertEqual(b'', response.extended_transaction_unsigned.tx.transaction_hash) self.assertEqual(bob.address, response.extended_transaction_unsigned.tx.transfer.addrs_to[0]) self.assertEqual(101, response.extended_transaction_unsigned.tx.transfer.amounts[0]) req_push = qrl_pb2.PushTransactionReq(transaction_signed=response.extended_transaction_unsigned.tx) resp_push = service.PushTransaction(req_push, context=context) context.set_code.assert_not_called() context.set_details.assert_not_called() self.assertIsNotNone(resp_push) self.assertEqual(qrl_pb2.PushTransactionResp.VALIDATION_FAILED, resp_push.error_code)
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 tx_transfer(ctx, src, dst, amount, fee): """ Transfer coins from src to dst """ 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() address_src_otsidx = src_xmss.get_index() address_dst = dst.encode() # FIXME: This could be problematic. Check amount_shor = int(amount * 1.e8) fee_shor = int(fee * 1.e8) except Exception 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) transferCoinsReq = qrl_pb2.TransferCoinsReq( address_from=address_src, address_to=address_dst, amount=amount_shor, fee=fee_shor, xmss_pk=address_src_pk, xmss_ots_index=address_src_otsidx) transferCoinsResp = stub.TransferCoins(transferCoinsReq, timeout=5) tx = Transaction.from_pbdata(transferCoinsResp.transaction_unsigned) tx.sign(src_xmss.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 tx_transfer(ctx, src, master, dst, amounts, fee, ots_key_index): """ Transfer coins from src to dst """ 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(ots_key_index) addresses_dst, shor_amounts = _parse_dsts_amounts(dst, amounts) master_addr = _parse_qaddress(master) fee_shor = _shorize(fee) except Exception as e: click.echo("Error validating arguments: {}".format(e)) quit(1) try: stub = ctx.obj.get_stub_public_api() transferCoinsReq = qrl_pb2.TransferCoinsReq(addresses_to=addresses_dst, amounts=shor_amounts, fee=fee_shor, xmss_pk=address_src_pk, master_addr=master_addr) transferCoinsResp = stub.TransferCoins(transferCoinsReq, timeout=5) tx = Transaction.from_pbdata( transferCoinsResp.extended_transaction_unsigned.tx) tx.sign(src_xmss) pushTransactionReq = qrl_pb2.PushTransactionReq( transaction_signed=tx.pbdata) pushTransactionResp = stub.PushTransaction(pushTransactionReq, timeout=5) print(pushTransactionResp) except Exception as e: print("Error {}".format(str(e)))
def tx_message(ctx, src, master, addr_to, message, fee, ots_key_index): """ Message Transaction """ 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) message = message.encode() if addr_to: addr_to = parse_qaddress(addr_to, False) else: addr_to = None master_addr = None if master: master_addr = parse_qaddress(master) fee_shor = _quanta_to_shor(fee) except Exception as e: click.echo("Error validating arguments: {}".format(e)) quit(1) try: stub = ctx.obj.get_stub_public_api() tx = MessageTransaction.create(message_hash=message, addr_to=addr_to, 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) except Exception as e: print("Error {}".format(str(e)))
def send(): """ Transfer coins """ channel = get_channel() stub = qrl_pb2_grpc.PublicAPIStub(channel) walletObj = get_wallet_obj() print_wallet_list(walletObj) selected_wallet = select_wallet(walletObj) if not selected_wallet: return address_to = click.prompt('Enter Address To', type=str) amount = click.prompt('Enter Amount', type=float) fee = click.prompt('Fee', type=float) address_to = address_to.encode() int_amount = int(amount * 10**8) int_fee = int(fee * 10**8) try: transferCoinsReq = qrl_pb2.TransferCoinsReq( address_from=selected_wallet.address, address_to=address_to, amount=int_amount, fee=int_fee, xmss_pk=selected_wallet.xmss.pk(), xmss_ots_index=selected_wallet.xmss.get_index()) f = stub.TransferCoins.future(transferCoinsReq, timeout=5) transferCoinsResp = f.result(timeout=5) tx = Transaction.from_pbdata(transferCoinsResp.transaction_unsigned) tx.sign(selected_wallet.xmss) pushTransactionReq = qrl_pb2.PushTransactionReq( transaction_signed=tx.pbdata) f = stub.PushTransaction.future(pushTransactionReq, timeout=5) pushTransactionResp = f.result(timeout=5) print('%s' % (pushTransactionResp.some_response, )) except Exception as e: print("Error {}".format(str(e)))
def tx_latticepk(ctx, src, kyber_pk, dilithium_pk, fee, ots_key_index): """ Create Lattice Public Keys Transaction """ if not ctx.obj.remote: click.echo('This command is unsupported for local wallets') return stub = qrl_pb2_grpc.PublicAPIStub(ctx.obj.channel_public) 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_ots_index(ots_key_index) kyber_pk = kyber_pk.encode() dilithium_pk = dilithium_pk.encode() # FIXME: This could be problematic. Check fee_shor = int(fee * 1.e9) except Exception: click.echo("Error validating arguments") quit(1) try: tx = LatticePublicKey.create(addr_from=address_src, fee=fee_shor, kyber_pk=kyber_pk, dilithium_pk=dilithium_pk, xmss_pk=address_src_pk) 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 tx_latticepk(ctx, src, master, kyber_pk, dilithium_pk, fee, ots_key_index): """ Create Lattice Public Keys Transaction """ 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(ots_key_index) kyber_pk = kyber_pk.encode() dilithium_pk = dilithium_pk.encode() master_addr = _parse_qaddress(master) # FIXME: This could be problematic. Check fee_shor = _shorize(fee) except Exception as e: click.echo("Error validating arguments: {}".format(e)) quit(1) try: tx = LatticePublicKey.create(fee=fee_shor, kyber_pk=kyber_pk, dilithium_pk=dilithium_pk, xmss_pk=address_src_pk, master_addr=master_addr) tx.sign(src_xmss) stub = ctx.obj.get_stub_public_api() 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 tx_push(ctx, txblob): tx = None try: txbin = bytes(hstr2bin(txblob)) pbdata = qrl_pb2.Transaction() pbdata.ParseFromString(txbin) tx = Transaction.from_pbdata(pbdata) except Exception as e: click.echo("tx blob is not valid") quit(1) tmp_json = tx.to_json() # FIXME: binary fields are represented in base64. Improve output print(tmp_json) if len(tx.signature) == 0: click.echo('Signature missing') quit(1) channel = grpc.insecure_channel(ctx.obj.node_public_address) stub = qrl_pb2_grpc.PublicAPIStub(channel) pushTransactionReq = qrl_pb2.PushTransactionReq(transaction_signed=tx.pbdata) pushTransactionResp = stub.PushTransaction(pushTransactionReq, timeout=5) print(pushTransactionResp.error_code)
def lattice(): channel = get_channel() stub = qrl_pb2_grpc.PublicAPIStub(channel) walletObj = get_wallet_obj() print_wallet_list(walletObj) selected_wallet = select_wallet(walletObj) if not selected_wallet: return lattice_public_key = click.prompt('Enter Lattice Public Key', type=str) lattice_public_key = lattice_public_key.encode() try: latticePublicKeyTxnReq = qrl_pb2.LatticePublicKeyTxnReq( address_from=selected_wallet.address, kyber_pk=lattice_public_key, tesla_pk=lattice_public_key, xmss_pk=selected_wallet.xmss.pk(), xmss_ots_index=selected_wallet.xmss.get_index()) f = stub.GetLatticePublicKeyTxn.future(latticePublicKeyTxnReq, timeout=5) latticePublicKeyResp = f.result(timeout=5) tx = Transaction.from_pbdata(latticePublicKeyResp.transaction_unsigned) tx.sign(selected_wallet.xmss) pushTransactionReq = qrl_pb2.PushTransactionReq( transaction_signed=tx.pbdata) f = stub.PushTransaction.future(pushTransactionReq, timeout=5) pushTransactionResp = f.result(timeout=5) print('%s' % (pushTransactionResp.some_response, )) except Exception as e: print("Error {}".format(str(e)))
def test_transferCoins_sign(self): with set_qrl_dir('wallet_ver1'): with State() as db_state: p2p_factory = Mock(spec=P2PFactory) p2p_factory.pow = Mock(spec=POW) chain_manager = ChainManager(db_state) qrlnode = QRLNode(db_state, mining_address=b'') qrlnode.set_chain_manager(chain_manager) qrlnode._p2pfactory = p2p_factory qrlnode._pow = p2p_factory.pow qrlnode._peer_addresses = ['127.0.0.1', '192.168.1.1'] service = PublicAPIService(qrlnode) context = Mock(spec=ServicerContext) alice = get_alice_xmss() bob = get_bob_xmss() request = qrl_pb2.TransferCoinsReq( addresses_to=[bob.address], amounts=[101], fee=12, xmss_pk=alice.pk ) response = service.TransferCoins(request=request, context=context) context.set_code.assert_not_called() context.set_details.assert_not_called() self.assertIsNotNone(response) self.assertIsNotNone(response.extended_transaction_unsigned.tx) self.assertEqual('transfer', response.extended_transaction_unsigned.tx.WhichOneof('transactionType')) self.assertEqual(12, response.extended_transaction_unsigned.tx.fee) self.assertEqual(alice.pk, response.extended_transaction_unsigned.tx.public_key) self.assertEqual(0, response.extended_transaction_unsigned.tx.nonce) self.assertEqual(b'', response.extended_transaction_unsigned.tx.signature) self.assertEqual(b'', response.extended_transaction_unsigned.tx.transaction_hash) self.assertEqual(bob.address, response.extended_transaction_unsigned.tx.transfer.addrs_to[0]) self.assertEqual(101, response.extended_transaction_unsigned.tx.transfer.amounts[0]) tmp_hash_pre = bytes(QRLHelper.getAddress(response.extended_transaction_unsigned.tx.public_key)) tmp_hash_pre += str(response.extended_transaction_unsigned.tx.fee).encode() tmp_hash_pre += response.extended_transaction_unsigned.tx.transfer.addrs_to[0] tmp_hash_pre += str(response.extended_transaction_unsigned.tx.transfer.amounts[0]).encode() self.assertEqual('010300a1da274e68c88b0ccf448e0b1916fa789b01eb2ed4e9ad565ce264c939078' '2a9c61ac02f31320103001d65d7e59aed5efbeae64246e0f3184d7c42411421eb38' '5ba30f2c1c005a85ebc4419cfd313031', bin2hstr(tmp_hash_pre)) tmp_hash = sha256(tmp_hash_pre) self.assertEqual('3645f2819aba65479f9a7fad3f5d7a41a9357410a595fa02fb947bfe3ed96e0f', bin2hstr(tmp_hash)) signed_transaction = response.extended_transaction_unsigned.tx signed_transaction.signature = alice.sign(tmp_hash) req_push = qrl_pb2.PushTransactionReq(transaction_signed=signed_transaction) resp_push = service.PushTransaction(req_push, context=context) context.set_code.assert_not_called() context.set_details.assert_not_called() self.assertIsNotNone(resp_push) self.assertEqual(qrl_pb2.PushTransactionResp.SUBMITTED, resp_push.error_code) self.assertEqual('30955fdc5e2d9dbe5fb9bf812f2e1b6c4b409a8a7c7a75f1c3e9ba1ffdd8e60e', bin2hstr(resp_push.tx_hash))
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: 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 tx_transfer(ctx, src, master, dsts, amounts, message_data, fee, ots_key_index): """ Transfer coins from src to dsts """ address_src_pk = None master_addr = None addresses_dst = [] shor_amounts = [] fee_shor = [] signing_object = None message_data = message_data.encode() try: # Retrieve signing object selected_wallet = _select_wallet(ctx, src) if selected_wallet is None or len(selected_wallet) != 2: click.echo("A wallet was not found") quit(1) _, src_xmss = selected_wallet 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) signing_object = src_xmss # Get and validate other inputs if master: master_addr = parse_qaddress(master) addresses_dst, shor_amounts = _parse_dsts_amounts( dsts, amounts, check_multi_sig_address=True) fee_shor = _quanta_to_shor(fee) except Exception as e: click.echo("Error validating arguments: {}".format(e)) quit(1) try: # Create transaction tx = TransferTransaction.create(addrs_to=addresses_dst, amounts=shor_amounts, message_data=message_data, fee=fee_shor, xmss_pk=address_src_pk, master_addr=master_addr) # Sign transaction tx.sign(signing_object) # Print result txjson = tx_unbase64(tx.to_json()) print(txjson) if not tx.validate(): print("It was not possible to validate the signature") quit(1) print("\nTransaction Blob (signed): \n") txblob = tx.pbdata.SerializeToString() txblobhex = hexlify(txblob).decode() print(txblobhex) # Push transaction print("Sending to a QRL Node...") stub = ctx.obj.get_stub_public_api() push_transaction_req = qrl_pb2.PushTransactionReq( transaction_signed=tx.pbdata) push_transaction_resp = stub.PushTransaction( push_transaction_req, timeout=CONNECTION_TIMEOUT) # Print result print(push_transaction_resp) except Exception as e: print("Error {}".format(str(e)))
def test_transferCoins_sign(self): with set_data_dir('no_data'): with State() as db_state: with set_wallet_dir("test_wallet"): p2p_factory = Mock(spec=P2PFactory) p2p_factory.pow = Mock(spec=POW) chain_manager = ChainManager(db_state) qrlnode = QRLNode(db_state, slaves=[]) qrlnode.set_chain_manager(chain_manager) qrlnode._p2pfactory = p2p_factory qrlnode._pow = p2p_factory.pow qrlnode._peer_addresses = ['127.0.0.1', '192.168.1.1'] service = PublicAPIService(qrlnode) context = Mock(spec=ServicerContext) alice = get_alice_xmss() bob = get_bob_xmss() request = qrl_pb2.TransferCoinsReq( address_from=alice.address, addresses_to=[bob.address], amounts=[101], fee=12, xmss_pk=alice.pk) response = service.TransferCoins(request=request, context=context) context.set_code.assert_not_called() context.set_details.assert_not_called() self.assertIsNotNone(response) self.assertIsNotNone(response.transaction_unsigned) self.assertEqual( 'transfer', response.transaction_unsigned.WhichOneof( 'transactionType')) self.assertEqual(alice.address, response.transaction_unsigned.addr_from) self.assertEqual(12, response.transaction_unsigned.fee) self.assertEqual(alice.pk, response.transaction_unsigned.public_key) self.assertEqual(0, response.transaction_unsigned.nonce) self.assertEqual(b'', response.transaction_unsigned.signature) self.assertEqual( b'', response.transaction_unsigned.transaction_hash) self.assertEqual( bob.address, response.transaction_unsigned.transfer.addrs_to[0]) self.assertEqual( 101, response.transaction_unsigned.transfer.amounts[0]) tmp_hash_pre = response.transaction_unsigned.addr_from tmp_hash_pre += str( response.transaction_unsigned.fee).encode() tmp_hash_pre += response.transaction_unsigned.transfer.addrs_to[ 0] tmp_hash_pre += str(response.transaction_unsigned.transfer. amounts[0]).encode() self.assertEqual( '010300a1da274e68c88b0ccf448e0b1916fa789b01eb2ed4e9ad565ce264c939078' '2a9c61ac02f31320103001d65d7e59aed5efbeae64246e0f3184d7c42411421eb38' '5ba30f2c1c005a85ebc4419cfd313031', bin2hstr(tmp_hash_pre)) tmp_hash = sha256(tmp_hash_pre) self.assertEqual( '3645f2819aba65479f9a7fad3f5d7a41a9357410a595fa02fb947bfe3ed96e0f', bin2hstr(tmp_hash)) signed_transaction = response.transaction_unsigned signed_transaction.signature = alice.sign(tmp_hash) req_push = qrl_pb2.PushTransactionReq( transaction_signed=signed_transaction) resp_push = service.PushTransaction(req_push, context=context) context.set_code.assert_not_called() context.set_details.assert_not_called() self.assertIsNotNone(resp_push) self.assertEqual(qrl_pb2.PushTransactionResp.SUBMITTED, resp_push.error_code) self.assertEqual( '832c0fe9819992cc0d1d97f8d6579ca28e210c7884488a3858376a9c0cec279d', bin2hstr(resp_push.tx_hash))
def test_messageTxn_sign(self): with set_qrl_dir('wallet_ver1'): with State() as db_state: p2p_factory = Mock(spec=P2PFactory) p2p_factory.pow = Mock(spec=POW) chain_manager = ChainManager(db_state) qrlnode = QRLNode(db_state, mining_address=b'') qrlnode.set_chain_manager(chain_manager) qrlnode._p2pfactory = p2p_factory qrlnode._pow = p2p_factory.pow qrlnode._peer_addresses = ['127.0.0.1', '192.168.1.1'] service = PublicAPIService(qrlnode) context = Mock(spec=ServicerContext) alice = get_alice_xmss() my_message = b'Hello QRL!' request = qrl_pb2.MessageTxnReq( message=my_message, fee=12, xmss_pk=alice.pk ) response = service.GetMessageTxn(request=request, context=context) context.set_code.assert_not_called() context.set_details.assert_not_called() self.assertIsNotNone(response) self.assertIsNotNone(response.extended_transaction_unsigned.tx) self.assertEqual('message', response.extended_transaction_unsigned.tx.WhichOneof('transactionType')) self.assertEqual(12, response.extended_transaction_unsigned.tx.fee) self.assertEqual(alice.pk, response.extended_transaction_unsigned.tx.public_key) self.assertEqual(0, response.extended_transaction_unsigned.tx.nonce) self.assertEqual(b'', response.extended_transaction_unsigned.tx.signature) self.assertEqual(b'', response.extended_transaction_unsigned.tx.transaction_hash) self.assertEqual(my_message, response.extended_transaction_unsigned.tx.message.message_hash) tmp_hash_pre = response.extended_transaction_unsigned.tx.master_addr tmp_hash_pre += response.extended_transaction_unsigned.tx.fee.to_bytes(8, byteorder='big', signed=False) tmp_hash_pre += response.extended_transaction_unsigned.tx.message.message_hash tmp_hash = sha256(tmp_hash_pre) hash_found = bin2hstr(Transaction.from_pbdata(response.extended_transaction_unsigned.tx). get_hashable_bytes()) self.assertEqual(hash_found, bin2hstr(tmp_hash)) signed_transaction = response.extended_transaction_unsigned.tx signed_transaction.signature = alice.sign(tmp_hash) req_push = qrl_pb2.PushTransactionReq(transaction_signed=signed_transaction) resp_push = service.PushTransaction(req_push, context=context) context.set_code.assert_not_called() context.set_details.assert_not_called() self.assertIsNotNone(resp_push) self.assertEqual(qrl_pb2.PushTransactionResp.SUBMITTED, resp_push.error_code) self.assertEqual('b7ee814a548a6bbb8d97b2d3a0eb9e1f8b6ceee49b764e3c7b23d104aca6abeb', bin2hstr(resp_push.tx_hash))