1717# Caner Candan <caner@candan.fr>, http://caner.candan.fr
1818#
1919
20- import hashlib , logging
20+ import logging
2121from .. import pks , ucg , hdc , settings
2222
2323logger = logging .getLogger ("wrappers" )
@@ -26,229 +26,4 @@ class Wrapper:
2626 def __call__ (self ):
2727 pass
2828
29- class Transaction (Wrapper ):
30- def __init__ (self , type , pgp_fingerprint , message = '' ):
31- self .pgp_fingerprint = pgp_fingerprint
32- self .message = message
33- self .type = type
34- self .error = None
35-
36- def __call__ (self ):
37- try :
38- last_tx = hdc .transactions .sender .Last (self .pgp_fingerprint ).get ()
39- except ValueError :
40- last_tx = None
41-
42- context_data = {}
43- context_data .update (settings )
44- context_data ['version' ] = 1
45- context_data ['number' ] = 0 if not last_tx else last_tx ['transaction' ]['number' ]+ 1
46- context_data ['previousHash' ] = hashlib .sha1 (("%(raw)s%(signature)s" % last_tx ).encode ('ascii' )).hexdigest ().upper () if last_tx else None
47- context_data ['message' ] = self .message
48- context_data ['type' ] = self .type
49- context_data .update (self .get_context_data ())
50-
51- tx = """\
52- Version: %(version)d
53- Currency: %(currency)s
54- Sender: %(fingerprint)s
55- Number: %(number)d
56- """ % context_data
57-
58- if last_tx : tx += "PreviousHash: %(previousHash)s\n " % context_data
59-
60- tx += self .get_message (context_data )
61-
62- tx += """\
63- Comment:
64- %(message)s
65- """ % context_data
66-
67- tx = tx .replace ("\n " , "\r \n " )
68- txs = settings ['gpg' ].sign (tx , detach = True )
69-
70- if self .error : return False
71-
72- return self .process (tx , txs )
73-
74- def get_context_data (self ):
75- return {}
76-
77- def get_message (self , context_data , tx = '' ):
78- return tx
79-
80- def get_error (self ):
81- return self .error
82-
83- def process (self , tx , txs ):
84- try :
85- hdc .transactions .Process ().post (transaction = tx , signature = txs )
86- except ValueError as e :
87- self .error = str (e )
88- else :
89- return True
90-
91- return False
92-
93- class Transfer (Transaction ):
94- def __init__ (self , pgp_fingerprint , recipient , coins , message = '' ):
95- super ().__init__ ('TRANSFER' , pgp_fingerprint , message )
96- self .recipient = recipient
97- self .coins = coins
98-
99- def get_message (self , context_data , tx = '' ):
100- context_data ['recipient' ] = self .recipient
101-
102- tx += """\
103- Recipient: %(recipient)s
104- Type: %(type)s
105- Coins:
106- """ % context_data
107-
108- for coin in self .coins .split (',' ):
109- data = coin .split (':' )
110- issuer = data [0 ]
111- for number in data [1 :]:
112- context_data .update (hdc .coins .View (issuer , int (number )).get ())
113- tx += '%(id)s, %(transaction)s\n ' % context_data
114-
115- return tx
116-
117- class MonoTransaction (Transaction ):
118- def get_next_coin_number (self , coins ):
119- number = 0
120- for c in coins :
121- candidate = int (c ['id' ].split ('-' )[1 ])
122- if candidate > number : number = candidate
123- return number + 1
124-
125- def get_message (self , context_data , tx = '' ):
126- tx += """\
127- Recipient: %(fingerprint)s
128- Type: %(type)s
129- Coins:
130- """ % context_data
131-
132- try :
133- last_issuance = hdc .transactions .sender .issuance .Last (self .pgp_fingerprint ).get ()
134- except ValueError :
135- last_issuance = None
136-
137- context_data ['previous_idx' ] = 0 if not last_issuance else self .get_next_coin_number (last_issuance ['transaction' ]['coins' ])
138-
139- tx += self .get_mono_message (context_data )
140-
141- return tx
142-
143- def get_mono_message (self , context_data , tx = '' ):
144- return tx
145-
146- class Issue (MonoTransaction ):
147- def __init__ (self , pgp_fingerprint , amendment , coins , message = '' ):
148- super ().__init__ ('ISSUANCE' , pgp_fingerprint , message )
149- self .amendment = amendment
150- self .coins = coins
151-
152- def get_mono_message (self , context_data , tx = '' ):
153- context_data ['amendment' ] = self .amendment
154-
155- for idx , coin in enumerate (self .coins ):
156- context_data ['idx' ] = idx + context_data ['previous_idx' ]
157- context_data ['base' ], context_data ['power' ] = [int (x ) for x in coin .split (',' )]
158- tx += '%(fingerprint)s-%(idx)d-%(base)d-%(power)d-A-%(amendment)d\n ' % context_data
159-
160- return tx
161-
162- class Fusion (MonoTransaction ):
163- def __init__ (self , pgp_fingerprint , coins , message = '' ):
164- super ().__init__ ('FUSION' , pgp_fingerprint , message )
165- self .coins = coins
166-
167- def get_mono_message (self , context_data , tx = '' ):
168- context_data ['coins' ] = self .coins
169-
170- coins = []
171- for coin in context_data ['coins' ].split (',' ):
172- data = coin .split (':' )
173- issuer , numbers = data [0 ], data [1 :]
174- for number in numbers :
175- coins .append (ucoin .hdc .coins .View (issuer , int (number )).get ())
176-
177- __sum = 0
178- for coin in coins :
179- base , power = coin ['id' ].split ('-' )[2 :4 ]
180- __sum += int (base ) * 10 ** int (power )
181-
182- m = re .match (r'^(\d)(0*)$' , str (__sum ))
183-
184- if not m :
185- self .error = 'bad sum value %d' % __sum
186- return tx
187-
188- context_data ['base' ], context_data ['power' ] = int (m .groups ()[0 ]), len (m .groups ()[1 ])
189- tx += '%(fingerprint)s-%(previous_idx)d-%(base)d-%(power)d-F-%(number)d\n ' % context_data
190-
191- for coin in coins :
192- context_data .update (coin )
193- tx += '%(id)s, %(transaction)s\n ' % context_data
194-
195- return tx
196-
197- class CoinsWrapper (Wrapper ):
198- def __init__ (self , pgp_fingerprint ):
199- self .pgp_fingerprint = pgp_fingerprint
200-
201- class CoinsGet (CoinsWrapper ):
202- def __init__ (self , pgp_fingerprint , values ):
203- super ().__init__ (pgp_fingerprint )
204- self .values = values
205-
206- def __call__ (self ):
207- __list = hdc .coins .List (self .pgp_fingerprint ).get ()
208- coins = {}
209- for c in __list ['coins' ]:
210- for id in c ['ids' ]:
211- n ,b ,p ,t ,i = id .split ('-' )
212- amount = int (b ) * 10 ** int (p )
213- if amount not in coins : coins [amount ] = []
214- coins [amount ].append ({'issuer' : c ['issuer' ], 'number' : int (n ), 'base' : int (b ), 'power' : int (p ), 'type' : t , 'type_number' : int (i ), 'amount' : amount })
215-
216- issuers = {}
217- for v in self .values :
218- if v in coins and coins [v ]:
219- c = coins [v ].pop ()
220- issuers [c ['issuer' ]] = issuers .get (c ['issuer' ]) or []
221- issuers [c ['issuer' ]].append (c )
222- else :
223- raise ValueError ('You do not have enough coins of value (%d)' % v )
224-
225- res = ''
226- for i , issuer in enumerate (issuers ):
227- if i > 0 : res += ','
228- res += issuer
229- for c in issuers [issuer ]:
230- res += ':%(number)d' % c
231-
232- return res
233-
234- class CoinsList (CoinsWrapper ):
235- def __init__ (self , pgp_fingerprint , limit = None ):
236- super ().__init__ (pgp_fingerprint )
237- self .limit = limit
238-
239- def __call__ (self ):
240- __list = hdc .coins .List (self .pgp_fingerprint ).get ()
241- coins = []
242- __sum = 0
243-
244- for c in __list ['coins' ]:
245- for id in c ['ids' ]:
246- n ,b ,p ,t ,i = id .split ('-' )
247- amount = int (b ) * 10 ** int (p )
248- __dict = {'issuer' : c ['issuer' ], 'number' : int (n ), 'base' : int (b ), 'power' : int (p ), 'type' : t , 'type_number' : int (i ), 'amount' : amount }
249-
250- if not self .limit or self .limit >= amount :
251- coins .append (__dict )
252- __sum += amount
253-
254- return __sum , coins
29+ from . import transactions , coins
0 commit comments