def wallet_info(data): l = json.loads(data) key = RSAKey(RSAPublicKey.load(l.get('public_key')), None) wallet = Wallet(key, blockchain) return json.dumps({"balance": wallet.balance()})
def __init__(self, seed, *args): self.seed = seed self.wallet = Wallet(utils.hash(str(self.seed))) self.neighbours = set() self.DAG = {} root_transaction = Transaction('0000', 'root', 25000000000) self.attach_transaction(root_transaction, ['root'])
def test_fraudulent_tx_source_other_user(self): blockchain = Blockchain() victim = generate_key() miner_key = generate_key() miner = Miner(blockchain) miner.reward_addr = miner_key.publickey() emptyblock = miner._mine() transfer = Wallet(miner_key, blockchain) transfer.send(10, victim.publickey()) self.assertEqual(len(emptyblock.transactions), 1) self._test_fraudulent_tx(victim, blockchain)
def wallet_send(data): l = json.loads(data) key = RSAKey(RSAPublicKey.load(l.get('public_key')), RSAPrivateKey.load(l.get('private_key'))) wallet = Wallet(key, blockchain) try: wallet.send(l.get('amount'), l.get('recipient')) except InsufficientFundsException: return json.dumps({ "successful": False, "message": "Insufficient funds" }) return json.dumps({"successful": True})
def allowConnection(self, user_ID, password, newWallet=False): """Create or connect to a wallet user_ID : The identification of the user password : The password of the user newWallet : True to create a new wallet with these information False to connecte to user to his Wallet """ hashPass = sha_256(password) if newWallet: if newUser(user_ID, hashPass[:16] + hashPass[48:]): return Wallet(user_ID, password) else: if userExist(user_ID, hashPass[:16] + hashPass[48:]): return Wallet(user_ID, password) return None
def add_user(self, username): wallet = Wallet(user=username) return wallet
def __init__(self, passphrase, config): self.config = config self.passphrase = passphrase self.wallet = Wallet(self.passphrase, self.config)
def get_user(self, wallet_id): wallet = Wallet() wallet.load(wallet_id=wallet_id) return wallet
class Node(): def __init__(self, seed, *args): self.seed = seed self.wallet = Wallet(utils.hash(str(self.seed))) self.neighbours = set() self.DAG = {} root_transaction = Transaction('0000', 'root', 25000000000) self.attach_transaction(root_transaction, ['root']) def proof_of_work(self, str_input): proof = 0 while self.is_valid_proof(str_input, proof) is False: proof += 1 return proof def is_valid_proof(self, str_input, proof): result = utils.hash(str_input + str(proof)) return result.count("00") >= 2 and result[-4:] == "0000" def select_tips(self): available_transactions = [] selected_transactions = [] for key in self.DAG: _transaction = self.DAG[key] if _transaction.state == 1: available_transactions.append(_transaction) if len(available_transactions) >= 1: for i in range(2): selected_transactions.append(available_transactions[randint( 0, len(available_transactions) - 1)].key) return selected_transactions def make_transaction(self, receiving_addr, value): ''' 1. Pick at least two transactions in Tangle to confirm 2. Check picked transactions for conflict 3. Approve non conflicting transactions 4. Perform proof of work 5. Send transaction to tangle ''' confirmed_transactions = self.confirm_transactions() if len(confirmed_transactions) >= 2: proof_of_work = self.proof_of_work(''.join(confirmed_transactions)) new_transaction = Transaction(self.wallet.generate_address(), receiving_addr, value) new_transaction.pow = proof_of_work return self.attach_transaction(new_transaction, confirmed_transactions) return {'msg': 'transaction failed'} def confirm_transactions(self): ''' Even when a node is not making any transactions, it must participate in confirming transactions in the network. A lazy node risks being dropped by its neighbour Different approches to picking transactions to confirm> 1. Randomly pick any N visible transactions 2. Pick r.N/n transactions. r=rate of new transaction attachment to Tangle. N=number of visible transactions. n=number of neighbour nodes. we will pick the naive one. TODO: check the validity of the PoW of selected transactions ''' ''' Select tips and assume the transactions are non-conflicting. ''' return self.select_tips() def sync_neighbour(self): #TODO: search for neighbour and return a Tangle pass def register_neighbours(self, neighbours): for ip in neighbours: self.neighbours.add(neighbours[ip]) return None def attach_transaction(self, transaction, confirmed_transactions): if self.is_valid_transaction(transaction): transaction.key = utils.hash( utils.str_join([ transaction.time_stamp, transaction.pow, transaction.tnx['sending_addr'], transaction.tnx['receiving_addr'], transaction.tnx['value'] ])) for trans in confirmed_transactions: transaction.pre_transactions.add(trans) self.DAG[transaction.key] = transaction # switch transaction state to revealed after 30 secs. Timer(30, lambda: self.reveal(transaction), None).start() return {'msg': 'ransaction successful'} return {'msg': 'invalid transaction. Attachment failed'} def is_valid_transaction(self, transaction): # TODO: implement transaction validation logic return True def reveal(self, transaction): transaction.state = 1 print("transaction revealed")
def main(): # Script argument parsing parser = argparse.ArgumentParser( description= 'A script to perform bruteforce dictionary attacks on brainwallets.') parser.add_argument('-t', action='store', dest='type', help='Blockchain lookup type ({}|{}|{}|{})'.format( Abe.STRING_TYPE, BlockchainInfo.STRING_TYPE, Insight.STRING_TYPE, BlockExplorerCom.STRING_TYPE, AddressSetExplorer.STRING_TYPE), required=True) parser.add_argument('-d', action='store', dest='dict_file', help='Dictionary file (e.g. dictionary.txt)', required=True) parser.add_argument('-o', action='store', dest='output_file', help='Output file (e.g. output.txt)', required=True) parser.add_argument('-s', action='store', dest='server', help='Abe server address (e.g. localhost)') parser.add_argument('-p', action='store', dest='port', help='Abe port (e.g. 2751)') parser.add_argument('-c', action='store', dest='chain', help='Abe chain string (e.g. Bitcoin)') parser.add_argument( '-k', action='store', dest='is_private_key', default=0, help= '0 - treat as passphrase, 1 - treat as private key, 2- treat as old electrum passphrase' ) parser.add_argument('-C', action='store_true', dest='capitalize', default=False, help='capitalize each word') parser.add_argument('-u', action='store_true', dest='uppercase', default=False, help='uppercase each word') parser.add_argument('-a', action='store_true', dest='append', default=False, help='append found file') parser.add_argument( '-rpc', action='store', dest='rpc', default=None, help= 'auto add found keys to your wallet using rpc url (e,g: http://myuser:mypassword@localhost:8332/)' ) parser.add_argument('--version', action='version', version='%(prog)s 1.1') args = parser.parse_args() # Setup logging logging.basicConfig( level=logging.INFO, format='%(asctime)s %(levelname)-6s line %(lineno)-4s %(message)s') # Check valid blockchain lookup type is specified if args.type != BlockchainInfo.STRING_TYPE and args.type != Abe.STRING_TYPE and args.type != Insight.STRING_TYPE and args.type != BlockExplorerCom.STRING_TYPE and args.type != AddressSetExplorer.STRING_TYPE: logging.error("Invalid -t option specified.") sys.exit(1) # If abe is selected, make sure required options are given if args.type == Abe.STRING_TYPE: if not args.server: logging.error("Abe server (-s) must be specified.") sys.exit(1) if not args.port: logging.error("Abe port (-p) must be specified.") sys.exit(1) if not args.chain: logging.error("Abe chain (-c) must be specified.") sys.exit(1) # Choose connection type if args.type == Abe.STRING_TYPE: blockexplorer = Abe(args.server, args.port, args.chain) elif args.type == BlockchainInfo.STRING_TYPE: blockexplorer = BlockchainInfo() elif args.type == Insight.STRING_TYPE: blockexplorer = Insight() elif args.type == BlockExplorerCom.STRING_TYPE: blockexplorer = BlockExplorerCom() elif args.type == AddressSetExplorer.STRING_TYPE: blockexplorer = AddressSetExplorer() else: logging.error("Invalid lookup type specified '{}'".format(args.type)) sys.exit(1) # Open session logging.info("Opening session for {}".format(args.type)) blockexplorer.open_session() if args.capitalize: logging.info('capitalizing...') if args.uppercase: logging.info('uppercasing...') # Open dictionary file and validate encoding dictionary_encoding = "utf-8" logging.info( "Opening dictionary file {} and validating encoding is {}".format( args.dict_file, dictionary_encoding)) try: f_dictionary = io.open(args.dict_file, 'rt', encoding=dictionary_encoding) f_dictionary.read(4096) f_dictionary.close() except Exception as e: logging.error( "Failed to open dictionary file {}. Make sure file is {} encoded.". format(args.dict_file, dictionary_encoding)) sys.exit(1) # Open dictionary file for reading logging.info("Opening dictionary file {} for reading".format( args.dict_file)) try: # Open file for reading logging.info( "Opening file with encoding {}".format(dictionary_encoding)) f_dictionary = io.open(args.dict_file, 'rt', encoding=dictionary_encoding) except Exception as e: logging.error("Failed to open dictionary file {}. Error: {}".format( args.dict_file, e.args)) sys.exit(1) # Open output file for found addresses file_header = 'dictionary word, received bitcoins, wallet address, private address, current balance' logging.info("Opening output file {} for writing".format(args.output_file)) try: f_found_addresses = codecs.open(args.output_file, 'a' if args.append else 'w', dictionary_encoding) logging.info(file_header) if not args.append: f_found_addresses.writelines(file_header + '\n') except Exception as e: logging.error("Failed to open output file {}. Error: {}".format( args.found_file, e.args)) sys.exit(1) # Loop through dictionary for raw_word in f_dictionary: dictionary_word = raw_word.rstrip() if not dictionary_word: continue if args.capitalize: dictionary_word = dictionary_word.capitalize() elif args.uppercase: dictionary_word = dictionary_word.upper() # Print each word since this is rate limited if args.type == BlockchainInfo.STRING_TYPE: logging.info(u"Checking wallet '%s'" % dictionary_word) # Create wallet try: wallet = Wallet(dictionary_word, args.is_private_key) except Exception as e: logging.error("failed to generate key " + str(e) + " " + dictionary_word) continue # Get received bitcoins retry = 0 retry_count = 6 sleep_seconds = 10 while retry < retry_count: try: received_bitcoins = blockexplorer.get_received(wallet.address) break except Exception as e: logging.warning( "Failed to get proper response for received bitcoins. Retry in {} seconds." .format(sleep_seconds)) time.sleep(sleep_seconds) retry += 1 if retry == retry_count: logging.error( "Failed to get response for received bitcoins after {} retries. Skipping." .format(retry_count)) continue if received_bitcoins == 0: logging.debug("Received bitcoins is zero.. moving on") continue elif args.rpc: try: res = post(args.rpc, json={ 'method': "importprivkey", 'params': [wallet.wif, "brute", False] }) if res.status_code != 200: logging.error("import private key failed: " + res.text) except Exception as e: logging.error('rpc failed: ' + str(e)) # Get current balance retry = 0 retry_count = 5 sleep_seconds = 15 while retry < retry_count: try: current_balance = blockexplorer.get_balance(wallet.address) break except Exception as e: logging.warning( "Failed to get proper response for balance. Retry in {} seconds." .format(sleep_seconds)) time.sleep(sleep_seconds) retry += 1 if retry == retry_count: logging.error( "Failed to get response for balance after {} retries. Skipping." .format(retry_count)) continue # Output results output = 'Found used wallet: {},{:.8f},{},{},{:.8f}'.format( dictionary_word, received_bitcoins, wallet.address, wallet.wif, current_balance) logging.info(output) f_found_addresses.write(output + '\n') # Close files and connection blockexplorer.close_session() f_found_addresses.close() f_dictionary.close() if args.rpc: logging.info("force reload of the wallet by importing new address in") try: res = post(args.rpc, json={ 'method': "importprivkey", 'params': [Wallet().wif, "brute", False] }) if res.status_code != 200: logging.error("import private key for reload failed: " + res.text) except Exception as e: logging.error('rpc failed: ' + str(e))
def api(): operation = request.form.get('operation') resp = {} if operation == 'add': # create a new user wallet if genesis_wallet.get_balance() < 50.: resp['code'] = 500 resp['message'] = 'Server full cannot add new users.' else: username = request.form.get('username') wallet = manager.add_user(username) users[wallet.wallet_id] = wallet wallet.save() # save the wallet to disk. # add 50 coins to new user's wallet upon signup. last_block = block_chain.get_block(block_chain.size() - 1) transaction = genesis_wallet.send_funds(wallet.public_key, 50.) add_block(last_block.hash, transaction) resp['code'] = 200 resp['message'] = "User added and a wallet is created" resp['info'] = { 'balance': wallet.get_balance(), 'id': wallet.wallet_id } elif operation == 'list': # list all the online users to whom the amount can be transferred resp['code'] = 200 resp['message'] = "List generated successfully" users_list = [] for wallet_id in users.keys(): users_list.append({'id': wallet_id, 'name': users[wallet_id].user}) resp['info'] = {'users_list': users_list} elif operation == 'fetch': wallet_id = request.form.get('wallet_id') if wallet_id in users: wallet = users[wallet_id] resp['code'] = 200 resp['message'] = 'Info fetched successfully' resp['info'] = {'balance': wallet.get_balance(), 'id': wallet_id} else: resp['code'] = 500 resp['message'] = 'Cannot find wallet info in logged in users.' elif operation == 'login': # user login wallet_id = request.form.get('wallet_id') if manager.check_user(wallet_id): wallet = manager.get_user(wallet_id) users[wallet.wallet_id] = wallet resp['code'] = 200 resp['message'] = "User logged in successfully" resp['info'] = {'balance': wallet.get_balance(), 'id': wallet_id} else: resp['code'] = 500 resp['message'] = "User does not exists with the name" elif operation == 'logout': wallet_id = request.form.get('wallet_id') if wallet_id in users: wallet = users[wallet_id] wallet.save() del users[wallet_id] resp['code'] = 200 resp['message'] = "User logged out successfully" else: resp['code'] = 500 resp['message'] = "User cannot be logged out" elif operation == 'transact': sender = request.form.get('sender') # sender wallet id receiver = request.form.get('receiver') # receiver wallet id amount = float(request.form.get('amount')) sender_wallet = users[sender] receiver_wallet = Wallet() receiver_wallet.load(receiver) if sender_wallet.get_balance() < amount: resp['code'] = 500 resp['message'] = "Low balance, cannot proceed with transaction" else: last_block = block_chain.get_block(block_chain.size() - 1) transaction = sender_wallet.send_funds(receiver_wallet.public_key, amount) add_block(last_block.hash, transaction) resp['code'] = 200 resp['message'] = "Transaction successful" resp['info'] = { 'balance': sender_wallet.get_balance(), 'transaction_id': transaction.transaction_id } else: resp['code'] = 500 resp['message'] = "Unknown operation" return json.dumps(resp)
pass if __name__=="__main__": # options if sys.argv[1:]: if sys.argv[1] in ['-h','--help','-?']: print __doc__ sys.exit(0) gap_limit = int(sys.argv[1]) if int(sys.argv[1]) >= 5 else 5 else: gap_limit = 10 config = SimpleConfig(offline_config) storage = EphemeralStorage(config) storage.write = lambda : None wallet = Wallet(storage) wallet.init_seed(None) #wallet.save_seed() wallet.create_accounts() #called by save_seed wallet.change_gap_limit(gap_limit) wallet.synchronize() print print print 'SEED',wallet.get_mnemonic(None) for a,k in [(address,wallet.get_private_key(address, None)[0]) for address in wallet.addresses(False)]: print a,k
else: resp['code'] = 500 resp['message'] = "Unknown operation" return json.dumps(resp) def add_block(prev_hash, transaction): block = Block(prev_hash) block.add_transaction(transaction) block_chain.add(block) if __name__ == '__main__': # create the genesis block coinbase = Wallet() genesis_wallet = Wallet() genesis_transaction = Transaction(coinbase.public_key, genesis_wallet.public_key, GENESIS_AMOUNT, None) genesis_transaction.gen_signature( coinbase.private_key) # manually sign the genesis transaction genesis_transaction.transaction_id = "0" # set the transaction id # add the Transactions Output genesis_output = TransactionOutput(genesis_transaction.receiver, genesis_transaction.amount, genesis_transaction.transaction_id) genesis_transaction.transaction_outputs.append(genesis_output)
def wallet(env): return Wallet(env.config)
def test_chained_tx(self): blockchain = Blockchain() member1 = generate_key() member2 = generate_key() member3 = generate_key() miner = Miner(blockchain) miner.reward_addr = member1.publickey() _ = miner._mine() wallet1 = Wallet(member1, blockchain) wallet1.send(10, member2.publickey()) wallet2 = Wallet(member2, blockchain) wallet2.send(10, member3.publickey()) wallet3 = Wallet(member3, blockchain) self.assertEqual(wallet1.balance(), 0) self.assertEqual(wallet2.balance(), 0) self.assertEqual(wallet3.balance(), 10)
def _sanity_check_upgraded_storage(self, storage): self.assertFalse(storage.requires_split()) self.assertFalse(storage.requires_upgrade()) w = Wallet(storage)
def test_value_transfer(self): """ Test successful transaction """ SENDER_ORIG_VALUE = MINING_REWARD # Mining reward SEND_AMOUNT = 5 blockchain = Blockchain() sender = generate_key() receiver = generate_key() miner_key = generate_key() # This is an empty blockchain so create value out of thin air. miner = Miner(blockchain) miner.reward_addr = sender.publickey() emptyblock = miner._mine() self.assertEqual(len(emptyblock.transactions), 1) # First test with unconfirmed transactions for i in range(1, 3): wallet = Wallet(sender, blockchain) wallet.send(SEND_AMOUNT, receiver.publickey()) # Scan the blockchain for the transaction that just happened. receiver_owns = blockchain.scan_unspent_transactions( receiver.publickey()) value_received = sum( map(lambda x: x.get('value', 0), receiver_owns)) self.assertEqual(value_received, SEND_AMOUNT * i) sender_owns = blockchain.scan_unspent_transactions( sender.publickey()) value_owned_by_sender = sum( map(lambda x: x.get('value', 0), sender_owns)) self.assertEqual(value_owned_by_sender, SENDER_ORIG_VALUE - SEND_AMOUNT * i) # Mine the transactions miner = Miner(blockchain) miner.reward_addr = miner_key.publickey() newb = miner._mine() # Test with confirmed transactions receiver_owns = blockchain.scan_unspent_transactions( receiver.publickey()) value_received = sum(map(lambda x: x.get('value', 0), receiver_owns)) self.assertEqual(value_received, SEND_AMOUNT * 2) sender_owns = blockchain.scan_unspent_transactions(sender.publickey()) value_owned_by_sender = sum( map(lambda x: x.get('value', 0), sender_owns)) self.assertEqual(value_owned_by_sender, SENDER_ORIG_VALUE - SEND_AMOUNT * 2) # Check whether miner received the award miner_owns = blockchain.scan_unspent_transactions( miner_key.publickey()) value_owned_by_miner = sum(map(lambda x: x.get('value', 0), miner_owns)) self.assertEqual(value_owned_by_miner, MINING_REWARD) self.assertEqual(len(newb.transactions), 3)