Author SHA1 Message Date
marc ac9d8a108b 8.84/10 2022-02-23 21:47:59 +01:00
Samy Haffoudhi ec9f0e1b36 Merge pull request #4 from MarcPartensky/dockerignore
dockerignore
2022-02-23 21:31:10 +01:00
Samy Haffoudhi f55195618f Merge pull request #3 from MarcPartensky/pipenv
pipenv
2022-02-23 21:30:23 +01:00
marc bec6a801bf dockerignore 2022-02-23 21:30:15 +01:00
marc 330e709c9a pipfile + pipfile.lock 2022-02-23 21:28:29 +01:00
Samy Haffoudhi fe8edb6a00 Merge pull request #2 from MarcPartensky/shebang
shebang
2022-02-23 21:27:19 +01:00
Samy Haffoudhi 79965a8a46 tg marc, merci 2022-02-23 21:25:42 +01:00
marc 9de5492201 shebang 2022-02-23 21:24:49 +01:00
Samy Haffoudhi 2e718c5924 Merge branch 'master' of https://github.com/samyhaff/Blockchain 2022-02-23 21:15:35 +01:00
Samy Haffoudhi f9cf1f31a5 maj script 2022-02-23 21:11:03 +01:00
Samy Haffoudhi 82cb74fb58 bug fix resolve conflicts, for real this time
git push origin master
2022-02-23 21:10:41 +01:00
Samy Haffoudhi c4f32d21dc Merge pull request #1 from MarcPartensky/dockercompose
docker-compose.yml
2022-02-23 20:27:54 +01:00
Samy Haffoudhi 6d0b596fea bug fix resolve conflicts 2022-02-23 20:24:34 +01:00
6 changed files with 216 additions and 16 deletions
+5
View File
@@ -0,0 +1,5 @@
.git
docker-compose.yml
Dockerfile
README.md
test
+13
View File
@@ -0,0 +1,13 @@
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
requests = "==2.27.1"
Flask = "==2.0.2"
[dev-packages]
[requires]
python_version = "3.10"
Generated
+146
View File
@@ -0,0 +1,146 @@
{
"_meta": {
"hash": {
"sha256": "3ee84615107062eb60ff41cf23471c62c89af654722d8425b186d1e4bab2afd8"
},
"pipfile-spec": 6,
"requires": {
"python_version": "3.10"
},
"sources": [
{
"name": "pypi",
"url": "https://pypi.org/simple",
"verify_ssl": true
}
]
},
"default": {
"certifi": {
"hashes": [
"sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872",
"sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"
],
"version": "==2021.10.8"
},
"charset-normalizer": {
"hashes": [
"sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597",
"sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df"
],
"markers": "python_version >= '3'",
"version": "==2.0.12"
},
"click": {
"hashes": [
"sha256:6a7a62563bbfabfda3a38f3023a1db4a35978c0abd76f6c9605ecd6554d6d9b1",
"sha256:8458d7b1287c5fb128c90e23381cf99dcde74beaf6c7ff6384ce84d6fe090adb"
],
"markers": "python_version >= '3.6'",
"version": "==8.0.4"
},
"flask": {
"hashes": [
"sha256:7b2fb8e934ddd50731893bdcdb00fc8c0315916f9fcd50d22c7cc1a95ab634e2",
"sha256:cb90f62f1d8e4dc4621f52106613488b5ba826b2e1e10a33eac92f723093ab6a"
],
"index": "pypi",
"version": "==2.0.2"
},
"idna": {
"hashes": [
"sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff",
"sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"
],
"markers": "python_version >= '3'",
"version": "==3.3"
},
"itsdangerous": {
"hashes": [
"sha256:29285842166554469a56d427addc0843914172343784cb909695fdbe90a3e129",
"sha256:d848fcb8bc7d507c4546b448574e8a44fc4ea2ba84ebf8d783290d53e81992f5"
],
"markers": "python_version >= '3.7'",
"version": "==2.1.0"
},
"jinja2": {
"hashes": [
"sha256:077ce6014f7b40d03b47d1f1ca4b0fc8328a692bd284016f806ed0eaca390ad8",
"sha256:611bb273cd68f3b993fabdc4064fc858c5b47a973cb5aa7999ec1ba405c87cd7"
],
"markers": "python_version >= '3.6'",
"version": "==3.0.3"
},
"markupsafe": {
"hashes": [
"sha256:023af8c54fe63530545f70dd2a2a7eed18d07a9a77b94e8bf1e2ff7f252db9a3",
"sha256:09c86c9643cceb1d87ca08cdc30160d1b7ab49a8a21564868921959bd16441b8",
"sha256:142119fb14a1ef6d758912b25c4e803c3ff66920635c44078666fe7cc3f8f759",
"sha256:1d1fb9b2eec3c9714dd936860850300b51dbaa37404209c8d4cb66547884b7ed",
"sha256:204730fd5fe2fe3b1e9ccadb2bd18ba8712b111dcabce185af0b3b5285a7c989",
"sha256:24c3be29abb6b34052fd26fc7a8e0a49b1ee9d282e3665e8ad09a0a68faee5b3",
"sha256:290b02bab3c9e216da57c1d11d2ba73a9f73a614bbdcc027d299a60cdfabb11a",
"sha256:3028252424c72b2602a323f70fbf50aa80a5d3aa616ea6add4ba21ae9cc9da4c",
"sha256:30c653fde75a6e5eb814d2a0a89378f83d1d3f502ab710904ee585c38888816c",
"sha256:3cace1837bc84e63b3fd2dfce37f08f8c18aeb81ef5cf6bb9b51f625cb4e6cd8",
"sha256:4056f752015dfa9828dce3140dbadd543b555afb3252507348c493def166d454",
"sha256:454ffc1cbb75227d15667c09f164a0099159da0c1f3d2636aa648f12675491ad",
"sha256:598b65d74615c021423bd45c2bc5e9b59539c875a9bdb7e5f2a6b92dfcfc268d",
"sha256:599941da468f2cf22bf90a84f6e2a65524e87be2fce844f96f2dd9a6c9d1e635",
"sha256:5ddea4c352a488b5e1069069f2f501006b1a4362cb906bee9a193ef1245a7a61",
"sha256:62c0285e91414f5c8f621a17b69fc0088394ccdaa961ef469e833dbff64bd5ea",
"sha256:679cbb78914ab212c49c67ba2c7396dc599a8479de51b9a87b174700abd9ea49",
"sha256:6e104c0c2b4cd765b4e83909cde7ec61a1e313f8a75775897db321450e928cce",
"sha256:736895a020e31b428b3382a7887bfea96102c529530299f426bf2e636aacec9e",
"sha256:75bb36f134883fdbe13d8e63b8675f5f12b80bb6627f7714c7d6c5becf22719f",
"sha256:7d2f5d97fcbd004c03df8d8fe2b973fe2b14e7bfeb2cfa012eaa8759ce9a762f",
"sha256:80beaf63ddfbc64a0452b841d8036ca0611e049650e20afcb882f5d3c266d65f",
"sha256:84ad5e29bf8bab3ad70fd707d3c05524862bddc54dc040982b0dbcff36481de7",
"sha256:8da5924cb1f9064589767b0f3fc39d03e3d0fb5aa29e0cb21d43106519bd624a",
"sha256:961eb86e5be7d0973789f30ebcf6caab60b844203f4396ece27310295a6082c7",
"sha256:96de1932237abe0a13ba68b63e94113678c379dca45afa040a17b6e1ad7ed076",
"sha256:a0a0abef2ca47b33fb615b491ce31b055ef2430de52c5b3fb19a4042dbc5cadb",
"sha256:b2a5a856019d2833c56a3dcac1b80fe795c95f401818ea963594b345929dffa7",
"sha256:b8811d48078d1cf2a6863dafb896e68406c5f513048451cd2ded0473133473c7",
"sha256:c532d5ab79be0199fa2658e24a02fce8542df196e60665dd322409a03db6a52c",
"sha256:d3b64c65328cb4cd252c94f83e66e3d7acf8891e60ebf588d7b493a55a1dbf26",
"sha256:d4e702eea4a2903441f2735799d217f4ac1b55f7d8ad96ab7d4e25417cb0827c",
"sha256:d5653619b3eb5cbd35bfba3c12d575db2a74d15e0e1c08bf1db788069d410ce8",
"sha256:d66624f04de4af8bbf1c7f21cc06649c1c69a7f84109179add573ce35e46d448",
"sha256:e67ec74fada3841b8c5f4c4f197bea916025cb9aa3fe5abf7d52b655d042f956",
"sha256:e6f7f3f41faffaea6596da86ecc2389672fa949bd035251eab26dc6697451d05",
"sha256:f02cf7221d5cd915d7fa58ab64f7ee6dd0f6cddbb48683debf5d04ae9b1c2cc1",
"sha256:f0eddfcabd6936558ec020130f932d479930581171368fd728efcfb6ef0dd357",
"sha256:fabbe18087c3d33c5824cb145ffca52eccd053061df1d79d4b66dafa5ad2a5ea",
"sha256:fc3150f85e2dbcf99e65238c842d1cfe69d3e7649b19864c1cc043213d9cd730"
],
"markers": "python_version >= '3.7'",
"version": "==2.1.0"
},
"requests": {
"hashes": [
"sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61",
"sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"
],
"index": "pypi",
"version": "==2.27.1"
},
"urllib3": {
"hashes": [
"sha256:000ca7f471a233c2251c6c7023ee85305721bfdf18621ebff4fd17a8653427ed",
"sha256:0e7c33d9a63e7ddfcb86780aac87befc2fbddf46c58dbb487e0855f7ceec283c"
],
"markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4' and python_version < '4'",
"version": "==1.26.8"
},
"werkzeug": {
"hashes": [
"sha256:1421ebfc7648a39a5c58c601b154165d05cf47a3cd0ccb70857cbdacf6c8f2b8",
"sha256:b863f8ff057c522164b6067c9e28b041161b4be5ba4d0daceeaa50a163822d3c"
],
"markers": "python_version >= '3.6'",
"version": "==2.0.3"
}
},
"develop": {}
}
+18 -11
View File
@@ -1,9 +1,12 @@
from time import time #!/usr/bin/env python
from flask import Flask, request """Flask server to serve the block API."""
import json import json
from uuid import uuid4 from time import time
from blockchain import Blockchain, Transaction, Block
import argparse import argparse
from uuid import uuid4
from flask import Flask, request
from blockchain import Blockchain, Transaction, Block
parser = argparse.ArgumentParser(description="A blockchain simulation") parser = argparse.ArgumentParser(description="A blockchain simulation")
parser.add_argument("-p", "--port", type=int, help="Port number", default=80) parser.add_argument("-p", "--port", type=int, help="Port number", default=80)
@@ -13,18 +16,19 @@ port = args.port
app = Flask(__name__) app = Flask(__name__)
node_identifier = str(uuid4()).replace("-", "") NODE_IDENTIFIER = str(uuid4()).replace("-", "")
blockchain = Blockchain() blockchain = Blockchain()
@app.route("/mine", methods=["GET"]) @app.route("/mine", methods=["GET"])
def mine(): def mine():
"""Mine samy coin."""
last_block = blockchain.blocks[-1] last_block = blockchain.blocks[-1]
last_proof = last_block.proof last_proof = last_block.proof
proof = blockchain.proof_of_work(last_proof) proof = blockchain.proof_of_work(last_proof)
transaction = Transaction("Network", node_identifier, 50) transaction = Transaction("Network", NODE_IDENTIFIER, 50)
blockchain.new_transaction(transaction) blockchain.new_transaction(transaction)
block = Block( block = Block(
len(blockchain.blocks) + 1, len(blockchain.blocks) + 1,
@@ -40,6 +44,7 @@ def mine():
@app.route("/transactions/new", methods=["POST"]) @app.route("/transactions/new", methods=["POST"])
def new_transaction(): def new_transaction():
"""Submit a new transaction."""
values = request.get_json() values = request.get_json()
transaction = Transaction(values["sender"], values["recipient"], values["amount"]) transaction = Transaction(values["sender"], values["recipient"], values["amount"])
blockchain.new_transaction(transaction) blockchain.new_transaction(transaction)
@@ -49,27 +54,29 @@ def new_transaction():
@app.route("/chain", methods=["GET"]) @app.route("/chain", methods=["GET"])
def chain(): def chain():
"""Display the block chain."""
return json.dumps([b.__dict__ for b in blockchain.blocks]) return json.dumps([b.__dict__ for b in blockchain.blocks])
@app.route("/nodes", methods=["GET"]) @app.route("/nodes", methods=["GET"])
def nodes(): def nodes():
"""List known nodes."""
return json.dumps(list(blockchain.nodes)) return json.dumps(list(blockchain.nodes))
@app.route("/register", methods=["POST"]) @app.route("/register", methods=["POST"])
def register_nodes(): def register_nodes():
values = request.get_json() """Register a new node."""
nodes = values["nodes"] json_values = request.get_json()
for node in json_values["nodes"]:
for node in nodes:
blockchain.register_node(node) blockchain.register_node(node)
return "New node has been added\n" return "New node has been added\n"
@app.route("/resolve", methods=["GET"]) @app.route("/resolve", methods=["GET"])
def consensus(): def resolve():
"""Resolve the blockchain."""
replaced = blockchain.resolve_conflicts() replaced = blockchain.resolve_conflicts()
if replaced: if replaced:
+30 -2
View File
@@ -1,3 +1,5 @@
#!/usr/bin/env python
import hashlib import hashlib
from time import time from time import time
import json import json
@@ -87,6 +89,32 @@ class Blockchain:
return True return True
def json_to_transactions(self, transactions_json):
transactions = [
Transaction(
transaction["sender"],
transaction["recipient"],
transaction["amount"],
)
for transaction in transactions_json
]
return transactions
def json_to_chain(self, chain_json):
chain = [
Block(
block["index"],
block["timestamp"],
self.json_to_transactions(block["transactions"]),
block["previous_hash"],
block["proof"],
)
for block in chain_json
]
return chain
def resolve_conflicts(self): def resolve_conflicts(self):
neighbours = self.nodes neighbours = self.nodes
new_chain = None new_chain = None
@@ -100,10 +128,10 @@ class Blockchain:
if length > max_lengh and self.valid_chain(chain): if length > max_lengh and self.valid_chain(chain):
max_lengh = length max_lengh = length
new_chain = chain new_chain = self.json_to_chain(chain)
if new_chain: if new_chain:
self.chain = new_chain self.blocks = new_chain
return True return True
return False return False
+4 -3
View File
@@ -1,8 +1,9 @@
#!/bin/sh #!/bin/sh
curl "localhost:5123/register" -H "Content-Type: application/json" -d '{"nodes": ["http://127.0.0.1:5000"]}' curl "localhost:5001/register" -H "Content-Type: application/json" -d '{"nodes": ["http://127.0.0.1:5000"]}'
curl "localhost:5000/transactions/new" -H "Content-Type: application/json" -d '{"sender": "marc", "recipient": "samy", "amount": 50}' curl "localhost:5000/transactions/new" -H "Content-Type: application/json" -d '{"sender": "marc", "recipient": "samy", "amount": 50}'
curl "localhost:5000/mine" curl "localhost:5000/mine"
curl -s "localhost:5000/chain" | jq curl -s "localhost:5000/chain" | jq
curl -s "localhost:5123/chain" | jq curl -s "localhost:5001/chain" | jq
curl "localhost:5123/resolve" curl "localhost:5001/resolve"
curl -s "localhost:5001/chain" | jq