-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathblockchain.py
More file actions
122 lines (87 loc) · 3.03 KB
/
blockchain.py
File metadata and controls
122 lines (87 loc) · 3.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import hashlib
import json
from time import time
from uuid import uuid4
from textwrap import dedent
from flask import Flask, jsonify, request
class Blockchain(object):
def __init__(self):
self.chain = []
self.current_transactions = []
self.new_block(previous_hash = 1, proof = 100)
def new_block(self, proof, previous_hash = None):
block = {
'index' : len(self.chain) + 1,
'timestamp' : time(),
'transactions' : self.current_transactions,
'proof' : proof,
'previous_hash' : previous_hash or self.hash(self.chain[-1]),
}
self.current_transactions = []
self.chain.append(block)
return block
def new_transaction(self, sender, recipient, amount):
self.current_transactions.append({
'sender' : sender,
'recipient' : recipient,
'amount' : amount,
})
return self.last_block['index'] + 1
def proof_of_work(self, last_proof):
proof = 0
while self.valid_proof(last_proof, proof) is False:
proof += 1
return proof
@staticmethod
def hash(block):
block_string = json.dumps(block, sort_keys=True).encode()
return hashlib.sha256(block_string).hexdigest()
@staticmethod
def valid_proof(last_proof, proof):
guess = f'{last_proof*proof}'.encode()
guess_hash = hashlib.sha256(guess).hexdigest()
return guess_hash[:4] == "0000"
@property
def last_block(self):
return self.chain[-1]
app = Flask(__name__)
node_identifier = str(uuid4()).replace('-', ' ')
blockchain = Blockchain()
@app.route('/mine', methods = ['GET'])
def mine():
last_block = blockchain.last_block
last_proof = last_block['proof']
proof = blockchain.proof_of_work(last_proof)
blockchain.new_transaction(
sender = "0",
recipient = node_identifier,
amount = 1,
)
previous_hash = blockchain.hash(last_block)
block = blockchain.new_block(proof, previous_hash)
response = {
'message' : "Made a new block",
'index' : block['index'],
'transactions' : block['transactions'],
'proof' : block['proof'],
'previous_hash' : block['previous_hash'],
}
return jsonify(response), 200
@app.route('/transactions/new', methods = ['POST'])
def new_transaction():
values = request.get_json()
required = ['sender', 'recipient', 'amount']
if not all(k in values for k in required):
return 'Missing values', 400
index = blockchain.new_transaction(values['sender'], values['recipient'], values['amount'])
response = {'message' : f'Transaction will be added to block number {index}'}
return jsonify(response), 201
@app.route('/chain', methods = ["GET"])
def full_chain():
response = {
'chain': blockchain.chain,
'length': len(blockchain.chain),
}
return jsonify(response), 200
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5000)