-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnode.py
More file actions
133 lines (118 loc) · 4.68 KB
/
node.py
File metadata and controls
133 lines (118 loc) · 4.68 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
123
124
125
126
127
128
129
130
131
132
133
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Mar 14 20:59:33 2018
@author: manny
"""
import json
import pickle
import datetime
from blockClass import Block
from wallet import generate_key_pair
from blockchainUtilities import create_genesis_block, proof_of_work, consensus, verify_message, get_balance
from Crypto.PublicKey import RSA
from flask import Flask, request
node = Flask(__name__)
try:
config = json.load(open('config.json'))
node_wallet_name = config['node_settings']['node_wallet_name']
mining = config['node_settings']['mining_enabled']
node_ip_address = config['node_settings']['node_ip_address']
node_port = config['node_settings']['node_port']
peer_nodes = []
for peer_node in config['peer_nodes']:
peer_nodes.append(peer_node)
except Exception:
print("Error: Unable to load node config file")
exit()
if mining:
try:
key_file = open(node_wallet_name+'_public_key.pem', 'rb')
except Exception:
print("Node wallet not found, generating new wallet...")
generate_key_pair(node_wallet_name)
key_file = open(node_wallet_name+'_public_key.pem', 'rb')
node_addr= RSA.importKey(key_file.read()).exportKey().decode("UTF-8")
blockchain = []
if blockchain == []:
try:
blockchain = consensus(peer_nodes, blockchain)
except Exception:
print("Can't connect to peer nodes")
if blockchain == []:
print("No peer nodes found")
try:
with open('blockchain.pkl', 'rb') as blockchain_file:
blockchain = pickle.load(blockchain_file)
print("I'm pickle Chain! - blockchain initialised from local pkl file")
except Exception:
print("No local blockchain found")
if blockchain == []:
print("Generating local blockchain...")
blockchain = [create_genesis_block()]
tmp_blockchain = blockchain
this_nodes_txions = []
@node.route('/txion', methods=['POST'])
def transaction():
if request.method == 'POST':
new_txion = request.get_json()
if new_txion['amount'] < 0:
return "Cannot process transactions of less than 0!\n", 403
if new_txion['amount'] > get_balance(RSA.importKey(new_txion['from'].encode("UTF-8"))):
return "Insufficient funds to carry out transaction!\n", 403
else:
this_nodes_txions.append(new_txion)
print("---New Transaction")
print("FROM: {0}".format(new_txion['from']))
print("TO: {0}".format(new_txion['to']))
print("AMOUNT: #{0}".format(new_txion['amount']))
#print("VERIFIED: {0}".format(verified))
return "Transaction submission successful!\n"
@node.route('/mine', methods=['GET'])
def mine():
if mining:
new_blockchain = consensus(peer_nodes, blockchain)
last_block = new_blockchain[len(new_blockchain) - 1]
last_proof = last_block.data['proof-of-work']
proof = proof_of_work(last_proof)
this_nodes_txions.append(
{"from": "Mining", "to": node_addr, "amount": 1})
new_block_data = {"proof-of-work": proof,
"transactions": list(this_nodes_txions)}
new_block_index = last_block.index + 1
new_block_timestamp = datetime.datetime.now()
last_block_hash = last_block.hash
this_nodes_txions[:] = []
mined_block = Block(new_block_index,
new_block_timestamp,
new_block_data,
last_block_hash)
new_blockchain.append(mined_block)
store_blockchain()
return json.dumps({"index": new_block_index,
"timestamp": str(new_block_timestamp),
"data": new_block_data,
"hash": last_block_hash}) + "\n"
else:
return "Mining not enabled!\n"
@node.route('/blocks', methods=['GET'])
def get_blocks():
new_blockchain = consensus(peer_nodes, blockchain)
chain_to_send = []
for block in new_blockchain:
block_index = str(block.index)
block_timestamp = str(block.timestamp)
block_data = str(block.data)
block_hash = str(block.hash)
new_block = {"index": block_index,
"timestamp": block_timestamp,
"data": block_data,
"hash": block_hash}
chain_to_send.append(new_block)
chain_to_send = json.dumps(chain_to_send)
return chain_to_send
def store_blockchain():
new_blockchain = consensus(peer_nodes, blockchain)
with open('blockchain.pkl', 'wb') as blockchain_file:
pickle.dump(new_blockchain, blockchain_file, pickle.HIGHEST_PROTOCOL)
node.run(host=node_ip_address, port=int(node_port), threaded=True)