This repository has been archived by the owner on Oct 14, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathApp.py
187 lines (140 loc) · 5.11 KB
/
App.py
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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
from typing import List
from flask import Flask, jsonify, request, Response
from flask_expects_json import expects_json
from Classes.block_chain import BlockChain
from Classes.node import Node
from Classes.transaction import Transaction
from Classes.transaction_input import TransactionInput
from Classes.transaction_output import TransactionOutput
block_chain = BlockChain()
app = Flask(__name__)
nodes: List[Node] = []
node_register_password = 'da859bfa-3a8e-4da7-8e60-200d5259e15b'
@app.route('/difficulty', methods=['GET'])
def get_difficulty() -> Response:
return jsonify(block_chain.difficulty)
@app.route('/genesisBlock', methods=['GET'])
def get_genesis_block() -> Response:
genesis_block = block_chain.get_genesis_block()
return jsonify(genesis_block.__dict__())
@app.route('/lastBlock', methods=['GET'])
def get_last_block() -> Response:
return jsonify(block_chain.get_last_block().__dict__())
@app.route('/chain', methods=['GET'])
def get_chain() -> Response:
chain = map(lambda block: block.__dict__(), block_chain.chain)
return jsonify(list(chain))
@app.route('/block', methods=['POST'])
@expects_json({
"type": "object",
"required": ["address"],
'address': {'type': 'string'},
})
def create_block() -> Response:
block = block_chain.add_block(request.json['address'])
for node in nodes:
node.broadcast_block(block)
return jsonify(block.__dict__())
@app.route('/block/<block_hash>', methods=['GET'])
def get_block(block_hash) -> Response:
block = block_chain.get_block(block_hash)
if block is None:
return jsonify({'error': 'Block not found'}), 404
return jsonify(block.__dict__())
@app.route('/transaction', methods=['POST'])
@expects_json({
"type": "object",
"required": ["inputs", "outputs"],
"properties": {
"inputs": {
"type": "array",
"items": {
"type": "object",
"required": ["transaction_output_id"],
"properties": {
"transaction_output_id": {"type": "string"}
},
}
},
"outputs": {
"type": "array",
"items": {
"type": "object",
"required": ["address", "amount"],
"properties": {
"address": {"type": "string"},
"amount": {"type": "integer"}
}
}
}
},
})
def create_transaction():
transaction_inputs = []
for requestInput in request.json['inputs']:
output = block_chain.get_transaction_output(requestInput['transaction_output_id'])
if output is None:
return jsonify({'error': 'Invalid transaction output id'}), 400
transaction_inputs.append(TransactionInput(output))
transaction_outputs = []
for requestOutput in request.json['outputs']:
transaction_outputs.append(TransactionOutput(requestOutput['address'], requestOutput['amount']))
transaction = Transaction(transaction_inputs, transaction_outputs)
if not transaction.is_valid(block_chain):
return jsonify({'error': 'Invalid transaction'}), 400
block_chain.add_transaction(transaction)
return jsonify(transaction.__dict__()), 201
@app.route('/valid', methods=['GET'])
def is_valid():
return jsonify({
'valid': block_chain.is_valid(),
})
@app.route('/balance/<address>', methods=['GET'])
def get_balance(address) -> Response:
balance = block_chain.get_balance(address)
return jsonify({
'balance': balance,
})
@app.route('/node/register', methods=['POST'])
@expects_json({
"type": "object",
"required": ["password", "address", "port"],
"properties": {
"password": {
"type": "string",
},
"address": {
"type": "string",
},
"port": {
"type": "integer",
}
},
})
def register_node():
if request.json['password'] != node_register_password:
return jsonify({'error': 'Invalid password'}), 400
for node in nodes:
if node.address == request.json['address'] and node.port == request.json['port']:
return jsonify({'error': 'Node already registered'}), 400
node = Node(request.json['address'], request.json['port'])
nodes.append(node)
return jsonify({'success': True}), 201
@app.route('/blocks-from-height/<height>', methods=['GET'])
def get_blocks_from_height(height) -> Response:
blocks = block_chain.get_blocks_from_height(int(height))
return jsonify(list(map(lambda block: block.__dict__(), blocks)))
@app.route('/node/block', methods=['POST'])
def receive_block():
data = request.json
block_added = block_chain.add_block_from_dict(data)
if block_added:
return jsonify({'success': True}), 201
return jsonify({'error': 'Block not added'}), 400
@app.route('/node/transaction', methods=['POST'])
def receive_transaction():
data = request.json
transaction_added = block_chain.add_transaction_from_dict(data)
if transaction_added:
return jsonify({'success': True}), 201
return jsonify({'error': 'Block not added'}), 400