def execute(args: Namespace, wallet_passwd: str) -> None: from hathor.crypto.util import get_private_key_bytes, get_public_key_bytes_compressed from hathor.wallet import Wallet from hathor.wallet.util import generate_multisig_address, generate_multisig_redeem_script if (args.pubkey_count and args.pubkey_count > 16) or args.signatures_required > 16: print( 'Error: maximum number of public keys or signatures required is 16' ) return if not args.pubkey_count and not args.public_keys: print('Error: you must give at least pubkey_count or public_keys') return if args.dir: wallet = Wallet(directory=args.dir) else: wallet = Wallet() wallet.unlock(wallet_passwd.encode()) if args.public_keys: public_keys_hex = args.public_keys.split(',') public_bytes = [bytes.fromhex(pkh) for pkh in public_keys_hex] else: # If not public keys as parameter, we need to create them public_bytes = [] for i in range(args.pubkey_count): addr = wallet.get_unused_address() key = wallet.keys[addr] pk = key.get_private_key(wallet_passwd.encode()) public_key_bytes = get_public_key_bytes_compressed(pk.public_key()) public_bytes.append(public_key_bytes) print('------------------\n') print('Key {}\n'.format(i + 1)) print('Private key: {}\n'.format( get_private_key_bytes( pk, encryption_algorithm=serialization.BestAvailableEncryption( wallet_passwd.encode())).hex())) print('Public key: {}\n'.format(public_key_bytes.hex())) print('Address: {}\n'.format(addr)) # Then we create the redeem script redeem_script = generate_multisig_redeem_script(args.signatures_required, public_bytes) print('------------------\n') print('Redeem script:', redeem_script.hex()) print('\n') # Then we created the multisig address address = generate_multisig_address(redeem_script) print('------------------\n') print('MultiSig address:', address) print('------------------\n\n')
def create_wallet(): if args.wallet == 'hd': print('Using HDWallet') kwargs = { 'words': args.words, } if args.passphrase: wallet_passphrase = getpass.getpass( prompt='HD Wallet passphrase:') kwargs['passphrase'] = wallet_passphrase.encode() if args.data: kwargs['directory'] = args.data return HDWallet(**kwargs) elif args.wallet == 'keypair': print('Using KeyPairWallet') if args.data: wallet = Wallet(directory=args.data) else: wallet = Wallet() wallet.flush_to_disk_interval = 5 # seconds if args.unlock_wallet: wallet_passwd = getpass.getpass(prompt='Wallet password:'******'Invalid type for wallet')
def test_wallet_keys_storage(self): w = Wallet(directory=self.directory) # Testing password error not in bytes with self.assertRaises(ValueError): w.unlock('testpass') w.unlock(b'testpass') w.generate_keys() # Using one address to save used/unused addresses in the file w.get_unused_address() w._write_keys_to_file() # wallet 2 will read from saved file w2 = Wallet(directory=self.directory) w2._manually_initialize() for address, key in w.keys.items(): key2 = w2.keys.pop(address) self.assertEqual(key, key2)
def setUp(self): super().setUp() self.network = 'testnet' self.manager = self.create_peer(self.network, unlock_wallet=True) self.tmpdir = tempfile.mkdtemp() self.wallet = Wallet(directory=self.tmpdir) self.wallet.unlock(b'123')
def test_insuficient_funds(self): w = Wallet(directory=self.directory) w.unlock(PASSWORD) # create transaction spending some value new_address = w.get_unused_address() out = WalletOutputInfo(decode_address(new_address), 100, timelock=None) with self.assertRaises(InsufficientFunds): w.prepare_transaction_compute_inputs(Transaction, outputs=[out])
def _create_test_wallet(self): """ Generate a Wallet with a number of keypairs for testing :rtype: Wallet """ tmpdir = tempfile.mkdtemp() self.tmpdirs.append(tmpdir) wallet = Wallet(directory=tmpdir) wallet.unlock(b'MYPASS') wallet.generate_keys(count=20) wallet.lock() return wallet
def execute(args: Namespace, password: str) -> None: from hathor.wallet import Wallet passwd: bytes = password.encode('utf-8') count = args.count directory = args.directory or './' print('Generating {} keys at {}'.format(count, directory)) wallet = Wallet(directory=directory) wallet.unlock(passwd) wallet.generate_keys(count=count) wallet._write_keys_to_file()
def setUp(self, tx_storage, reactor=None): if not reactor: self.reactor = Clock() else: self.reactor = reactor self.reactor.advance(time.time()) self.tx_storage = tx_storage assert tx_storage.first_timestamp > 0 tx_storage._manually_initialize() self.genesis = self.tx_storage.get_all_genesis() self.genesis_blocks = [tx for tx in self.genesis if tx.is_block] self.genesis_txs = [tx for tx in self.genesis if not tx.is_block] from hathor.manager import HathorManager self.tmpdir = tempfile.mkdtemp() wallet = Wallet(directory=self.tmpdir) wallet.unlock(b'teste') self.manager = HathorManager(self.reactor, tx_storage=self.tx_storage, wallet=wallet) self.tx_storage.wallet_index = WalletIndex(self.manager.pubsub) self.tx_storage.tokens_index = TokensIndex() block_parents = [tx.hash for tx in chain(self.genesis_blocks, self.genesis_txs)] output = TxOutput(200, bytes.fromhex('1e393a5ce2ff1c98d4ff6892f2175100f2dad049')) self.block = Block(timestamp=MIN_TIMESTAMP, weight=12, outputs=[output], parents=block_parents, nonce=100781, storage=tx_storage) self.block.resolve() self.block.verify() tx_parents = [tx.hash for tx in self.genesis_txs] tx_input = TxInput( tx_id=self.genesis_blocks[0].hash, index=0, data=bytes.fromhex('46304402203470cb9818c9eb842b0c433b7e2b8aded0a51f5903e971649e870763d0266a' 'd2022049b48e09e718c4b66a0f3178ef92e4d60ee333d2d0e25af8868acf5acbb35aaa583' '056301006072a8648ce3d020106052b8104000a034200042ce7b94cba00b654d4308f8840' '7345cacb1f1032fb5ac80407b74d56ed82fb36467cb7048f79b90b1cf721de57e942c5748' '620e78362cf2d908e9057ac235a63')) self.tx = Transaction( timestamp=MIN_TIMESTAMP + 2, weight=10, nonce=932049, inputs=[tx_input], outputs=[output], tokens=[bytes.fromhex('0023be91834c973d6a6ddd1a0ae411807b7c8ef2a015afb5177ee64b666ce602')], parents=tx_parents, storage=tx_storage) self.tx.resolve() # Disable weakref to test the internal methods. Otherwise, most methods return objects from weakref. self.tx_storage._disable_weakref() self.tx_storage.enable_lock()
def test_block_increase_balance(self): # generate a new block and check if we increase balance w = Wallet(directory=self.directory) w.unlock(PASSWORD) new_address = w.get_unused_address() key = w.keys[new_address] out = WalletOutputInfo(decode_address(key.address), BLOCK_REWARD, timelock=None) tx = w.prepare_transaction(Transaction, inputs=[], outputs=[out]) tx.update_hash() w.on_new_tx(tx) utxo = w.unspent_txs[settings.HATHOR_TOKEN_UID].get((tx.hash, 0)) self.assertIsNotNone(utxo) self.assertEqual(w.balance[settings.HATHOR_TOKEN_UID], WalletBalance(0, BLOCK_REWARD))
def setUp(self): super().setUp() self.wallet = Wallet() self.tx_storage = TransactionMemoryStorage() self.genesis = self.tx_storage.get_all_genesis() self.genesis_blocks = [tx for tx in self.genesis if tx.is_block] self.genesis_txs = [tx for tx in self.genesis if not tx.is_block] # read genesis keys self.genesis_private_key = get_genesis_key() self.genesis_public_key = self.genesis_private_key.public_key() # this makes sure we can spend the genesis outputs self.manager = self.create_peer('testnet', tx_storage=self.tx_storage, unlock_wallet=True) blocks = add_blocks_unlock_reward(self.manager) self.last_block = blocks[-1]
def test_invalid_address(self): w = Wallet(directory=self.directory) w.unlock(PASSWORD) # creating valid address valid_address = '15d14K5jMqsN2uwUEFqiPG5SoD7Vr1BfnH' WalletOutputInfo(decode_address(valid_address), 100, None) # creating invalid address invalid_address = '5d14K5jMqsN2uwUEFqiPG5SoD7Vr1BfnH' with self.assertRaises(InvalidAddress): WalletOutputInfo(decode_address(invalid_address), 100, None) # invalid address (checksum invalid) invalid_address2 = '15d14K5jMqsN2uwUEFqiPG5SoD7Vr1Bfnq' with self.assertRaises(InvalidAddress): WalletOutputInfo(decode_address(invalid_address2), 100, None)
def test_manager_connections(self): tx_storage = TransactionMemoryStorage() tmpdir = tempfile.mkdtemp() wallet = Wallet(directory=tmpdir) wallet.unlock(b'teste') manager = HathorManager(self.clock, tx_storage=tx_storage, wallet=wallet) endpoint = 'tcp://127.0.0.1:8005' manager.connections.connect_to(endpoint, use_ssl=True) self.assertFalse(endpoint in manager.connections.connecting_peers) self.assertFalse(endpoint in manager.connections.handshaking_peers) self.assertFalse(endpoint in manager.connections.connected_peers) manager.stop() manager.stop() shutil.rmtree(tmpdir)
def test_locked(self): # generate a new block and check if we increase balance w = Wallet(directory=self.directory) with self.assertRaises(OutOfUnusedAddresses): w.get_unused_address() # now it should work w.unlock(PASSWORD) w.get_unused_address() # lock wallet and fake that there are no more unused keys w.unused_keys = set() w.lock() with self.assertRaises(OutOfUnusedAddresses): w.get_unused_address() with self.assertRaises(WalletLocked): w.generate_keys()
def test_manager_connections(self): tx_storage = TransactionMemoryStorage() tmpdir = tempfile.mkdtemp() wallet = Wallet(directory=tmpdir) wallet.unlock(b'teste') manager = HathorManager(self.clock, tx_storage=tx_storage, wallet=wallet) endpoint = 'tcp://127.0.0.1:8005' manager.connections.connect_to(endpoint, use_ssl=True) self.assertNotIn(endpoint, manager.connections.iter_not_ready_endpoints()) self.assertNotIn(endpoint, manager.connections.iter_ready_connections()) self.assertNotIn(endpoint, manager.connections.iter_all_connections()) shutil.rmtree(tmpdir)
def test_wallet_create_transaction(self): genesis_private_key_bytes = get_private_key_bytes( self.genesis_private_key, encryption_algorithm=serialization.BestAvailableEncryption( PASSWORD)) genesis_address = get_address_b58_from_public_key( self.genesis_public_key) # create wallet with genesis block key key_pair = KeyPair(private_key_bytes=genesis_private_key_bytes, address=genesis_address, used=True) keys = {} keys[key_pair.address] = key_pair w = Wallet(keys=keys, directory=self.directory) w.unlock(PASSWORD) genesis_blocks = [ tx for tx in get_genesis_transactions(None) if tx.is_block ] genesis_block = genesis_blocks[0] genesis_value = sum([output.value for output in genesis_block.outputs]) # wallet will receive genesis block and store in unspent_tx w.on_new_tx(genesis_block) for index in range(len(genesis_block.outputs)): utxo = w.unspent_txs[settings.HATHOR_TOKEN_UID].get( (genesis_block.hash, index)) self.assertIsNotNone(utxo) self.assertEqual(w.balance[settings.HATHOR_TOKEN_UID], WalletBalance(0, genesis_value)) # create transaction spending this value, but sending to same wallet new_address = w.get_unused_address() out = WalletOutputInfo(decode_address(new_address), 100, timelock=None) tx1 = w.prepare_transaction_compute_inputs(Transaction, outputs=[out]) tx1.storage = self.storage tx1.update_hash() self.storage.save_transaction(tx1) w.on_new_tx(tx1) self.assertEqual(len(w.spent_txs), 1) self.assertEqual(w.balance[settings.HATHOR_TOKEN_UID], WalletBalance(0, genesis_value)) # pass inputs and outputs to prepare_transaction, but not the input keys # spend output last transaction input_info = WalletInputInfo(tx1.hash, 1, None) new_address = w.get_unused_address() key2 = w.keys[new_address] out = WalletOutputInfo(decode_address(key2.address), 100, timelock=None) tx2 = w.prepare_transaction_incomplete_inputs(Transaction, inputs=[input_info], outputs=[out], tx_storage=self.storage) tx2.storage = self.storage tx2.update_hash() self.storage.save_transaction(tx2) w.on_new_tx(tx2) self.assertEqual(len(w.spent_txs), 2) self.assertEqual(w.balance[settings.HATHOR_TOKEN_UID], WalletBalance(0, genesis_value)) # test keypair exception with self.assertRaises(WalletLocked): key_pair.get_private_key(None)