-
Notifications
You must be signed in to change notification settings - Fork 5
/
chain.py
153 lines (117 loc) · 4.09 KB
/
chain.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
from redis import Redis
import rsa
from hashlib import sha256
import json
from config import *
class Transaction(object):
def __init__(self, prev_hash, transaction_type, sender, receiver):
""" Constructor for creating new transaction
"""
self.prev_hash = prev_hash
self.transaction_type = transaction_type
self.sender = sender
self.receiver = receiver
def add_signature(self, signature):
""" Add signature to the transaction """
self.signature = signature
@property
def message(self):
return json.dumps(self.to_dict(), sort_keys=True).encode('utf-8')
@property
def hash(self):
return sha256(json.dumps(self.to_dict(), sort_keys=True).encode('utf-8')).hexdigest()
def to_dict(self):
"""
Converts the transaction data into a serializable json format.
"""
return {
'prev_hash': self.prev_hash,
'transaction_type': self.transaction_type,
'sender': {
'n': self.sender.n,
'e': self.sender.e,
},
'receiver': {
'n': self.receiver.n,
'e': self.receiver.e,
},
}
def to_redis(self):
"""
Converts the entire transaction into a json format that can be put into redis
"""
return {
'data': self.to_dict(),
}
def write_to_redis(self, r, key):
r.rpush(key, json.dumps(self.to_redis(), sort_keys=True))
sig_key = "{}{}".format(TRANSACTIONS_SIGNATURE, self.hash)
print("signature key for transaction = " + sig_key)
r.set(sig_key, self.signature)
def verify(self):
""" Verifies the signature of transaction
"""
try:
rsa.verify(self.message, self.signature, self.sender)
except VerificationError:
print("Verification failed", file=sys.stderr)
return False
return True
@classmethod
def from_redis(cls, redis, payload):
""" Factory to create a Transaction object from redis
"""
print("in from redis")
obj = cls(
prev_hash=payload['data']['prev_hash'],
transaction_type=payload['data']['transaction_type'],
sender=rsa.key.PublicKey(payload['data']['sender']['n'], payload['data']['sender']['e']),
receiver=rsa.key.PublicKey(payload['data']['receiver']['n'], payload['data']['receiver']['e']),
)
key = '{}{}'.format(TRANSACTIONS_SIGNATURE, obj.hash)
print(key)
obj.add_signature(redis.get(key))
print("Hello")
return obj
class Block(object):
def __init__(self, prev_hash):
self.prev_hash = prev_hash
self.transactions = []
self.signatures = []
def full(self):
return len(self.transactions) >= TRANSACTIONS_IN_BLOCK
def add_transaction(self, transaction):
self.transactions.append(transaction)
self.signatures.append(transaction.signature)
def to_json(self):
payload = {
'nonce': self.nonce,
'prev_hash': self.prev_hash,
'transactions': [],
}
for t in self.transactions:
payload['transactions'].append(t.to_redis())
return payload
def add_nonce(self, nonce):
self.nonce = nonce
def to_redis(self):
data = self.to_json()
data['hash'] = self.hash
return data
@property
def hash(self):
return sha256(json.dumps(self.to_json(), sort_keys=True).encode('utf-8')).hexdigest()
@classmethod
def from_json(cls, payload):
obj = cls(payload['prev_hash'])
for transaction in payload['transactions']:
obj.transactions.append(Transaction.from_json(transaction))
obj.add_nonce(payload['nonce'])
return obj
def verify(self):
acc = ''
for t in self.transactions:
acc += str(t.hash)
return int(sha256((str(self.nonce)+acc).encode('utf-8')).hexdigest()[0:6],16) < GAMER_BAWA
if __name__ == '__main__':
pass