예제 #1
0
def tx_push(ctx, txblob):
    """
    Sends a signed transaction blob to a node
    """
    tx = None
    try:
        txbin = parse_hexblob(txblob)
        pbdata = xrd_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 = xrd_pb2.PushTransactionReq(transaction_signed=tx.pbdata)
    pushTransactionResp = stub.PushTransaction(pushTransactionReq, timeout=CONNECTION_TIMEOUT)
    print(pushTransactionResp.error_code)
예제 #2
0
    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 is 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 = xrd_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 != xrd_pb2.PushTransactionResp.SUBMITTED:
            raise Exception(push_transaction_resp.error_description)
예제 #3
0
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 = xrd_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 test_transferCoins_push_unsigned(self):
        with set_xrd_dir('wallet_ver1'):
            with State() as db_state:
                p2p_factory = Mock(spec=P2PFactory)
                p2p_factory.pow = Mock(spec=POW)
                chain_manager = ChainManager(db_state)

                xrdnode = xrdNode(mining_address=b'')
                xrdnode.set_chain_manager(chain_manager)
                xrdnode._p2pfactory = p2p_factory
                xrdnode._pow = p2p_factory.pow
                xrdnode._peer_addresses = ['127.0.0.1', '192.168.1.1']

                service = PublicAPIService(xrdnode)

                context = Mock(spec=ServicerContext)

                alice = get_alice_xmss()
                bob = get_bob_xmss()

                request = xrd_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 = xrd_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(xrd_pb2.PushTransactionResp.VALIDATION_FAILED,
                                 resp_push.error_code)
예제 #5
0
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 = 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)))
예제 #6
0
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=xrd_pb2.PushTransactionReq(
            transaction_signed=tx.pbdata))
        return None

    if access_type == 0:
        return True

    return False
예제 #7
0
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()
        addr_to = parse_qaddress(addr_to, False)

        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 = xrd_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)))
예제 #8
0
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,
                                    message_data=None,
                                    fee=fee,
                                    xmss_pk=xmss.pk,
                                    master_addr=payment_slaves[0])

    tx.sign(xmss)

    response = stub.PushTransaction(request=xrd_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 test_messageTxn_sign(self):
        with set_xrd_dir('wallet_ver1'):
            with State() as db_state:
                p2p_factory = Mock(spec=P2PFactory)
                p2p_factory.pow = Mock(spec=POW)
                chain_manager = ChainManager(db_state)

                xrdnode = xrdNode(mining_address=b'')
                xrdnode.set_chain_manager(chain_manager)
                xrdnode._p2pfactory = p2p_factory
                xrdnode._pow = p2p_factory.pow
                xrdnode._peer_addresses = ['127.0.0.1', '192.168.1.1']

                service = PublicAPIService(xrdnode)

                context = Mock(spec=ServicerContext)

                alice = get_alice_xmss()
                my_message = b'Hello xrd!'

                request = xrd_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_data_hash())
                self.assertEqual(hash_found,
                                 bin2hstr(tmp_hash))

                signed_transaction = response.extended_transaction_unsigned.tx
                signed_transaction.signature = alice.sign(tmp_hash)

                req_push = xrd_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(xrd_pb2.PushTransactionResp.SUBMITTED,
                                 resp_push.error_code)
                self.assertEqual('b7ee814a548a6bbb8d97b2d3a0eb9e1f8b6ceee49b764e3c7b23d104aca6abeb',
                                 bin2hstr(resp_push.tx_hash))
    def test_transferCoins_sign(self):
        with set_xrd_dir('wallet_ver1'):
            with State() as db_state:
                p2p_factory = Mock(spec=P2PFactory)
                p2p_factory.pow = Mock(spec=POW)
                chain_manager = ChainManager(db_state)

                xrdnode = xrdNode(mining_address=b'')
                xrdnode.set_chain_manager(chain_manager)
                xrdnode._p2pfactory = p2p_factory
                xrdnode._pow = p2p_factory.pow
                xrdnode._peer_addresses = ['127.0.0.1', '192.168.1.1']

                service = PublicAPIService(xrdnode)

                context = Mock(spec=ServicerContext)

                alice = get_alice_xmss()
                bob = get_bob_xmss()

                request = xrd_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(xrdHelper.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 = xrd_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(xrd_pb2.PushTransactionResp.SUBMITTED,
                                 resp_push.error_code)
                self.assertEqual('30955fdc5e2d9dbe5fb9bf812f2e1b6c4b409a8a7c7a75f1c3e9ba1ffdd8e60e',
                                 bin2hstr(resp_push.tx_hash))
예제 #11
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)))
예제 #12
0
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 xrd Node...")
        stub = ctx.obj.get_stub_public_api()
        push_transaction_req = xrd_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)))