---
# System prepended metadata

title: STL 2 Assignment 8

---

# 3

![](https://hackmd.io/_uploads/HkHJvbdq2.png)
![](https://hackmd.io/_uploads/rkR7PW_5h.png)
![](https://hackmd.io/_uploads/S1tHwZ_52.png)

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
![](https://hackmd.io/_uploads/B1BduZesh.png)

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

![](https://hackmd.io/_uploads/SJYziZlj3.png)
![](https://hackmd.io/_uploads/Sy91n-ej3.png)

- 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). 
![](https://hackmd.io/_uploads/Sye132ein.png)

![](https://hackmd.io/_uploads/ryBIp3ejn.png)

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.

![](https://hackmd.io/_uploads/ByHkjolj2.png)


# 5

![](https://hackmd.io/_uploads/ry4ROZd53.png)
![](https://hackmd.io/_uploads/Bk7ktW_cn.png)
![](https://hackmd.io/_uploads/SyHgtW_c2.png)


`{"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"`.

![](https://hackmd.io/_uploads/rJwsPRgsn.png)
![](https://hackmd.io/_uploads/BJOy_0eo3.png)

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
```




![](https://hackmd.io/_uploads/r130CJZsh.png)

![](https://hackmd.io/_uploads/BkUsygbj3.png)


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
```

![](https://hackmd.io/_uploads/BJ0TuxWs3.png)
![](https://hackmd.io/_uploads/BJIrhx-sn.png)


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

![](https://hackmd.io/_uploads/BynXplWin.png)
![](https://hackmd.io/_uploads/rJaZRgZoh.png)
![](https://hackmd.io/_uploads/HkaMAl-ih.png)


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

![](https://hackmd.io/_uploads/Bygxbbbsh.png)

Node is updated automatically
![](https://hackmd.io/_uploads/ryKBbbbjh.png)

In 5001, Node is also updated
![](https://hackmd.io/_uploads/HkM_---o2.png)

Checking whether the other way has no error in synching
![](https://hackmd.io/_uploads/S1j5Z-Zoh.png)

The instances are sync'd up
![](https://hackmd.io/_uploads/rJmpW-Wsh.png)
![](https://hackmd.io/_uploads/HJhsMbZoh.png)
