def getBlockchain(my_peers): block_num = 0 peer = 'https://iitkbucks.pclub.in' r = requests.get(peer + '/getBlock/0') #print(r.content) #block0 = open('block0', 'rb').read() genesis_block = block() genesis_block.from_bytes(r.content) #genesis_block.from_bytes(block0) my_Blockchain = Blockchain(my_peers) my_Blockchain.block_reward = genesis_block.transactions[0].outputs[0].amount flag = my_Blockchain.addBlock(genesis_block) block_num += 1 flag = True while flag: #peer = random.choice(my_peers) r = requests.get(peer + '/getBlock/' + str(block_num)) if r.status_code == 200: nblock = block() nblock.from_bytes(r.content) flag = my_Blockchain.addBlock(nblock) if flag == 0: flag = True block_num += 1 else: flag = False return my_Blockchain
def setUp(self): self.blockchain = Blockchain() self.buffer = Buffer(self.blockchain) self.buffer.add('1 transaction') self.buffer.generate_block() self.buffer.add('2 transaction') self.buffer.generate_block() self.buffer.add('3 transaction') self.buffer.generate_block() self.blockchain.save_chain()
def get(self): idx = int(request.args.get('idx')) with self.node.resolve_lock: blockchain = Blockchain( self.node.blockchain.block_list[idx:]).to_dict()['block_list'] return json.dumps({'blockchain': blockchain}), 200
def Worker(Blockchain, queueflag): print('\nSTARTED WORKER THREAD!') PUBLICKEY = open('my_pk.pem', 'rb').read() while True: while not len(Blockchain.PendingTxns._list_) > 0: time.sleep(5) print('\nWaiting......') #Blockchain.PendingTxns.get(Blockchain.peers, Blockchain.unused_outputs) #Blockchain.PendingTxns.sort(Blockchain.unused_outputs) accumulator = bytes() BlockFees = 0 num_txns = 1 unused_outputs = copy.deepcopy(Blockchain.unused_outputs) flag = True for i, txn in enumerate(Blockchain.PendingTxns._list_): flag, unused_outputs = txn.VerifyTxn(unused_outputs) if flag: accumulator += (txn.size + txn._bytes_) if not len(accumulator) < 10**6 - 520: accumulator -= (txn.size + txn._bytes_) break else: BlockFees += txn.getTxnFees(Blockchain.unused_outputs) num_txns += 1 coinbase_output = Output(BlockFees + Blockchain.block_reward, PUBLICKEY) coinbase = Tx() coinbase.newTxn([], [coinbase_output]) body = num_txns.to_bytes( 4, 'big') + coinbase.size + coinbase._bytes_ + accumulator my_block = block() my_block.new(Blockchain, body) flag = my_block.mine(queueflag) if flag: Blockchain.addBlock(my_block) else: return False
def inform_bootstrap(self): url = 'http://' + self.bootstrap_ip + ':' + self.bootstrap_port + '/hello_bootstrap' while True: try: response = r.post(url, data={'node': json.dumps(self.node_dict)}) code = response.status_code except r.exceptions.RequestException as e: print(e) code = 404 if code != 404: break else: sleep(3) if response.status_code != 200: print('Bootstrap says: "' + json.loads(response.json())['msg'] + '"') exit() else: response = json.loads(response.json()) self.id = response['id'] self.blockchain = Blockchain(response['blockchain']['block_list']) self.node_dict['utxos'] = OrderedDict(response['utxos']) print("I am in with id " + str(self.id)) valid, msg = self.blockchain.validate(self.difficulty) if not valid: print(msg) exit() while True: try: response = r.get('http://' + self.bootstrap_ip + ':' + self.bootstrap_port + '/broadcast_ring', params={'idx': self.id}) code = response.status_code except r.exceptions.RequestException as e: print(e) code = 401 sleep(3) if code == 200: break if self.transactions: self.start_transactions()
def connect(): global node if (not node): print(request.host) port = request.host.split(':', 1)[1] print(port) if (port == BOOTSTRAP_PORT): node = Node(HOST, port, index=0) node.wallet = node.create_wallet() node.NBCs.append({ 'id': '0', 'recipient_address': node.wallet.public_key, 'amount': NUM_OF_NODES * 100 }) node.ring.append({ 'id': node.index, 'port': port, 'public_key': node.wallet.public_key }) print("Bootstrap node successfully added!") print("My id: " + str(node.index)) else: node = Node(HOST, port) node.wallet = node.create_wallet() response = requests.get("http://" + HOST + ":" + BOOTSTRAP_PORT + "/init_node?port=" + port + "&public_key=" + node.wallet.public_key) if (response.status_code == 200): nid = response.json()['id'] node.index = int(nid) blockchain_json = response.json()['blockchain'] node.chain = Blockchain( node.index, blockchain_json['unconfirmed_transactions'], blockchain_json['chain']) response = requests.post("http://" + HOST + ":" + BOOTSTRAP_PORT + "/first_transaction?id=" + str(nid)) if (response.status_code == 200): output = response.json()['output'] node.NBCs.append(output) print("Median node added successfully!") if (node.index == NUM_OF_NODES - 1): print("Oops! It was the last one!") response = requests.post("http://" + HOST + ":" + BOOTSTRAP_PORT + "/nodes_ready") #for node in other_nodes: #node.ring=bootstrap_node.ring return "Node Added! Your port is: " + port, 201 else: return "Homepage!", 200
def resolve_conflicts(self): success, conflict_data = self.broadcast(data={}, endpoint='/resolve_conflict') if success: conflict_data.sort(key=lambda x: x[0], reverse=True) for length, hashchain, node_index in conflict_data: if length <= self.blockchain.length(): break idx = self.blockchain.index_of_fork(hashchain) try: response = r.get('http://' + self.ring[node_index]['ip'] + ':' + self.ring[node_index]['port'] + '/resolve_conflict', params={'idx': idx}) except r.exceptions.RequestException as e: continue rest_of_the_blockchain = json.loads( response.json())['blockchain'] blockchain = Blockchain(self.blockchain.block_list[:idx] + rest_of_the_blockchain, update_time=False) if blockchain.validate(self.difficulty)[0]: if self.mining_thread and self.mining_thread.is_alive(): self.mining_thread.hash_found.set() with self.resolve_lock: old_txs = self.blockchain.all_transactions(idx) new_txs = self.blockchain.all_transactions() self.blockchain = blockchain with self.utxo_lock: with self.tx_pool_lock: self.ring = self.resolve_tx(old_txs=old_txs, new_txs=new_txs, resolve=True)[1] return 200, ", node " + str( node_index) + " gave me the correct blockchain" return 200, ", but it was just a false alarm, I have the largest valid blockchain" else: return 400, ", I couldn't ask all nodes to resolve the conflict"
def __init__(self, ip, port, index=None, chain=None): self.index = index if (index == 0): self.chain = Blockchain(index) self.current_id_count = self.index + 1 else: self.chain = chain self.NBCs = [] self.ip = ip self.port = port self.wallet = None self.ring = []
class TestIntegrity(TestCase): def setUp(self): self.blockchain = Blockchain() self.buffer = Buffer(self.blockchain) self.buffer.add('1 transaction') self.buffer.generate_block() self.buffer.add('2 transaction') self.buffer.generate_block() self.buffer.add('3 transaction') self.buffer.generate_block() self.blockchain.save_chain() # fixme - this test overwrites blockchain.txt def test_edit_one_block(self): self.blockchain._blocks[1]._transactions[0] = 'aaa' self.assertEqual(self.blockchain.check_integrity(), False) self.assertEqual(self.blockchain.save_chain(), 'Inconsistent blockchain') # fixme - this test overwrites blockchain.txt def test_add_new_block(self): self.buffer.add('4 transaction') self.buffer.generate_block() self.assertEqual(self.blockchain.check_integrity(), True) self.assertEqual(self.blockchain.save_chain(), None)
from block import Blockchain, Buffer if __name__ == '__main__': blockchain = Blockchain() buffer = Buffer(blockchain) blockchain.load_chain() help_text = ''' add \t- add transaction to the buffer buf \t- show the buffer gen \t- generate block from transactions in buffer and clean buffer get \t- get the specific block stat \t- statistics for blockchain write \t- write blockchain to disk load \t- load blockchain from disk exit \t- close program''' s = '' print('Type "help" to see all options') while s != 'exit': s = input('>>> ') if s == 'help': print(help_text) if s == 'add': add_s = input('Transaction: ') buffer.add(add_s) print(f'Transaction "{add_s}" was added to the buffer.') if s == 'buf': print('TRANSACTIONS IN THE BUFFER:') buffer.show()
def i_am_bootstrap(self): self.id = 0 self.node_dict['utxos'] = OrderedDict() self.ring = OrderedDict({self.id: self.node_dict}) self.blockchain = Blockchain([self.genesis_block()])
# get global testset by train global_x_test = x_train[:num_global_testset] global_y_test = y_train[:num_global_testset] x_train = x_train[num_global_testset:] y_train = y_train[num_global_testset:] """set FL model""" flmodel = create_model(features) """set blockchain""" if preTrained == -1: file_list = os.listdir("./data/blocks") preTrained = len(file_list) - 1 genesis = readBlock("./data/blocks", 0) flchain = Blockchain(genesis) # set blockchain with genesis block for i in range(1, preTrained + 1): flblock = readBlock("./data/blocks", i) flchain.append(flblock) # append next block elif preTrained == 0: init_weights = flmodel.get_weights() genesis = Block( 0, "0" * 64, init_weights, (global_x_test, global_y_test), [], int(time.time()) ) flchain = Blockchain(genesis) # set blockchain with genesis block # writeBlockchain("./data", flchain) # save blockchain
def sessions(): global node print("Let's go!") if (not node): print(request.host) ip = request.host.split(':', 1)[0] port = request.host.split(':', 1)[1] if (ip == BOOTSTRAP_IP and port == BOOTSTRAP_PORT): node = Node(ip, port, index=0) node.wallet = node.create_wallet() node.NBCs.append({ 'id': '0', 'recipient_address': node.wallet.public_key, 'amount': NUM_OF_NODES * 100 }) node.ring.append({ 'id': node.index, 'ip': ip, 'port': port, 'public_key': node.wallet.public_key }) print("Bootstrap node successfully added!") print("My id: " + str(node.index)) else: node = Node(ip, port) node.wallet = node.create_wallet() while True: response = requests.get("http://" + BOOTSTRAP_IP + ":" + BOOTSTRAP_PORT + "/init_node?ip=" + ip + "&port=" + port + "&public_key=" + node.wallet.public_key) if response.status_code != 503: break if (response.status_code == 200): nid = response.json()['id'] node.index = int(nid) blockchain_json = response.json()['blockchain'] node.chain = Blockchain( node.index, blockchain_json['unconfirmed_transactions'], blockchain_json['chain']) if (node.valid_chain()): print("I got a valid blockchain!") else: print("My first blockchain is false :( ") while True: response = requests.post("http://" + BOOTSTRAP_IP + ":" + BOOTSTRAP_PORT + "/first_transaction?id=" + str(nid)) if response.status_code != 503: break if (response.status_code == 200): output = response.json()['output'] node.NBCs.append(output) print("Median node added successfully!") if (node.index == NUM_OF_NODES - 1): print("Oops! It was the last one!") while True: response = requests.post("http://" + BOOTSTRAP_IP + ":" + BOOTSTRAP_PORT + "/nodes_ready") if response.status_code != 503: break return render_template('homepage.html'), 200
def setUp(self): self.blockchain = Blockchain() self.buffer = Buffer(self.blockchain)
from flask import Flask from flask import request from block import Block from block import Blockchain import copy import datetime as time import json node = Flask(__name__) this_node_transactions = [] peer_nodes = [ "localhost:5000", ] mining = True this_chain = Blockchain() @node.route("/txion", methods=['POST']) def transaction(): if request.method == 'POST': new_txion = request.get_json() this_node_transactions.append(new_txion) print("New transaction") print("FROM: {}".format(new_txion['from'])) print("TO: {}".format(new_txion['to'])) print("AMOUNT: {}".format(new_txion['amount'])) return "Transction submission successful\n" miner_address = "q3nf394hjg-random-miner-address-34nf3i4nflkn3oi"
#!/usr/local/bin/python python # -*- coding: UTF-8 -*- from uuid import uuid4 from flask import Flask, jsonify, request from flask_cors import CORS from block import Blockchain # ノードを作る # Flaskについて詳しくはこちらを読んでほしい http://flask.pocoo.org/docs/0.12/quickstart/#a-minimal-application app = Flask(__name__) CORS(app, supports_credentials=True) # このノードのグローバルにユニークなアドレスを作る node_identifire = str(uuid4()).replace('-', '') # ブロックチェーンクラスをインスタンス化する blockchain = Blockchain() # メソッドはGETで/mineエンドポイントを作る @app.route('/mine', methods=['GET']) def mine(): # 次のプルーフを見つけるためプルーフ・オブ・ワークアルゴリズムを使用する last_block = blockchain.last_block last_proof = last_block['proof'] proof = blockchain.proof_of_work(last_proof) # プルーフを見つけたことに対する報酬を得る # 送信者は、採掘者が新しいコインを採掘したことを表すために"0"とする blockchain.new_transaction( sender="0", recipient=node_identifire, amount=1,
class Node: def __init__(self, ip, port, is_bootstrap, max_nodes, NBC, capacity, difficulty, bootstrap_ip, bootstrap_port, transactions): self.ip = ip self.port = port self.bootstrap = is_bootstrap self.max_nodes = max_nodes self.NBC = NBC self.capacity = capacity self.difficulty = difficulty self.bootstrap_ip = bootstrap_ip self.bootstrap_port = bootstrap_port self.transactions = transactions self.ring = {} self.wallet = Wallet() self.tx_pool = [] self.node_dict = { 'ip': self.ip, 'port': self.port, 'address': self.wallet.address, 'ready': False } self.mining_thread = None self.utxo_lock = Lock() self.tx_pool_lock = Lock() self.chain_lock = Lock() self.resolve_lock = Lock() if self.bootstrap: self.i_am_bootstrap() else: t = Thread(target=self.inform_bootstrap) t.start() def i_am_bootstrap(self): self.id = 0 self.node_dict['utxos'] = OrderedDict() self.ring = OrderedDict({self.id: self.node_dict}) self.blockchain = Blockchain([self.genesis_block()]) def genesis_block(self): amount = self.NBC * self.max_nodes transactions = [ Transaction(sender_address='0', sender_private_key=None, receiver_address=self.wallet.address, amount=amount, ring=self.ring).to_dict() ] return Block(idx=0, transactions=transactions, previous_hash='1', nonce='0') def inform_bootstrap(self): url = 'http://' + self.bootstrap_ip + ':' + self.bootstrap_port + '/hello_bootstrap' while True: try: response = r.post(url, data={'node': json.dumps(self.node_dict)}) code = response.status_code except r.exceptions.RequestException as e: print(e) code = 404 if code != 404: break else: sleep(3) if response.status_code != 200: print('Bootstrap says: "' + json.loads(response.json())['msg'] + '"') exit() else: response = json.loads(response.json()) self.id = response['id'] self.blockchain = Blockchain(response['blockchain']['block_list']) self.node_dict['utxos'] = OrderedDict(response['utxos']) print("I am in with id " + str(self.id)) valid, msg = self.blockchain.validate(self.difficulty) if not valid: print(msg) exit() while True: try: response = r.get('http://' + self.bootstrap_ip + ':' + self.bootstrap_port + '/broadcast_ring', params={'idx': self.id}) code = response.status_code except r.exceptions.RequestException as e: print(e) code = 401 sleep(3) if code == 200: break if self.transactions: self.start_transactions() def node_already_exists(self, new_node): msg = None for node in self.ring.values(): if new_node['ip'] == node['ip'] and new_node['port'] == node[ 'port']: msg = "You are already in with another wallet" if new_node['address'] == node['address']: msg = "I already have your wallet's address" return msg def register_node_to_ring(self, node_dict): if not self.bootstrap: return 400, "I am sorry, bootstrap is not here", None, None, None if self.max_nodes == len(self.ring): return 400, "Sorry we are full, " + str( self.max_nodes) + " nodes at a time", None, None, None msg = self.node_already_exists(node_dict) if msg: return 400, msg, None, None, None idx = len(self.ring) node_dict['utxos'] = OrderedDict() self.ring[idx] = node_dict success, error = self.create_transaction(node_dict['address'], self.NBC) if not success: return 400, error, None, None, None else: return 200, "OK", idx, self.blockchain.to_dict( ), self.ring[idx]['utxos'] def broadcast(self, data, endpoint): node_list = [ node for node_id, node in self.ring.items() if node_id != self.id and node['ready'] ] num_of_nodes = len(node_list) if num_of_nodes == 0: return True, [] url_list = [ 'http://' + node['ip'] + ':' + node['port'] + endpoint for node in node_list ] data_list = [data] * num_of_nodes p = Pool(num_of_nodes) try: successes, msg_list = list( zip(*p.starmap(send_stuff, zip(url_list, data_list)))) p.close() p.join() except r.exceptions.RequestException as e: print(e) p.close() p.join() exit() successful = sum(successes) == num_of_nodes return successful, list(msg_list) def broadcast_ring(self): while len([node for node in self.ring.values() if node['ready'] ]) != self.max_nodes - 1: print("Waiting for all nodes to get in") sleep(3) ring = self.ring.copy() ring[0]['ready'] = True success, msg_list = self.broadcast(data={'ring': json.dumps(ring)}, endpoint='/broadcast_ring') if not success: print("Failed broadcasting ring") exit() else: print("All nodes are informed, let\'s start") if self.transactions: t = Thread(target=self.start_transactions) t.start() self.ring[0]['ready'] = True def broadcast_transaction(self, tx_dict): success, msg_list = self.broadcast(data={'tx': json.dumps(tx_dict)}, endpoint='/validate_transaction') if success: msg = ("All nodes know about transaction now") else: msg = "Failed broadcasting transaction" for m in msg_list: print(m) return success, msg def broadcast_block(self, block_dict): success, msg_list = self.broadcast( data={'block': json.dumps(block_dict)}, endpoint='/validate_block') if success: msg = ("All nodes know about block " + str(block_dict['idx']) + " now") else: msg = "Failed broadcasting block" for m in msg_list: print(m) return success, msg def start_transactions(self): filename = os.path.join('transactions', str(self.max_nodes) + 'nodes', 'transactions' + str(self.id) + '.txt') with open(filename, 'r') as tx_file: txs = tx_file.readlines() start_time = time() successes = [] for tx in txs: recipient = self.ring[int(tx.split()[0].strip('id'))]['address'] amount = int(tx.split()[1]) success, msg = self.create_transaction(recipient, amount) print(msg) successes.append(success) sful = sum(successes) end_time = time() dirname = os.path.join('results', str(self.max_nodes) + 'nodes') Path(dirname).mkdir(parents=True, exist_ok=True) filename = os.path.join( dirname, 'tx_' + str(self.id) + '_' + str(self.capacity) + '_' + str(self.difficulty) + '.txt') with open(filename, 'w') as file: file.write( str(sful) + ' Transactions in ' + str(end_time - start_time) + ' seconds, ' + str(len(txs) - sful) + ' failed\n') def create_transaction(self, recipient, amount): try: self.utxo_lock.acquire() tx_dict = Transaction(sender_address=self.wallet.address, sender_private_key=self.wallet.private_key, receiver_address=recipient, amount=amount, ring=self.ring).to_dict() except ValueError as e: self.utxo_lock.release() return False, str(e) self.utxo_lock.release() s, m = self.broadcast_transaction(tx_dict) self.add_transaction_to_pool(tx_dict) return s, m def add_transaction_to_pool(self, tx_dict): with self.tx_pool_lock: if tx_dict not in self.tx_pool + self.blockchain.all_transactions( ): self.tx_pool.append(tx_dict) poolsize = len(self.tx_pool) transactions = self.tx_pool[:self.capacity] if poolsize >= self.capacity: if (not self.mining_thread or not self.mining_thread.is_alive()) and self.ring: self.create_new_block(transactions) def create_new_block(self, transactions): with self.chain_lock: next_index = self.blockchain.next_index() last_hash = self.blockchain.last_hash() if [ tx for tx in transactions if tx in self.blockchain.all_transactions() ]: return block = Block(idx=next_index, transactions=transactions, previous_hash=last_hash) self.mining_thread = Mining(node=self, block=block) self.mining_thread.start() return def validate_transaction(self, tx_dict): try: self.utxo_lock.acquire() tx = Transaction(sender_address=tx_dict['sender_address'], sender_private_key=None, receiver_address=tx_dict['receiver_address'], amount=tx_dict['amount'], ring=self.ring, signature=tx_dict['signature'], inputs=tx_dict['inputs'], outputs=tx_dict['outputs'], tx_id=tx_dict['transaction_id']) except ValueError as e: self.utxo_lock.release() return 400, str(e) self.utxo_lock.release() self.add_transaction_to_pool(tx_dict) return 200, "Transaction validated" def validate_block(self, block_dict): block = Block(idx=block_dict['idx'], transactions=block_dict['transactions'], previous_hash=block_dict['prev_hash'], nonce=block_dict['nonce'], hash_=block_dict['hash'], timestamp=block_dict['timestamp'], start_time=block_dict['start_time']) if not hasattr(self, 'blockchain'): return 200, "I just came here, what are you expecting me to say?" self.chain_lock.acquire() valid, msg = block.validate(self.difficulty, self.blockchain.last_hash()) if valid: # if self.ring: # with self.utxo_lock: # with self.tx_pool_lock: # if not self.resolve_tx(new_txs=block.transactions)[0]: # self.chain_lock.release() # return 400, "Block contains invalid transactions" with self.tx_pool_lock: self.tx_pool = [ tx for tx in self.tx_pool if not tx in block_dict['transactions'] ] if self.mining_thread and self.mining_thread.is_alive(): self.mining_thread.hash_found.set() self.blockchain.add_block(block) self.chain_lock.release() return 200, msg elif "Previous hash does not match" in msg: if block in self.blockchain.block_list: self.chain_lock.release() return 200, msg + ", but I already have this block" code, resolve_msg = self.resolve_conflicts() self.chain_lock.release() return code, msg + resolve_msg else: self.chain_lock.release() return 400, msg def resolve_conflicts(self): success, conflict_data = self.broadcast(data={}, endpoint='/resolve_conflict') if success: conflict_data.sort(key=lambda x: x[0], reverse=True) for length, hashchain, node_index in conflict_data: if length <= self.blockchain.length(): break idx = self.blockchain.index_of_fork(hashchain) try: response = r.get('http://' + self.ring[node_index]['ip'] + ':' + self.ring[node_index]['port'] + '/resolve_conflict', params={'idx': idx}) except r.exceptions.RequestException as e: continue rest_of_the_blockchain = json.loads( response.json())['blockchain'] blockchain = Blockchain(self.blockchain.block_list[:idx] + rest_of_the_blockchain, update_time=False) if blockchain.validate(self.difficulty)[0]: if self.mining_thread and self.mining_thread.is_alive(): self.mining_thread.hash_found.set() with self.resolve_lock: old_txs = self.blockchain.all_transactions(idx) new_txs = self.blockchain.all_transactions() self.blockchain = blockchain with self.utxo_lock: with self.tx_pool_lock: self.ring = self.resolve_tx(old_txs=old_txs, new_txs=new_txs, resolve=True)[1] return 200, ", node " + str( node_index) + " gave me the correct blockchain" return 200, ", but it was just a false alarm, I have the largest valid blockchain" else: return 400, ", I couldn't ask all nodes to resolve the conflict" def resolve_tx(self, old_txs=[], new_txs=[], resolve=False): self.tx_pool = [tx for tx in self.tx_pool if not tx in new_txs] old_txs = [tx for tx in old_txs if not tx in new_txs] # self.tx_pool = old_txs + self.tx_pool temp_ring = deepcopy(self.ring) for node_dict in temp_ring.values(): node_dict['utxos'] = OrderedDict() f = lambda tx: tx if isinstance(tx, dict) else tx.to_dict() transactions = [ f(tx) for block in self.blockchain.block_list for tx in block.transactions ] address_dict = {v['address']: int(k) for k, v in self.ring.items()} if resolve: transactions = transactions + self.tx_pool for tx in transactions: inputs = tx['inputs'] outputs = tx['outputs'] for out_id, tx_out in outputs.items(): receiver = temp_ring[address_dict[tx_out['recipient']]] receiver['utxos'][out_id] = tx_out if tx['signature'] == "genesis": continue sender = temp_ring[address_dict[tx['sender_address']]] for tx_in in inputs: if tx_in in sender['utxos']: del sender['utxos'][tx_in] else: return False, self.ring return True, temp_ring def write_block_times(self): avg, blocks = self.blockchain.block_time() dirname = os.path.join('results', str(self.max_nodes) + 'nodes') Path(dirname).mkdir(parents=True, exist_ok=True) filename = os.path.join( dirname, 'block_' + str(self.id) + '_' + str(self.capacity) + '_' + str(self.difficulty) + '.txt') with open(filename, 'w') as file: file.write('Average block time is ' + str(avg) + ' seconds, for ' + str(blocks) + 'blocks\n') def wallet_balance(self): with self.utxo_lock: balance = sum(utxo['amount'] for utxo in self.ring[self.id]['utxos'].values()) return balance def view_transactions(self): with self.chain_lock: last = self.blockchain.last_transactions() return last