• R/O
  • HTTP
  • SSH
  • HTTPS

bytom-spanner: Commit

Python based Bytom wallet tools


Commit MetaInfo

Revisione5969733256d162121350eedc3b9c8dc537c8ae3 (tree)
Time2020-04-24 21:14:36
AuthorDeKaiju <longjinglv@gmai...>
CommiterGitHub

Log Message

Merge pull request #9 from Bytom/asset

feat(asset): support transaction asset is not BTM

Change Summary

Incremental Difference

--- a/README.md
+++ b/README.md
@@ -23,7 +23,7 @@ Tool send BTM to large numbers of address
2323
2424 Usage:
2525 ```
26- spanner.py btmsender [-h] -n N -i I -a A [-c C] [-u] [-t T]
26+ spanner.py btmsender [-h] -n N -i I -a A [-s S] [-c C] [-u] [-t T]
2727 ```
2828 Options:
2929 ```
@@ -31,6 +31,7 @@ Options:
3131 -n node bytomd or vapord node address
3232 -i input transaction txt file
3333 -a account wallet account id
34+ -s asset_id transaction asset id
3435 -c count transaction output count
3536 -u use unconfirmed UTXO build transaction
3637 -t time_range the transaction will not be submitted into block after this height
--- a/btmsender/README.md
+++ b/btmsender/README.md
@@ -10,6 +10,7 @@ Options:
1010 -n node bytomd or vapord node address
1111 -i input transaction txt file
1212 -a account wallet account id
13+ -s asset_id transaction asset id
1314 -c count transaction output count
1415 -u use unconfirmed UTXO build transaction
1516 -t time_range the transaction will not be submitted into block after this height
@@ -17,7 +18,7 @@ Options:
1718
1819 Example:
1920 ```
20- spanner.py btmsender -i btmsender/btm.txt -a 0F0BV1OLG0A04 -p 123456 -c 1000 -u -t 96310
21+ spanner.py btmsender -i btmsender/btm.txt -a 0F0BV1OLG0A04 -s d50a426bdaaf1458d161aba4d8c3ebdd095eac7e1bbeb4a0252a3737ccf2d492 -p 123456 -c 1000 -u -t 96310
2122 ```
2223
2324 Transaction txt file format:
--- a/btmsender/btmsender.py
+++ b/btmsender/btmsender.py
@@ -3,7 +3,6 @@ from . import transaction
33
44
55 def sender():
6- node_address, file_path, account_id, password, output_count, use_unconfirmed, time_range = validation.validate_input()
7- btmsender = \
8- transaction.BTMSender(node_address, file_path, account_id, password, output_count, use_unconfirmed, time_range)
6+ _input = validation.validate_input()
7+ btmsender = transaction.BTMSender(_input)
98 btmsender.handle_input()
--- /dev/null
+++ b/btmsender/const.py
@@ -0,0 +1,3 @@
1+miner_fee = 40000000
2+max_output_count = 1500
3+btm_asset_id = 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'
--- a/btmsender/transaction.py
+++ b/btmsender/transaction.py
@@ -1,30 +1,22 @@
11 import os
22 import sys
3+
4+from . import const
35 from . import httprequest
46
57
68 class BTMSender:
7- miner_fee = 40000000
8- max_output_count = 1500
9-
10- def __init__(self, _node_address, _input_path, _account_id, _password, _output_count, _use_unconfirmed,
11- _time_range):
12- self.node_address = _node_address
13- self.input_path = _input_path
14- self.account_id = _account_id
15- self.password = _password
16- self.output_count = _output_count
17- self.use_unconfirmed = _use_unconfirmed
18- self.time_range = _time_range
9+ def __init__(self, _input):
10+ self.input = _input
1911
2012 def handle_input(self):
21- if self.output_count <= 0:
22- self.output_count = self.max_output_count
13+ if self.input.output_count <= 0:
14+ self.input.output_count = const.max_output_count
2315 lines = list()
24- with open(self.input_path, 'r', encoding='utf-8') as file:
16+ with open(self.input.input_path, 'r', encoding='utf-8') as file:
2517 for line in file:
2618 line = line.strip()
27- if len(lines) < self.output_count:
19+ if len(lines) < self.input.output_count:
2820 lines.append(line)
2921 else:
3022 self.handle_transaction(lines)
@@ -42,7 +34,7 @@ class BTMSender:
4234 tx_id = data['tx_id']
4335 if tx_id:
4436 print('transaction_id:\n' + tx_id)
45- write_lines_to_file(lines, self.input_path)
37+ write_lines_to_file(lines, self.input.input_path)
4638 else:
4739 print('Sign transaction is failed.Please check account password.')
4840 sys.exit(1)
@@ -56,24 +48,40 @@ class BTMSender:
5648 address = data[0]
5749 amount = int(data[1])
5850 amount_sum += amount
59- address_dict = get_address_dict(amount, address)
51+ address_dict = self.get_address_dict(amount, address)
6052 action_list.append(address_dict)
61- amount_sum += self.miner_fee
62- spend_dict = get_spend_dict(self.account_id, int(amount_sum), self.use_unconfirmed)
53+ fee_dict = self.get_spend_dict(const.miner_fee, const.btm_asset_id)
54+ spend_dict = self.get_spend_dict(int(amount_sum), self.input.asset_id)
6355 action_list.insert(0, spend_dict)
56+ action_list.insert(1, fee_dict)
6457 parameter = {'base_transaction': None, 'actions': action_list, 'ttl': 0}
65- if self.time_range != 0:
66- parameter.update(time_range=self.time_range)
67- return httprequest.post(self.node_address, 'build-transaction', parameter)
58+ if self.input.time_range != 0:
59+ parameter.update(time_range=self.input.time_range)
60+ return httprequest.post(self.input.node_address, 'build-transaction', parameter)
6861
6962 # parameter transaction: dict from build_transaction function return
7063 def sign_transaction(self, _transaction):
71- parameter = {'password': self.password, 'transaction': _transaction}
72- return httprequest.post(self.node_address, 'sign-transaction', parameter)
64+ parameter = {'password': self.input.password, 'transaction': _transaction}
65+ return httprequest.post(self.input.node_address, 'sign-transaction', parameter)
7366
7467 def submit_transaction(self, _transaction):
7568 parameter = {'raw_transaction': _transaction['transaction']['raw_transaction']}
76- return httprequest.post(self.node_address, 'submit-transaction', parameter)
69+ return httprequest.post(self.input.node_address, 'submit-transaction', parameter)
70+
71+ # control_address action
72+ def get_address_dict(self, _amount, _address):
73+ return {'amount': _amount,
74+ 'asset_id': self.input.asset_id,
75+ 'address': _address,
76+ 'type': 'control_address'}
77+
78+ # spend_account action
79+ def get_spend_dict(self, _amount_sum, _asset_id):
80+ return {'account_id': self.input.account_id,
81+ 'amount': _amount_sum,
82+ 'asset_id': _asset_id,
83+ 'type': 'spend_account',
84+ 'use_unconfirmed': self.input.use_unconfirmed}
7785
7886
7987 # write complete transactions lines to file
@@ -81,20 +89,3 @@ def write_lines_to_file(lines, _path):
8189 _path = os.path.abspath(os.path.dirname(_path)) + os.path.sep + 'completed.txt'
8290 with open(_path, 'a', encoding='utf-8') as file:
8391 file.write('\n'.join(lines) + '\n\n')
84-
85-
86-# control_address action
87-def get_address_dict(_amount, _address):
88- return {'amount': _amount,
89- 'asset_id': 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
90- 'address': _address,
91- 'type': 'control_address'}
92-
93-
94-# spend_account action
95-def get_spend_dict(_account_id, _amount_sum, _use_unconfirmed):
96- return {'account_id': _account_id,
97- 'amount': _amount_sum,
98- 'asset_id': 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
99- 'type': 'spend_account',
100- 'use_unconfirmed': _use_unconfirmed}
--- a/btmsender/validation.py
+++ b/btmsender/validation.py
@@ -1,9 +1,24 @@
11 import os
22 import sys
33 import argparse
4+
5+from . import const
46 from . import httprequest
57
68
9+class Input:
10+ def __init__(self, node_address, input_path, account_id, asset_id, password, output_count, use_unconfirmed,
11+ time_range):
12+ self.node_address = node_address
13+ self.input_path = input_path
14+ self.account_id = account_id
15+ self.asset_id = asset_id
16+ self.password = password
17+ self.output_count = output_count
18+ self.use_unconfirmed = use_unconfirmed
19+ self.time_range = time_range
20+
21+
722 def validate_address(node_address, line, address):
823 parameter = {'address': address}
924 data = httprequest.post(node_address, 'validate-address', parameter)
@@ -25,30 +40,42 @@ def get_input():
2540 parser.add_argument('-n', required=True, help='bytomd or vapord node api address')
2641 parser.add_argument('-i', required=True, help='transaction input file')
2742 parser.add_argument('-a', required=True, help='wallet account id')
43+ parser.add_argument('-s', type=str, default=const.btm_asset_id, help='transaction asset id')
2844 parser.add_argument('-c', type=int, default=0, help='transaction max output count')
2945 parser.add_argument('-u', action='store_true', help='use unconfirmed UTXO build transaction')
3046 parser.add_argument('-t', type=int, default=0,
3147 help='the transaction will not be submitted into block after this height')
3248 args = parser.parse_args()
33- return args.n, args.i, args.a, args.c, args.u, args.t
49+ _input = Input(node_address=args.n, input_path=args.i, account_id=args.a, asset_id=args.s, password="",
50+ output_count=args.c, use_unconfirmed=args.u, time_range=args.t)
51+ return _input
3452
3553
3654 def validate_input():
37- node_address, input_path, account_id, output_count, use_unconfirmed, time_range = get_input()
55+ _input = get_input()
3856 # relative path
39- file_path = os.path.abspath('.') + os.path.sep + input_path
57+ file_path = os.path.abspath('.') + os.path.sep + _input.input_path
4058 if not os.path.exists(file_path):
4159 # absolute path
42- file_path = input_path
60+ file_path = _input.input_path
4361 total_amount = 0
4462 # read file
4563 with open(file_path, 'r', encoding='utf-8') as file:
4664 for line in file:
4765 splits = line.strip().split(',')
48- validate_address(node_address, line, splits[0])
66+ validate_address(_input.node_address, line, splits[0])
4967 validate_amount(line, splits[1])
5068 total_amount += int(splits[1])
51- print('Transactions address and amount are valid.' +
52- '\nTotal amount is %.2f BTM(without gas).' % (total_amount / pow(10, 8)))
69+
70+ if _input.asset_id == const.btm_asset_id:
71+ print('Transactions address and amount are valid.' +
72+ '\nTotal amount is %.2f BTM(without gas).' % (total_amount / pow(10, 8)))
73+ else:
74+ print('Transactions address and amount are valid.' +
75+ '\nTotal amount is {total_amount} {asset_id}.'
76+ .format(total_amount=total_amount, asset_id=_input.asset_id))
77+
5378 password = input("Please input your account password:")
54- return node_address, file_path, account_id, password, output_count, use_unconfirmed, time_range
79+ _input.input_path = file_path
80+ _input.password = password
81+ return _input
Show on old repository browser