-
Notifications
You must be signed in to change notification settings - Fork 8
/
transaction.py
122 lines (92 loc) · 3.8 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
import json
import base64
import plyvel
# Vin class
class Vin(object):
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 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(object):
def __init__(self, value, lock):
self.value = value # float
self.lock = lock # bytes => PublicKey(pub, raw=True)로 디코딩
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]
# Make db for store pending transaction
@classmethod
def initialize(cls):
"""
Open and initialize Database of MemoryPool
"""
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):
"""
Insert Transaction into MemoryPool DB as
key : tx_id(bytes)
value : {'tx_id': string, 'in_num': int, 'vin': [Vin().to_dict], 'out_num': int,
'vout': [Vout().to_dict]}
Args:
tx_id : bytes
in_num : int
vin : list[Vin()]
out_num : int
vout : list[Vout()]
"""
tx_data = Transaction(tx_id, in_counter, vin, out_counter, vout).to_dict()
tx_data_en = json.dumps(tx_data).encode()
cls._MemoryPool.put(tx_id, tx_data_en)
# Pop transaction from DB
@classmethod
def Pop_MemoryPool(cls, tx_id):
"""
Delete Transaction from MemoryPool DB
key : txOutid(bytes) + index(bytes)
Args:
tx_id : bytes(key of db)
"""
cls._MemoryPool.delete(tx_id, sync=True)
@classmethod
def get_MemoryPool(cls, tx_id):
"""
Fetch Transaction from MemoryPool DB
key : tx_id(bytes)
Args:
tx_id : bytes(key of db)
return:
Transaction object or False
"""
result = Transaction._MemoryPool.get(tx_id, default=None)
if result is None:
return False
else:
data_json = json.loads(result)
return Transaction(b'0', 0, [], 0, []).from_dict(data_json)
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"]])