Merge pull request #9 from massa142/master

Add type hints
This commit is contained in:
Daniel van Flymen 2017-10-14 16:26:52 -04:00 committed by GitHub
commit f03d28f8ad
1 changed files with 27 additions and 31 deletions

View File

@ -1,6 +1,7 @@
import hashlib import hashlib
import json import json
from time import time from time import time
from typing import Any, Dict, List, Optional
from urllib.parse import urlparse from urllib.parse import urlparse
from uuid import uuid4 from uuid import uuid4
@ -8,32 +9,31 @@ import requests
from flask import Flask, jsonify, request from flask import Flask, jsonify, request
class Blockchain(object): class Blockchain:
def __init__(self): def __init__(self):
self.current_transactions = [] self.current_transactions = []
self.chain = [] self.chain = []
self.nodes = set() self.nodes = set()
# Create the genesis block # Create the genesis block
self.new_block(previous_hash=1, proof=100) self.new_block(previous_hash='1', proof=100)
def register_node(self, address): def register_node(self, address: str) -> None:
""" """
Add a new node to the list of nodes Add a new node to the list of nodes
:param address: <str> Address of node. Eg. 'http://192.168.0.5:5000' :param address: Address of node. Eg. 'http://192.168.0.5:5000'
:return: None
""" """
parsed_url = urlparse(address) parsed_url = urlparse(address)
self.nodes.add(parsed_url.netloc) self.nodes.add(parsed_url.netloc)
def valid_chain(self, chain): def valid_chain(self, chain: List[Dict[str, Any]]) -> bool:
""" """
Determine if a given blockchain is valid Determine if a given blockchain is valid
:param chain: <list> A blockchain :param chain: A blockchain
:return: <bool> True if valid, False if not :return: True if valid, False if not
""" """
last_block = chain[0] last_block = chain[0]
@ -57,12 +57,12 @@ class Blockchain(object):
return True return True
def resolve_conflicts(self): def resolve_conflicts(self) -> bool:
""" """
This is our consensus algorithm, it resolves conflicts This is our consensus algorithm, it resolves conflicts
by replacing our chain with the longest one in the network. by replacing our chain with the longest one in the network.
:return: <bool> True if our chain was replaced, False if not :return: True if our chain was replaced, False if not
""" """
neighbours = self.nodes neighbours = self.nodes
@ -91,13 +91,13 @@ class Blockchain(object):
return False return False
def new_block(self, proof, previous_hash=None): def new_block(self, proof: int, previous_hash: Optional[str]) -> Dict[str, Any]:
""" """
Create a new Block in the Blockchain Create a new Block in the Blockchain
:param proof: <int> The proof given by the Proof of Work algorithm :param proof: The proof given by the Proof of Work algorithm
:param previous_hash: (Optional) <str> Hash of previous Block :param previous_hash: Hash of previous Block
:return: <dict> New Block :return: New Block
""" """
block = { block = {
@ -114,14 +114,14 @@ class Blockchain(object):
self.chain.append(block) self.chain.append(block)
return block return block
def new_transaction(self, sender, recipient, amount): def new_transaction(self, sender: str, recipient: str, amount: int) -> int:
""" """
Creates a new transaction to go into the next mined Block Creates a new transaction to go into the next mined Block
:param sender: <str> Address of the Sender :param sender: Address of the Sender
:param recipient: <str> Address of the Recipient :param recipient: Address of the Recipient
:param amount: <int> Amount :param amount: Amount
:return: <int> The index of the Block that will hold this transaction :return: The index of the Block that will hold this transaction
""" """
self.current_transactions.append({ self.current_transactions.append({
'sender': sender, 'sender': sender,
@ -132,30 +132,26 @@ class Blockchain(object):
return self.last_block['index'] + 1 return self.last_block['index'] + 1
@property @property
def last_block(self): def last_block(self) -> Dict[str: Any]:
return self.chain[-1] return self.chain[-1]
@staticmethod @staticmethod
def hash(block): def hash(block: Dict[str, Any]) -> str:
""" """
Creates a SHA-256 hash of a Block Creates a SHA-256 hash of a Block
:param block: <dict> Block :param block: Block
:return: <str>
""" """
# We must make sure that the Dictionary is Ordered, or we'll have inconsistent hashes # We must make sure that the Dictionary is Ordered, or we'll have inconsistent hashes
block_string = json.dumps(block, sort_keys=True).encode() block_string = json.dumps(block, sort_keys=True).encode()
return hashlib.sha256(block_string).hexdigest() return hashlib.sha256(block_string).hexdigest()
def proof_of_work(self, last_proof): def proof_of_work(self, last_proof: int) -> int:
""" """
Simple Proof of Work Algorithm: Simple Proof of Work Algorithm:
- Find a number p' such that hash(pp') contains leading 4 zeroes, where p is the previous p' - Find a number p' such that hash(pp') contains leading 4 zeroes, where p is the previous p'
- p is the previous proof, and p' is the new proof - p is the previous proof, and p' is the new proof
:param last_proof: <int>
:return: <int>
""" """
proof = 0 proof = 0
@ -165,13 +161,13 @@ class Blockchain(object):
return proof return proof
@staticmethod @staticmethod
def valid_proof(last_proof, proof): def valid_proof(last_proof: int, proof: int) -> bool:
""" """
Validates the Proof Validates the Proof
:param last_proof: <int> Previous Proof :param last_proof: Previous Proof
:param proof: <int> Current Proof :param proof: Current Proof
:return: <bool> True if correct, False if not. :return: True if correct, False if not.
""" """
guess = f'{last_proof}{proof}'.encode() guess = f'{last_proof}{proof}'.encode()