Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0fdb646e39 |
@@ -1,12 +1,11 @@
|
||||
#!/usr/bin/env python
|
||||
"""Flask server to serve the block API."""
|
||||
|
||||
import json
|
||||
from time import time
|
||||
import argparse
|
||||
from uuid import uuid4
|
||||
from flask import Flask, request
|
||||
import json
|
||||
from uuid import uuid4
|
||||
from blockchain import Blockchain, Transaction, Block
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description="A blockchain simulation")
|
||||
parser.add_argument("-p", "--port", type=int, help="Port number", default=80)
|
||||
@@ -16,19 +15,18 @@ port = args.port
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
NODE_IDENTIFIER = str(uuid4()).replace("-", "")
|
||||
node_identifier = str(uuid4()).replace("-", "")
|
||||
|
||||
blockchain = Blockchain()
|
||||
|
||||
|
||||
@app.route("/mine", methods=["GET"])
|
||||
def mine():
|
||||
"""Mine Samycoin."""
|
||||
last_block = blockchain.blocks[-1]
|
||||
last_proof = last_block.proof
|
||||
proof = blockchain.proof_of_work(last_proof)
|
||||
|
||||
transaction = Transaction("Network", NODE_IDENTIFIER, 50)
|
||||
transaction = Transaction("Network", node_identifier, 50)
|
||||
blockchain.new_transaction(transaction)
|
||||
block = Block(
|
||||
len(blockchain.blocks) + 1,
|
||||
@@ -44,7 +42,6 @@ def mine():
|
||||
|
||||
@app.route("/transactions/new", methods=["POST"])
|
||||
def new_transaction():
|
||||
"""Submit a new transaction."""
|
||||
values = request.get_json()
|
||||
transaction = Transaction(values["sender"], values["recipient"], values["amount"])
|
||||
blockchain.new_transaction(transaction)
|
||||
@@ -54,29 +51,27 @@ def new_transaction():
|
||||
|
||||
@app.route("/chain", methods=["GET"])
|
||||
def chain():
|
||||
"""Display the block chain."""
|
||||
return json.dumps([b.__dict__ for b in blockchain.blocks])
|
||||
|
||||
|
||||
@app.route("/nodes", methods=["GET"])
|
||||
def nodes():
|
||||
"""List known nodes."""
|
||||
return json.dumps(list(blockchain.nodes))
|
||||
|
||||
|
||||
@app.route("/register", methods=["POST"])
|
||||
def register_nodes():
|
||||
"""Register a new node."""
|
||||
json_values = request.get_json()
|
||||
for node in json_values["nodes"]:
|
||||
values = request.get_json()
|
||||
nodes = values["nodes"]
|
||||
|
||||
for node in nodes:
|
||||
blockchain.register_node(node)
|
||||
|
||||
return "New node has been added\n"
|
||||
|
||||
|
||||
@app.route("/resolve", methods=["GET"])
|
||||
def resolve():
|
||||
"""Resolve the blockchain."""
|
||||
def consensus():
|
||||
replaced = blockchain.resolve_conflicts()
|
||||
|
||||
if replaced:
|
||||
|
||||
+1
-15
@@ -3,14 +3,13 @@
|
||||
import hashlib
|
||||
from time import time
|
||||
import json
|
||||
from urllib.parse import urlparse
|
||||
import requests
|
||||
from urllib.parse import urlparse
|
||||
|
||||
DIFFICULTY = 4
|
||||
|
||||
|
||||
class Block:
|
||||
"""Block of the blockkchain."""
|
||||
def __init__(self, index, timestamp, transactions, previous_hash, proof):
|
||||
self.index = index
|
||||
self.timestamp = timestamp
|
||||
@@ -20,7 +19,6 @@ class Block:
|
||||
self.hash = self.hash()
|
||||
|
||||
def hash(self):
|
||||
"""Hash the block using sha256."""
|
||||
data = self.__dict__
|
||||
data["transactions"] = [t.__dict__ for t in self.transactions]
|
||||
block_string = json.dumps(data, sort_keys=True).encode()
|
||||
@@ -31,7 +29,6 @@ class Block:
|
||||
|
||||
|
||||
class Transaction:
|
||||
"""Transaction class."""
|
||||
def __init__(self, sender, recipient, amount):
|
||||
self.sender = sender
|
||||
self.recipient = recipient
|
||||
@@ -42,7 +39,6 @@ class Transaction:
|
||||
|
||||
|
||||
class Blockchain:
|
||||
"""Blockchain class."""
|
||||
def __init__(self):
|
||||
self.blocks = []
|
||||
self.blocks.append(self.create_first_block())
|
||||
@@ -50,25 +46,20 @@ class Blockchain:
|
||||
self.nodes = set()
|
||||
|
||||
def register_node(self, address):
|
||||
"""Register a new node."""
|
||||
parsed_url = urlparse(address).netloc
|
||||
self.nodes.add(parsed_url)
|
||||
|
||||
def create_first_block(self):
|
||||
"""create the initial block."""
|
||||
return Block(1, time(), [], 1, 100)
|
||||
|
||||
def new_transaction(self, transaction):
|
||||
"""Add a new transaction."""
|
||||
self.transactions.append(transaction)
|
||||
|
||||
def new_block(self, block):
|
||||
"""Add a new block."""
|
||||
self.transactions = []
|
||||
self.blocks.append(block)
|
||||
|
||||
def proof_of_work(self, last_proof):
|
||||
"""Computes the proof."""
|
||||
proof = 0
|
||||
while not self.valid_proof(proof, last_proof):
|
||||
proof += 1
|
||||
@@ -76,13 +67,11 @@ class Blockchain:
|
||||
|
||||
@staticmethod
|
||||
def valid_proof(proof, last_proof):
|
||||
"""Tests proof."""
|
||||
guess = f"{last_proof}{proof}".encode()
|
||||
guess_hash = hashlib.sha256(guess).hexdigest()
|
||||
return guess_hash[:DIFFICULTY] == "0" * DIFFICULTY
|
||||
|
||||
def valid_chain(self, chain):
|
||||
"""Tests the validity of a chain."""
|
||||
last_block = chain[0]
|
||||
current_index = 1
|
||||
|
||||
@@ -101,7 +90,6 @@ class Blockchain:
|
||||
return True
|
||||
|
||||
def json_to_transactions(self, transactions_json):
|
||||
"""Converts json to a list of transactions."""
|
||||
transactions = [
|
||||
Transaction(
|
||||
transaction["sender"],
|
||||
@@ -114,7 +102,6 @@ class Blockchain:
|
||||
return transactions
|
||||
|
||||
def json_to_chain(self, chain_json):
|
||||
"""Convert json to a chain."""
|
||||
chain = [
|
||||
Block(
|
||||
block["index"],
|
||||
@@ -129,7 +116,6 @@ class Blockchain:
|
||||
return chain
|
||||
|
||||
def resolve_conflicts(self):
|
||||
"""Resolve conflicts using the consensus algorithm."""
|
||||
neighbours = self.nodes
|
||||
new_chain = None
|
||||
max_lengh = len(self.blocks)
|
||||
|
||||
+18
-1
@@ -1,2 +1,19 @@
|
||||
Flask==2.0.2
|
||||
#
|
||||
# These requirements were autogenerated by pipenv
|
||||
# To regenerate from the project's Pipfile, run:
|
||||
#
|
||||
# pipenv lock --requirements
|
||||
#
|
||||
|
||||
-i https://pypi.org/simple
|
||||
certifi==2021.10.8
|
||||
charset-normalizer==2.0.12; python_version >= '3'
|
||||
click==8.0.4; python_version >= '3.6'
|
||||
flask==2.0.2
|
||||
idna==3.3; python_version >= '3'
|
||||
itsdangerous==2.1.0; python_version >= '3.7'
|
||||
jinja2==3.0.3; python_version >= '3.6'
|
||||
markupsafe==2.1.0; python_version >= '3.7'
|
||||
requests==2.27.1
|
||||
urllib3==1.26.8; python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'
|
||||
werkzeug==2.0.3; python_version >= '3.6'
|
||||
|
||||
Reference in New Issue
Block a user