# 3



What we see is that when we trigger the `mine` function, we would need to wait for the server to verify whether the mining is successful or not. When we trigger the `blockchain` functionality, we can see the latest block.
# 4
- 5 : 0.35 s

- 6 : 2 minutes 30s for the first `mine`


- 8 : More than 3 hours
Took 8 hours to laod the flask server. I don't think it's possible to mine it within a reasonable amount of time (which is less than 2 minutes).


There seem to be an exponential increase in time taken for each additional increase in complexity.
- 10 X
Can't load the flask server, therefore can't load the `mine` function.
For 10 digit complexity, the reason why it takes so long to load is because it is difficult to reach the level complexity that we desire. As it is stuck in the while loop trying to find a hash complex enough to satisfy the requirments.
Similarly, the mining function takes more than the reasonable length of time to do and as such was not able to be done within the time scope.

# 5



`{"hash_of_previous_block":"bc8a9e7776a0cd09dec9f0a8bcc5e55d7084274068063f3d8e8a803bdfc64fae","index":2,"message":"New Block Mined","nonce":83036,"transactions":[{"amount":0.5,"recipient":"cd0f75d2367ad456607647edde665d6f","sender":"9dca926ac13d4f078503bf78b9309085"},{"amount":1,"recipient":"9dca926ac13d4f078503bf78b9309085","sender":"0"}]}
`
We can see that Block 2 has now been mined and it contains two transactions, This means that the new block mined creates a transaction the for the recipient and the sender with the transaction verified by the server. We can see that in the second block it contain the details of the previous block with a mined amount of "1". When we created a transaction to send 0.5 to another receipient, this was also detailed into block 2 as a deducting amount.
# 6
To synchronise in a reasonable timeframe, the complexity is returned back to `"0000"`.


Original code does not have the synchronisation between the 2 instances. We need to add a synchronisation function.
Adding the following functions should add the synchronisation:
In the Blockchain object, we add the check for validity and longest chain.
```python=
class Blockchain():
def init():
...
self.nodes = set()
...
def valid_chain(self, chain):
'''
Check validity of the chain
'''
last_block = chain[0]
current_index = 1
while current_index < len(chain):
block = chain[current_index]
if block['hash_of_previous_block'] != self.hash_block(last_block):
return False
if not self.valid_proof(
block['index'],
block['hash_of_previous_block'],
block['transactions'],
block['nonce']):
return False
last_block = block
current_index += 1
return True
def update_blockchain(self):
'''
Update to sync chain
'''
neighbours = self.nodes
new_chain = None
max_length = len(self.chain)
# Iterate over each node and get its blockchain
for node in neighbours:
response = requests.get(f'http://{node}/blockchain')
if response.status_code == 200:
length = response.json()['length']
chain = response.json()['chain']
if length > max_length and self.valid_chain(chain):
max_length = length
new_chain = chain
if new_chain:
self.chain = new_chain
return True
return False
```


Since both have the same initial seed, both should return the same hash.
To sync, we need to add the node manually and make sure that both instances (5000 and 5001 add each other)
```python
'''
Adding sync function
'''
# Route for syncing the nodes
@app.route('/nodes/sync', methods=['GET'])
def sync():
updated = blockchain.update_blockchain()
if updated:
response = {
'message': 'The blockchain has been updated to the latest',
}
else:
response = {
'message': 'Our blockchain is the latest',
}
return jsonify(response), 200
# Route for adding new nodes to the network
@app.route('/blockchain/new_block', methods=['POST'])
def new_block():
'''
Add
'''
block = request.get_json()
index = block['index']
hash_of_previous_block = block['hash_of_previous_block']
transactions = block['transactions']
nonce = block['nonce']
if index == len(blockchain.chain) and blockchain.valid_proof(index, hash_of_previous_block, transactions, nonce):
blockchain.chain.append(block)
response = {'message': 'New block added to the blockchain'}
else:
response = {'message': 'Invalid block'}
# Route for receiving new blocks from other nodes
@app.route('/nodes/add_nodes', methods=['POST'])
def add_nodes():
'''
Add new nodes when add_node is triggered.
'''
nodes = request.get_json().get('nodes')
if nodes is None:
return "Error: Missing node(s) info", 400
for node in nodes:
parsed_url = urlparse(node)
if parsed_url.netloc:
blockchain.nodes.add(parsed_url.netloc)
response = {
'message': 'New nodes added',
'nodes': list(blockchain.nodes)
}
return jsonify(response), 201
```


Once we add both the nodes to both instances, we can test mining a block and check the chain.



As can be seen both 5001 and 5000, when triggering blockchain returns the same state of the blockchain.

Node is updated automatically

In 5001, Node is also updated

Checking whether the other way has no error in synching

The instances are sync'd up

