Skip to content

Commit d31a5cd

Browse files
Initial commit
0 parents  commit d31a5cd

File tree

3 files changed

+283
-0
lines changed

3 files changed

+283
-0
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.DS_Store

blockchain.py

+105
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# Blockchain
2+
3+
import datetime
4+
import hashlib
5+
import json
6+
from flask import Flask, jsonify
7+
8+
class Blockchain:
9+
10+
def __init__(self):
11+
self.chain = []
12+
self.create_block(proof = 1, previous_hash = '0')
13+
14+
def create_block(self, proof, previous_hash):
15+
block = {
16+
'index': len(self.chain) + 1,
17+
'timestamp': str(datetime.datetime.now()),
18+
'proof': proof,
19+
'previous_hash': previous_hash
20+
}
21+
self.chain.append(block)
22+
return block
23+
24+
def get_previous_block(self):
25+
return self.chain[-1]
26+
27+
def proof_of_work(self, previous_proof):
28+
new_proof = 1
29+
check_proof = False
30+
while check_proof is False:
31+
hash_operation = hashlib.sha256(str(new_proof**2 - previous_proof**2).encode()).hexdigest()
32+
if hash_operation[:4] == '0000':
33+
check_proof = True
34+
else:
35+
new_proof += 1
36+
return new_proof
37+
38+
def hash(self, block):
39+
encoded_block = json.dumps(block, sort_keys = True).encode()
40+
return hashlib.sha256(encoded_block).hexdigest()
41+
42+
def is_chain_valid(self, chain):
43+
previous_block = chain[0]
44+
block_index = 1
45+
while block_index < len(chain):
46+
block = chain[block_index]
47+
if block['previous_hash'] != self.hash(previous_block):
48+
return False
49+
previous_proof = previous_block['proof']
50+
proof = block['proof']
51+
hash_operation = hashlib.sha256(str(proof**2 - previous_proof**2).encode()).hexdigest()
52+
if hash_operation[:4] != '0000':
53+
return False
54+
previous_block = block
55+
block_index += 1
56+
return True
57+
58+
# Web app
59+
app = Flask(__name__)
60+
61+
# Create Blockchain
62+
blockchain = Blockchain()
63+
64+
# Mine new block
65+
@app.route('/mine', methods=['GET'])
66+
def mine_block():
67+
previous_block = blockchain.get_previous_block()
68+
previous_proof = previous_block['proof']
69+
proof = blockchain.proof_of_work(previous_proof)
70+
previous_hash = blockchain.hash(previous_block)
71+
block = blockchain.create_block(proof, previous_hash)
72+
response = {
73+
'message': 'Block mined',
74+
'index': block['index'],
75+
'timestamp': block['timestamp'],
76+
'proof': block['proof'],
77+
'previous_hash': block['previous_hash']
78+
}
79+
return jsonify(response), 200
80+
81+
# Get full chain
82+
@app.route('/blockchain', methods=['GET'])
83+
def get_blockchain():
84+
response = {
85+
'length': len(blockchain.chain),
86+
'chain': blockchain.chain
87+
}
88+
return jsonify(response), 200
89+
90+
# Check if blockchain is valid
91+
@app.route('/blockchain/valid', methods=['GET'])
92+
def is_valid():
93+
is_valid = blockchain.is_chain_valid(blockchain.chain)
94+
if is_valid:
95+
response = {
96+
'message': 'Blockchain is valid'
97+
}
98+
else:
99+
response = {
100+
'message': 'Blockchain is NOT valid'
101+
}
102+
return jsonify(response), 200
103+
104+
# Run the app
105+
app.run(host = '0.0.0.0', port = 5000)

requirements.txt

+177
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
alabaster==0.7.10
2+
anaconda-client==1.6.9
3+
anaconda-navigator==1.7.0
4+
anaconda-project==0.8.2
5+
appnope==0.1.0
6+
appscript==1.0.1
7+
asn1crypto==0.24.0
8+
astroid==1.6.1
9+
astropy==2.0.3
10+
attrs==17.4.0
11+
Babel==2.5.3
12+
backports.shutil-get-terminal-size==1.0.0
13+
beautifulsoup4==4.6.0
14+
bitarray==0.8.1
15+
bkcharts==0.2
16+
blaze==0.11.3
17+
bleach==2.1.2
18+
bokeh==0.12.13
19+
boto==2.48.0
20+
Bottleneck==1.2.1
21+
certifi==2018.1.18
22+
cffi==1.11.4
23+
chardet==3.0.4
24+
click==6.7
25+
cloudpickle==0.5.2
26+
clyent==1.2.2
27+
colorama==0.3.9
28+
conda==4.4.10
29+
conda-build==3.4.1
30+
conda-verify==2.0.0
31+
contextlib2==0.5.5
32+
cryptography==2.1.4
33+
cycler==0.10.0
34+
Cython==0.27.3
35+
cytoolz==0.9.0
36+
dask==0.16.1
37+
datashape==0.5.4
38+
decorator==4.2.1
39+
distributed==1.20.2
40+
docutils==0.14
41+
entrypoints==0.2.3
42+
et-xmlfile==1.0.1
43+
fastcache==1.0.2
44+
filelock==2.0.13
45+
Flask==0.12.2
46+
Flask-Cors==3.0.3
47+
gevent==1.2.2
48+
glob2==0.6
49+
gmpy2==2.0.8
50+
greenlet==0.4.12
51+
h5py==2.7.1
52+
heapdict==1.0.0
53+
html5lib==1.0.1
54+
idna==2.6
55+
imageio==2.2.0
56+
imagesize==0.7.1
57+
ipykernel==4.8.0
58+
ipython==6.2.1
59+
ipython-genutils==0.2.0
60+
ipywidgets==7.1.1
61+
isort==4.2.15
62+
itsdangerous==0.24
63+
jdcal==1.3
64+
jedi==0.11.1
65+
Jinja2==2.10
66+
jsonschema==2.6.0
67+
jupyter==1.0.0
68+
jupyter-client==5.2.2
69+
jupyter-console==5.2.0
70+
jupyter-core==4.4.0
71+
jupyterlab==0.31.5
72+
jupyterlab-launcher==0.10.2
73+
lazy-object-proxy==1.3.1
74+
llvmlite==0.21.0
75+
locket==0.2.0
76+
lxml==4.1.1
77+
MarkupSafe==1.0
78+
matplotlib==2.1.2
79+
mccabe==0.6.1
80+
mistune==0.8.3
81+
mpmath==1.0.0
82+
msgpack-python==0.5.1
83+
multipledispatch==0.4.9
84+
navigator-updater==0.1.0
85+
nbconvert==5.3.1
86+
nbformat==4.4.0
87+
networkx==2.1
88+
nltk==3.2.5
89+
nose==1.3.7
90+
notebook==5.4.0
91+
numba==0.36.2
92+
numexpr==2.6.4
93+
numpy==1.14.0
94+
numpydoc==0.7.0
95+
odo==0.5.1
96+
olefile==0.45.1
97+
openpyxl==2.4.10
98+
packaging==16.8
99+
pandas==0.22.0
100+
pandocfilters==1.4.2
101+
parso==0.1.1
102+
partd==0.3.8
103+
path.py==10.5
104+
pathlib2==2.3.0
105+
patsy==0.5.0
106+
pep8==1.7.1
107+
pexpect==4.3.1
108+
pickleshare==0.7.4
109+
Pillow==5.0.0
110+
pkginfo==1.4.1
111+
pluggy==0.6.0
112+
ply==3.10
113+
prompt-toolkit==1.0.15
114+
psutil==5.4.3
115+
ptyprocess==0.5.2
116+
py==1.5.2
117+
pycodestyle==2.3.1
118+
pycosat==0.6.3
119+
pycparser==2.18
120+
pycrypto==2.6.1
121+
pycurl==7.43.0.1
122+
pyflakes==1.6.0
123+
Pygments==2.2.0
124+
pylint==1.8.2
125+
pyodbc==4.0.22
126+
pyOpenSSL==17.5.0
127+
pyparsing==2.2.0
128+
PySocks==1.6.7
129+
pytest==3.3.2
130+
python-dateutil==2.6.1
131+
pytz==2017.3
132+
PyWavelets==0.5.2
133+
PyYAML==3.12
134+
pyzmq==16.0.3
135+
QtAwesome==0.4.4
136+
qtconsole==4.3.1
137+
QtPy==1.3.1
138+
requests==2.18.4
139+
rope==0.10.7
140+
ruamel-yaml==0.15.35
141+
scikit-image==0.13.1
142+
scikit-learn==0.19.1
143+
scipy==1.0.0
144+
seaborn==0.8.1
145+
Send2Trash==1.4.2
146+
simplegeneric==0.8.1
147+
singledispatch==3.4.0.3
148+
six==1.11.0
149+
snowballstemmer==1.2.1
150+
sortedcollections==0.5.3
151+
sortedcontainers==1.5.9
152+
Sphinx==1.6.6
153+
sphinxcontrib-websupport==1.0.1
154+
spyder==3.2.6
155+
SQLAlchemy==1.2.1
156+
statsmodels==0.8.0
157+
sympy==1.1.1
158+
tables==3.4.2
159+
tblib==1.3.2
160+
terminado==0.8.1
161+
testpath==0.3.1
162+
toolz==0.9.0
163+
tornado==4.5.3
164+
traitlets==4.3.2
165+
typing==3.6.2
166+
unicodecsv==0.14.1
167+
urllib3==1.22
168+
wcwidth==0.1.7
169+
webencodings==0.5.1
170+
Werkzeug==0.14.1
171+
widgetsnbextension==3.1.0
172+
wrapt==1.10.11
173+
xlrd==1.1.0
174+
XlsxWriter==1.0.2
175+
xlwings==0.11.5
176+
xlwt==1.2.0
177+
zict==0.1.3

0 commit comments

Comments
 (0)