Created
September 23, 2017 18:30
-
-
Save dvf/896beebf8ab0347078487fb4a0cc07a4 to your computer and use it in GitHub Desktop.
Step 5: Complete Class
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import hashlib | |
import json | |
from textwrap import dedent | |
from time import time | |
from uuid import uuid4 | |
class Blockchain(object): | |
def __init__(self): | |
self.current_transactions = [] | |
self.chain = [] | |
# Create the genesis block | |
genesis_block = self.new_block(previous_hash=1, proof=100) | |
self.chain.append(genesis_block) | |
def new_block(self, proof, previous_hash=None): | |
""" | |
Create a new Block in the Blockchain | |
:param proof: <int> The proof given by the Proof of Work algorithm | |
:param previous_hash: (Optional) <str> Hash of previous Block | |
:return: <dict> New Block | |
""" | |
block = { | |
'index': len(self.chain) + 1, | |
'timestamp': time(), | |
'transactions': self.current_transactions, | |
'proof': proof, | |
'previous_hash': previous_hash or self.chain[-1]['hash'], | |
} | |
# Calculate the hash of this new Block | |
block['hash'] = self.hash(block) | |
# Reset the current list of transactions | |
self.current_transactions = [] | |
self.chain.append(block) | |
return block | |
def new_transaction(self, sender, recipient, amount): | |
""" | |
Creates a new transaction to go into the next mined Block | |
:param sender: <str> Address of the Sender | |
:param recipient: <str> Address of the Recipient | |
:param amount: <int> Amount | |
:return: <int> The index of the Block that will hold this transaction | |
""" | |
self.current_transactions.append({ | |
'sender': sender, | |
'recipient': recipient, | |
'amount': amount, | |
}) | |
return self.last_block['index'] + 1 | |
@property | |
def last_block(self): | |
return self.chain[-1] | |
@staticmethod | |
def hash(block): | |
""" | |
Creates a SHA-256 hash of a Block | |
:param block: <dict> Block | |
:return: <str> | |
""" | |
block_string = json.dumps(block).encode() | |
return hashlib.sha256(block_string).hexdigest() | |
@staticmethod | |
def proof_of_work(last_proof): | |
""" | |
Simple Proof of Work Algorithm: | |
- 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 | |
:param last_proof: <int> | |
:return: <int> | |
""" | |
proof = 0 | |
while True: | |
guess = f'{last_proof}{proof}'.encode() | |
guess_hash = hashlib.sha256(guess).hexdigest() | |
if guess_hash[:4] == "0000": | |
break | |
proof += 1 | |
print(dedent(f''' | |
New Proof found! | |
New Proof: {proof} | |
Last Proof: {last_proof} | |
Hash: {guess_hash} | |
''')) | |
return proof |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment