示例#1
0
def get_unused_payment_xmss(public_stub):
    global payment_slaves
    global payment_xmss

    master_address = payment_slaves[0]
    master_address_state = get_addr_state(master_address)

    if payment_xmss:
        addr_state = get_addr_state(payment_xmss.address)
        if set_unused_ots_key(payment_xmss, addr_state,
                              payment_xmss.ots_index):
            if valid_payment_permission(public_stub, master_address_state,
                                        payment_xmss, payment_slaves[2]):
                return payment_xmss
        else:
            payment_xmss = None

    if not payment_xmss:
        unused_ots_found = False
        for slave_seed in payment_slaves[1]:
            xmss = XMSS.from_extended_seed(slave_seed)
            addr_state = get_addr_state(xmss.address)
            if set_unused_ots_key(xmss, addr_state):  # Unused ots_key_found
                payment_xmss = xmss
                unused_ots_found = True
                break

        if not unused_ots_found:  # Unused ots_key_found
            return None

    if not valid_payment_permission(public_stub, master_address_state,
                                    payment_xmss, payment_slaves[2]):
        return None

    return payment_xmss
示例#2
0
    def _get_xmss_by_index_no_cache(self, idx) -> Optional[XMSS]:
        """
        Generates an XMSS tree based on the information contained in the wallet
        :param idx: The index of the address item
        :return: An XMSS tree object
        """
        if idx >= len(self._address_items):
            return None

        item = self._address_items[idx]
        extended_seed = mnemonic2bin(item.mnemonic.strip())
        tmp_xmss = XMSS.from_extended_seed(extended_seed)
        tmp_xmss.set_ots_index(item.index)

        if item.qaddress != 'Q' + bin2hstr(tmp_xmss.address):
            raise Exception("Mnemonic and address do not match.")

        if item.hexseed != tmp_xmss.hexseed:
            raise Exception("hexseed does not match.")

        if item.mnemonic != tmp_xmss.mnemonic:
            raise Exception("mnemonic does not match.")

        if item.height != tmp_xmss.height:
            raise Exception("height does not match.")

        return tmp_xmss
    def get_mining_xmss(self):
        if self._mining_xmss:
            addr_state = self.state.get_address(self._mining_xmss.address)
            if self.set_unused_ots_key(self._mining_xmss, addr_state,
                                       self._mining_xmss.ots_index):
                if self.valid_mining_permission():
                    return self._mining_xmss
            else:
                self._mining_xmss = None
            return None

        if not self._mining_xmss:
            self._master_address = self._slaves[0]
            unused_ots_found = False
            for slave_seed in self._slaves[1]:
                xmss = XMSS.from_extended_seed(slave_seed)
                addr_state = self.state.get_address(xmss.address)
                if self.set_unused_ots_key(xmss,
                                           addr_state):  # Unused ots_key_found
                    self._mining_xmss = xmss
                    unused_ots_found = True
                    break

            if not unused_ots_found:  # Unused ots_key_found
                logger.warning('No OTS-KEY left for mining')
                return None

        if self._master_address == self._mining_xmss.address:
            return self._mining_xmss

        if not self.valid_mining_permission():
            return None

        return self._mining_xmss
示例#4
0
def main():
    if len(sys.argv) > 2:
        print("Unexpected arguments")
        sys.exit(0)
    elif len(sys.argv) == 1:
        print("Missing Filename")
        sys.exit(0)

    filename = sys.argv[1]

    if sys.version_info.major > 2:
        seed = bytes(hstr2bin(input('Enter extended hexseed: ')))
    else:
        seed = bytes(hstr2bin(raw_input('Enter extended hexseed: ')))  # noqa

    dist_xmss = XMSS.from_extended_seed(seed)

    transactions = get_migration_transactions(signing_xmss=dist_xmss, filename=filename)

    block = Block.create(dev_config=config.dev,
                         block_number=0,
                         prev_headerhash=config.user.genesis_prev_headerhash,
                         prev_timestamp=config.user.genesis_timestamp,
                         transactions=transactions,
                         miner_address=dist_xmss.address,
                         seed_height=None,
                         seed_hash=None)

    block.set_nonces(config.dev, 0, 0)

    block._data.genesis_balance.extend([qrl_pb2.GenesisBalance(address=config.dev.coinbase_address,
                                                               balance=105000000000000000)])

    with open('genesis.yml', 'w') as f:
        yaml.dump(json.loads(block.to_json()), f)
def generate_slave_from_input(slaves_filename):
    # FIXME: Refactor and improve error handling
    extended_seed = ''
    logger.warning('No Slave Seeds found!!')
    logger.warning('It is highly recommended to use the slave for mining')
    try:
        ans = input('Do you want to use main wallet for mining? (Y/N) ')
        if ans == 'N':
            quit(0)
        extended_seed = input(
            'Enter hex or mnemonic seed of mining wallet ').encode()
    except KeyboardInterrupt:
        quit(0)

    bin_extended_seed = None
    if len(extended_seed) == 102:  # hexseed
        bin_extended_seed = hstr2bin(extended_seed.decode())
    elif len(extended_seed.split()) == 34:
        bin_extended_seed = mnemonic2bin(extended_seed.decode())

    if bin_extended_seed is None:
        logger.warning('Invalid XMSS seed')
        quit(1)

    addrBundle = XMSS.from_extended_seed(bin_extended_seed)
    slaves = [
        bin2hstr(addrBundle.xmss.address), [addrBundle.xmss.extended_seed],
        None
    ]
    write_slaves(slaves_filename, slaves)
示例#6
0
    def get_xmss_by_item(self, item: AddressItem, ots_index=-1) -> XMSS:
        """
        Generates an XMSS tree based on the given AddressItem
        :param item:
        :param ots_index:
        :return:
        """

        extended_seed = mnemonic2bin(item.mnemonic.strip())
        tmp_xmss = XMSS.from_extended_seed(extended_seed)
        if ots_index > -1:
            tmp_xmss.set_ots_index(ots_index)
        else:
            tmp_xmss.set_ots_index(item.index)

        if item.qaddress != 'Q' + bin2hstr(tmp_xmss.address):
            raise Exception("Mnemonic and address do not match.")

        if item.hexseed != tmp_xmss.hexseed:
            raise Exception("hexseed does not match.")

        if item.mnemonic != tmp_xmss.mnemonic:
            raise Exception("mnemonic does not match.")

        if item.height != tmp_xmss.height:
            raise Exception("height does not match.")

        return tmp_xmss
示例#7
0
    def test_multi_output_transaction_add_block(self, time_mock):
        # Test that adding block with a multi-output Transaction updates everybody's balances correctly.
        self.chain_manager.load(self.genesis_block)

        extended_seed = "010300cebc4e25553afa0aab899f7838e59e18a48852fa9dfd5" \
                        "ae78278c371902aa9e6e9c1fa8a196d2dba0cbfd2f2d212d16c"
        random_xmss = XMSS.from_extended_seed(hstr2bin(extended_seed))

        transfer_transaction = TransferTransaction.create(
            addrs_to=[alice.address, random_xmss.address],
            amounts=[
                40 * int(config.dev.shor_per_quanta),
                59 * int(config.dev.shor_per_quanta)
            ],
            fee=1 * config.dev.shor_per_quanta,
            xmss_pk=bob.pk)
        transfer_transaction._data.nonce = 1
        transfer_transaction.sign(bob)

        time_mock.return_value = 1615270948  # Very high to get an easy difficulty

        block_1 = Block.create(block_number=1,
                               prev_headerhash=self.genesis_block.headerhash,
                               prev_timestamp=self.genesis_block.timestamp,
                               transactions=[transfer_transaction],
                               miner_address=alice.address)
        block_1.set_nonces(129, 0)

        # Uncomment only to determine the correct mining_nonce of above blocks
        # from qrl.core.PoWValidator import PoWValidator
        # while not PoWValidator().validate_mining_nonce(self.state, block_1.blockheader, False):
        #     block_1.set_nonces(block_1.mining_nonce + 1)
        #     print(block_1.mining_nonce)
        self.assertTrue(block_1.validate(self.chain_manager, {}))
        result = self.chain_manager.add_block(block_1)

        self.assertTrue(result)
        self.assertEqual(self.chain_manager.last_block, block_1)

        bob_addr_state = self.state.get_address_state(bob.address)
        alice_addr_state = self.state.get_address_state(alice.address)
        random_addr_state = self.state.get_address_state(random_xmss.address)

        self.assertEqual(bob_addr_state.balance, 0)
        self.assertEqual(
            alice_addr_state.balance, 140 * int(config.dev.shor_per_quanta) +
            block_1.block_reward + block_1.fee_reward)
        self.assertEqual(random_addr_state.balance,
                         159 * int(config.dev.shor_per_quanta))
示例#8
0
    def get_new_address(signature_tree_height=config.dev.xmss_tree_height,
                        seed=None) -> AddressBundle:
        """
        Get a new wallet address
        The address format is a list of two items [address, data structure from random_mss call]
        :param signature_tree_height:
        :param address_type:
        :param seed:
        :return: a wallet address
        """
        # FIXME: This should be always using the extended seed instead
        if seed and signature_tree_height:
            xmss = XMSS(XmssFast(seed, signature_tree_height))
        elif seed:
            xmss = XMSS.from_extended_seed(seed)
        else:
            xmss = XMSS.from_height(signature_tree_height)

        return AddressBundle(bin2hstr(xmss.address).encode(), xmss)
示例#9
0
    def add_address_from_seed(self, seed=None) -> str:
        self.authenticate()

        words = seed.split()
        if len(words) == 34:
            bin_seed = mnemonic2bin(seed)
        elif len(seed) == 102:
            bin_seed = hstr2bin(seed)
        else:
            raise ValueError("Invalid Seed")

        address_from_seed = XMSS.from_extended_seed(bin_seed)
        if self._wallet.get_xmss_by_qaddress(address_from_seed.qaddress,
                                             self._passphrase):
            raise Exception("Address is already in the wallet")
        self._wallet.append_xmss(address_from_seed)
        self._encrypt_last_item()
        self._wallet.save()

        return address_from_seed.qaddress
示例#10
0
def wallet_recover(ctx, seed_type):
    """
    Recovers a wallet from a hexseed or mnemonic (32 words)
    """
    if ctx.obj.remote:
        click.echo('This command is unsupported for remote wallets')
        return

    seed = click.prompt('Please enter your %s' % (seed_type, ))
    seed = seed.lower().strip()

    if seed_type == 'mnemonic':
        words = seed.split()
        if len(words) != 34:
            print('You have entered %s words' % (len(words), ))
            print('Mnemonic seed must contain only 34 words')
            return
        bin_seed = mnemonic2bin(seed)
    else:
        if len(seed) != 102:
            print('You have entered hexseed of %s characters' % (len(seed), ))
            print('Hexseed must be of only 102 characters.')
            return
        bin_seed = hstr2bin(seed)

    walletObj = Wallet(wallet_path=ctx.obj.wallet_path)

    recovered_xmss = XMSS.from_extended_seed(bin_seed)
    print('Recovered Wallet Address : %s' %
          (Wallet._get_Qaddress(recovered_xmss.address), ))
    for addr in walletObj.address_items:
        if recovered_xmss.qaddress == addr.qaddress:
            print('Wallet Address is already in the wallet list')
            return

    if click.confirm('Do you want to save the recovered wallet?'):
        click.echo('Saving...')
        walletObj.append_xmss(recovered_xmss)
        walletObj.save()
        click.echo('Done')
        _print_addresses(ctx, walletObj.address_items, config.user.wallet_dir)
示例#11
0
    def _read_wallet(self):
        self.address_bundle = []

        if not os.path.isfile(self.wallet_dat_filename):
            return

        try:
            with open(self.wallet_dat_filename, "rb") as infile:
                wallet_store = qrl_pb2.WalletStore()
                wallet_store.ParseFromString(bytes(infile.read()))

                self.address_bundle = []
                for a in wallet_store.wallets:
                    tmpxmss = XMSS.from_extended_seed(mnemonic2bin(a.mnemonic.strip()))
                    tmpxmss.set_ots_index(a.xmss_index)
                    if a.address != bin2hstr(tmpxmss.address).encode():
                        logger.fatal("Mnemonic and address do not match.")
                        exit(1)
                    self.address_bundle.append(AddressBundle(a.address, tmpxmss))

        except Exception as e:
            logger.warning("It was not possible to open the wallet: %s", e)
示例#12
0
    def test_multi_output_transaction_add_block(self):
        with set_data_dir('no_data'):
            with State() as state:
                state.get_measurement = MagicMock(return_value=10000000)
                alice_xmss = get_alice_xmss()
                bob_xmss = get_bob_xmss()
                extended_seed = "010300cebc4e25553afa0aab899f7838e59e18a48852fa9dfd5" \
                                "ae78278c371902aa9e6e9c1fa8a196d2dba0cbfd2f2d212d16c"
                random_xmss = XMSS.from_extended_seed(hstr2bin(extended_seed))

                transfer_transaction = TransferTransaction.create(
                    addrs_to=[alice_xmss.address, random_xmss.address],
                    amounts=[
                        40 * int(config.dev.shor_per_quanta),
                        59 * int(config.dev.shor_per_quanta)
                    ],
                    fee=1 * config.dev.shor_per_quanta,
                    xmss_pk=bob_xmss.pk)
                transfer_transaction._data.nonce = 1
                transfer_transaction.sign(bob_xmss)

                genesis_block = GenesisBlock()
                chain_manager = ChainManager(state)
                chain_manager.load(genesis_block)

                chain_manager._difficulty_tracker = Mock()
                dt = DifficultyTracker()
                tmp_difficulty = StringToUInt256('2')
                tmp_boundary = dt.get_target(tmp_difficulty)
                chain_manager._difficulty_tracker.get = MagicMock(
                    return_value=(tmp_difficulty, tmp_boundary))

                block = state.get_block(genesis_block.headerhash)
                self.assertIsNotNone(block)

                with mock.patch('qrl.core.misc.ntp.getTime') as time_mock:
                    time_mock.return_value = 1615270948  # Very high to get an easy difficulty

                    block_1 = Block.create(
                        block_number=1,
                        prevblock_headerhash=genesis_block.headerhash,
                        transactions=[transfer_transaction],
                        miner_address=alice_xmss.address)
                    block_1.set_nonces(274, 0)

                    # Uncomment only to determine the correct mining_nonce of above blocks
                    # from qrl.core.PoWValidator import PoWValidator
                    # while not PoWValidator().validate_mining_nonce(state, block_1.blockheader, False):
                    #     block_1.set_nonces(block_1.mining_nonce + 1)
                    #     print(block_1.mining_nonce)

                    result = chain_manager.add_block(block_1)

                self.assertTrue(result)
                self.assertEqual(chain_manager.last_block, block_1)

                bob_addr_state = state.get_address(bob_xmss.address)
                alice_addr_state = state.get_address(alice_xmss.address)
                random_addr_state = state.get_address(random_xmss.address)

                self.assertEqual(bob_addr_state.balance, 0)
                self.assertEqual(
                    alice_addr_state.balance,
                    140 * int(config.dev.shor_per_quanta) +
                    block_1.block_reward + block_1.fee_reward)
                self.assertEqual(random_addr_state.balance,
                                 159 * int(config.dev.shor_per_quanta))
示例#13
0
            transactions.append(
                create_tx(addrs_to, amounts, signing_xmss,
                          count // output_limit))

            addrs_to = []
            amounts = []

    if addrs_to:
        transactions.append(create_tx(addrs_to, amounts, signing_xmss, count))

    return transactions


seed = bytes(hstr2bin(input('Enter extended hexseed: ')))

dist_xmss = XMSS.from_extended_seed(seed)

transactions = get_migration_transactions(signing_xmss=dist_xmss)

block = Block.create(block_number=0,
                     prevblock_headerhash=config.dev.genesis_prev_headerhash,
                     transactions=transactions,
                     miner_address=dist_xmss.address)

block.set_nonces(0, 0)

block._data.genesis_balance.MergeFrom([
    qrl_pb2.GenesisBalance(address=config.dev.coinbase_address,
                           balance=105000000000000000)
])