OSDN Git Service

utxos list divide not mature utxo
[bytom/bytom-spanner.git] / utxo-combiner / UnspentOutputs.py
1 import json
2 import os
3 import time
4
5 from Account import Account
6 from Asset import Asset
7 from Transaction import Action, Transaction
8
9
10 class UnspentOutputs(object):
11
12     @staticmethod
13     def get_block_height(connection):
14         response = connection.request("/get-block-count")
15
16         resp_json = json.loads(response.text)
17
18         if resp_json['status'] == 'success':
19             return resp_json['data']['block_count'], 1
20         elif resp_json['status'] == 'fail':
21             return resp_json['msg'], -1
22         else:
23             return resp_json, 0
24
25     @staticmethod
26     def list_UTXO(connection):
27         response = connection.request("/list-unspent-outputs")
28
29         resp_json = json.loads(response.text)
30
31         if resp_json['status'] == 'success':
32             return resp_json['data'], 1
33         elif resp_json['status'] == 'fail':
34             return resp_json['msg'], -1
35         else:
36             return resp_json, 0
37
38     @staticmethod
39     def list_mature_UTXO(connection):
40         result = []
41         utxos, ret = UnspentOutputs.list_UTXO(connection=connection)
42         block_height, ret_code = UnspentOutputs.get_block_height(connection=connection)
43         if ret == 1 and ret_code == 1:
44             for utxo in utxos:
45                 # append mature utxo to set
46                 if utxo['valid_height'] < block_height:
47                     result.append(utxo)
48         return result
49
50     @staticmethod
51     def list_by_account_asset(connection, account_alias, asset_alias):
52         utxos = UnspentOutputs.list_mature_UTXO(connection)
53         result = []
54         for utxo in utxos:
55             if utxo['account_alias'] == account_alias and utxo['asset_alias'] == asset_alias:
56                 result.append(utxo)
57
58         return result
59
60     @staticmethod
61     def find_little_utxo(max_amount=5000000000, utxos=[]):
62         result = []
63         for utxo in utxos:
64             if utxo['amount'] <= max_amount:
65                 result.append(utxo)
66         return result
67
68     @staticmethod
69     def combine_actions(connection, account_alias, asset_alias, max_amount=5000000000, size=20):
70         actions = []
71         gas_amount = 40000000
72         amount = 0
73         asset = Asset.get_asset_by_alias(connection, asset_alias)
74         asset_id = asset['id']
75         address = Account.find_address_by_alias(connection, account_alias)
76
77         result = UnspentOutputs.list_by_account_asset(connection, account_alias, asset_alias)
78         utxos = UnspentOutputs.find_little_utxo(max_amount=max_amount, utxos=result);
79
80         if utxos.__len__() <= size:
81             for utxo in utxos:
82                 actions.append(Action.unspent_output(output_id=utxo['id']))
83                 amount = amount + utxo['amount']
84         else:
85             for i in range(0, size):
86                 actions.append(Action.unspent_output(output_id=utxos[i]['id']))
87                 amount = amount + utxos[i]['amount']
88
89         # consider gas amount
90         if amount > gas_amount:
91             amount = amount - gas_amount
92         else:
93             print('\nAttention: The amount of all utxos is too little, less than tx gas.')
94             os._exit(0)
95         actions.append(Action.control_address(amount=amount, asset_id=asset_id, address=address))
96
97         return actions
98
99     @staticmethod
100     def combine_utxos(connection, account_alias, password, asset_alias='BTM', max_amount=5000000000, size=20):
101         actions = UnspentOutputs.combine_actions(connection, account_alias, asset_alias, max_amount, size)
102         # print(actions)
103         issuance = Transaction.build_transaction(connection, actions)
104         # print("issuance:", issuance)
105         # sign transaction
106         signed_raw_transaction = Transaction.sign_transaction(connection, password, issuance)
107         # print("signed_raw_transaction:", signed_raw_transaction)
108         # submit transaction
109         tx_submit = Transaction.submit_transaction(connection, signed_raw_transaction)
110         tx_id = tx_submit['tx_id']
111         print("tx_id:", tx_id)
112         if tx_id is not None:
113             print("success to combine utxos.")
114
115             print("wait combine tx to chain...(about 2.5 minutes)")
116
117             while True:
118                 tx, ret = Transaction.get_transaction(connection=connection, tx_id=tx_id)
119                 if ret == 1:
120                     # print(tx)
121                     if int(tx['block_index']) > 0:
122                         print("combine tx to chain. You can combine next utxos.")
123                         break
124                 elif ret == -1:
125                     print("tx:", tx)
126                     break
127                 time.sleep(2)
128         else:
129             print(actions)
130             print("issuance:", issuance)
131             print("signed_raw_transaction:", signed_raw_transaction)