forked from qwerwon/SGBL_Project
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtransaction.py
168 lines (135 loc) · 5.84 KB
/
transaction.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
import json
import base64
import plyvel
# vin class
########################################################################################################################
class Vin:
def __init__(self, tx_id, index, unlock):
self.tx_id = tx_id # string
self.index = index # int
self.unlock = unlock # bytes => Privatekey.ecdsa_deserialize(unlock)로 디코딩
'''
def vin_to_dict(self):
return {
"tx_id" : self.tx_id,
"index" : self.index,
"unlock" : self.unlock
}
'''
def to_dict(self):
return {'tx_id': self.tx_id, 'index': self.index, 'unlock': base64.b64encode(self.unlock).decode('utf-8')}
def from_dict(self, data_json):
return Vin(data_json["tx_id"], data_json["index"], base64.b64decode(data_json["unlock"]))
# Vout class
########################################################################################################################
class Vout:
def __init__(self, value, lock):
self.value = value # float
self.lock = lock # bytes => PublicKey(pub, raw=True)로 디코딩
'''
def vout_to_dict(self):
return {
"value" : self.value,
"lock" : self.lock
}
'''
def to_dict(self):
return {'value': self.value, 'lock': base64.b64encode(self.lock).decode('utf-8')}
def from_dict(self, data_json):
return Vout(data_json["value"], base64.b64decode(data_json["lock"]))
# Transaction class
########################################################################################################################
class Transaction(object):
# class variables
_MemoryPool = 0
# init
####################################################################################################################
def __init__(self, tx_id, in_num, vin, out_num, vout):
# Key = tx_id
self.tx_id = tx_id # bytes
self.in_num = in_num # int
self.vin = vin # list[Vin]
self.out_num = out_num # int
self.vout = vout # list[Vout]
'''
# for tx to dictionary type.
def Tx_to_dict(self):
return {
"tx_id" : self.tx_id,
"in_num" : self.in_num,
"vin" : [item.vin_to_dict() for item in self.vin],
"out_num" : self.out_num,
"vout" : [item.vout_to_dict() for item in self.vout]
}
'''
# Make db for store pending transaction
####################################################################################################################
@classmethod
def initialize(cls):
cls._MemoryPool = plyvel.DB('./db/MemoryPool', create_if_missing=True)
# Insert transaction to DB
####################################################################################################################
@classmethod
def Insert_MemoryPool(cls, tx_id, in_counter, vin, out_counter, vout):
"""
Args:
tx_id : bytes(key of db)
in_counter : int
vin : list[Vin]
out_counter : int
vout : list[Vout]
"""
newVin = []
newVout = []
# Convert vin and vout for store
################################################################################################################
for vin_el in vin:
newVin.append(json.dumps(vin_el.__dict__))
for vout_el in vout:
newVout.append(json.dumps(vout_el.__dict__))
mempool = {"in_num": in_counter,
"vin": json.dumps(newVin),
"out_num": out_counter,
"vout": json.dumps(newVout)}
mempool_en = json.dumps(mempool)
cls._MemooryPool.put(tx_id, mempool_en.encode())
# Pop transaction from DB
####################################################################################################################
@classmethod
def Pop_MemoryPool(cls, tx_id):
"""
Args:
tx_id : bytes(key of db)
"""
cls._MemoryPool.delete(tx_id, sync=True)
def to_dict(self):
return {'tx_id': base64.b64encode(self.tx_id).decode('utf-8'), 'in_num': self.in_num,
'vin': [item.to_dict() for item in self.vin], 'out_num': self.out_num, 'vout': [item.to_dict() for item in self.vout]}
def from_dict(self, data_json):
return Transaction(base64.b64decode(data_json["tx_id"]), data_json["in_num"],
[Vin(0, 0, 0).from_dict(item) for item in data_json["vin"]], data_json["out_num"],
[Vout(0, 0).from_dict(item) for item in data_json["vout"]])
#Communication part.
def _broadcast_Tx(self):
message = {'type': 'TRANSACTION', 'tx': self.to_dict()}
#print(message)
return self._broadcast(message)
def _broadcast(self, message):
results = []
pool = multiprocessing.Pool(5)
# Peer._peers / self._peers
# have to
pp = (('127.0.0.1',5003),('127.0.0.1',5002))
for (host, port) in pp:
results.append(pool.apply_async(
self._send_message, args=(host, port, message)))
pool.close()
pool.join()
return [result.get() for result in results]
def _send_message(self, host, port, message):
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
print(host, port)
s.connect((host, port))
s.sendall(json.dumps(message).encode('utf-8'))
response = s.recv(655350, 0)
return response.decode('utf-8')