def test_clean_new_block(self): chain = [blockchain.create_genesis_block()] for _ in range(10): new_block = blockchain.create_block(chain[-1], "Hello, this is a block") chain.append(new_block) new_block = blockchain.create_block(chain[-1], "Hello, this is a block") self.assertTrue(blockchain.verify_new_block(chain, new_block))
def test_dirty_new_block(self): chain = [blockchain.create_genesis_block()] for _ in range(10): new_block = blockchain.create_block(chain[-1], "Hello, this is a block") chain.append(new_block) chain[3].data = "Hello" new_block = blockchain.create_block(chain[-1], "Hello, this is a bad new block") self.assertFalse(blockchain.verify_new_block(chain, new_block))
def test_forks(self): node1 = TestNode() node2 = TestNode(chain=node1.chain) node1.all_nodes = node2.all_nodes = [node1, node2] # create new block for node 1 new_block = blockchain.create_block(node1.chain[-1], [blockchain.add_transaction_meta({"data": "A"})]) node1.chain.append(new_block) # create also block for node 2 # new_block = blockchain.create_block(node2.chain[-1], "B") # node2.chain.append(new_block) # test if chain is still valid self.assertTrue(blockchain.verify_chain(node1.chain)) self.assertTrue(blockchain.verify_chain(node2.chain)) # test what happens if node 2 creates his own block node2.add_transaction({"data": "B"}) node2.mine() # now we have 2 different hashes self.assertEqual(node1.chain[-1].previous_hash, node2.chain[-1].previous_hash) self.assertNotEqual(node1.chain[-1].hash, node2.chain[-1].hash) # adding transaction C and mining it in node 2 should make node 1 identical to node 2 node2.add_transaction({"data": "C"}) node2.mine() self.assertEqual(node1.chain[-1].hash, node2.chain[-1].hash) self.assertTrue(blockchain.verify_chain(node1.chain)) self.assertTrue(blockchain.verify_chain(node2.chain))
def mine_block(): previous_block = blockchain.previous_block() previous_proof = previous_block['proof'] proof = blockchain.proof_of_work(previous_proof) previous_hash = blockchain.hash(previous_block) block = blockchain.create_block(proof, previous_hash) # The sender is "0" to signify that this node has mined a new coin. blockchain.new_transaction( sender = "0", recipient = node_identifier, amount = 1 ) response = { 'message': 'Congratulations, you just mined a block!', 'index': block['index'], 'timestamp': block['timestamp'], 'proof': block['proof'], 'previous hash': block['previous_hash'], 'transaction': block['transaction'] } return jsonify(response), 200
def add_graduate(): if request.method == 'POST': key = request.form['key'] name = request.form['name'] birthday = request.form['birthday'] subject = request.form['subject'] graduation = request.form['graduation'] # Check if user input is correctedly filled in and if the key is correct. Otherwise, produce negative feedback. if len( name ) == 0 or subject == "Choose..." or birthday == "" or graduation == "" or key != "12345": feedback = "The input is invalid. Please try again." return render_template('addgraduate.html', feedback=feedback, subject=subject, color="red", name=name, birthday=birthday, graduation=graduation, key=key) # If all input fields are valid, we return a success message and call the create_block() function from # blockchain.py to add a new block to blockchain with the data provided by the user. After successfully # creating a block, we reset all input fields. feedback = "Diploma successfully added to the blockchain!" bc.create_block(name=name, birthday=birthday, subject=subject, graduation=graduation, key=key) return render_template('addgraduate.html', feedback=feedback, subject="Choose...", color="green", name="", birthday="", graduation="", key="") return render_template('addgraduate.html', subject="Choose...", color="green", name="", birthday="", graduation="", key="")
def test_dirty_block(self): chain = [blockchain.create_genesis_block()] for _ in range(10): new_block = blockchain.create_block(chain[-1], "Hello, this is a block") chain.append(new_block) chain[3].data = "Tampered data" self.assertFalse(blockchain.verify_chain(chain))
def mine(self): if len(self.transactions) == 0: return None # solve for proof of work answer = solve_proof_of_work(self.chain[-1]) # get a copy of the transactions and flush the buffer with self.trans_lock: transactions = self.transactions.copy() self.transactions = [] # remove existing transactions with self.chain_lock: existing_transactions_id_list = [] for b in self.chain: if b.data is not None: for t in b.data: existing_transactions_id_list.append(t["id"]) valid_transactions = [] for t in transactions: if t["id"] not in existing_transactions_id_list: valid_transactions.append(t) transactions = valid_transactions # sort transactions transactions.sort(key=lambda i: i["time"]) # do not continue if there are no transactions if len(transactions) == 0: return # create new block new_block = create_block(self.chain[-1], transactions, proof_of_work=answer) # validate and add new block self.chain_lock.acquire() if is_new_block_valid(self.chain, new_block): self.chain.append(new_block) self.chain_lock.release() self.broadcast_new_block(new_block) else: self.chain_lock.release()
def mine_block(): previous_block = blockchain.get_previous_block() previous_proof = previous_block['proof'] proof = blockchain.proof_of_work(previous_proof) previous_hash = blockchain.hash(previous_block) # Transactions from newly mined block blockchain.add_transaction(sender=blockchain.node_url, receiver='Sab', amount=1) # Create Block for work done block = blockchain.create_block(proof, previous_hash) response = { 'message': 'Block mined!', 'index': block['index'], 'timestamp': block['timestamp'], 'proof': block['proof'], 'previous_hash': block['previous_hash'], 'transactions': block['transactions'] } return jsonify(response), 200
def add_data(self, attributes): data, sender, receiver, validator = dict(zip(self.fields, attributes)) bc.add_block(bc.create_block(data, sender, receiver, validator))