-
Notifications
You must be signed in to change notification settings - Fork 15
/
send_nogui_noconf.py
158 lines (123 loc) · 4.55 KB
/
send_nogui_noconf.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
"""
Send a transaction from console, with no password nor confirmation asked.
To be used for unattended, automated processes.
This file takes optional arguments,
arg1: amount to send
arg2: recipient address
arg3: operation
arg4: OpenField data
arg5: wallet file
arg6: request confirmation for every transaction
args3,4,6 are not prompted if ran without args
"""
import base64
import sys
import time
import socks
from Cryptodome.Hash import SHA
from Cryptodome.Signature import PKCS1_v1_5
from bismuthclient import rpcconnections
from bisbasic import essentials, options
from bisbasic.essentials import fee_calculate
from polysign.signerfactory import SignerFactory
def connect():
if 'regnet' in config.version:
port = 3030
elif 'testnet' in config.version:
port = 2829
else:
port = 5658
return rpcconnections.Connection(("127.0.0.1", int(port)))
if __name__ == "__main__":
config = options.Get()
config.read()
try:
wallet_file = sys.argv[5]
except:
wallet_file = input("Path to wallet: ")
try:
request_confirmation = sys.argv[6]
except:
request_confirmation = False
key, public_key_readable, private_key_readable, encrypted, unlocked, public_key_b64encoded, address, keyfile = essentials.keys_load_new(wallet_file)
if encrypted:
key, private_key_readable = essentials.keys_unlock(private_key_readable)
print(f'Number of arguments: {len(sys.argv)} arguments.')
print(f'Argument list: {"".join(sys.argv)}')
print(f'Using address: {address}')
# get balance
s = connect()
s._send ("balanceget")
s._send (address) # change address here to view other people's transactions
stats_account = s._receive()
balance = stats_account[0]
print("Transaction address: %s" % address)
print("Transaction address balance: %s" % balance)
try:
amount_input = sys.argv[1]
except IndexError:
amount_input = input("Amount: ")
try:
recipient_input = sys.argv[2]
except IndexError:
recipient_input = input("Recipient: ")
if not SignerFactory.address_is_valid(recipient_input):
print("Wrong address format")
sys.exit(1)
try:
operation_input = sys.argv[3]
except IndexError:
operation_input = ""
try:
openfield_input = sys.argv[4]
except IndexError:
openfield_input = ""
fee = fee_calculate(openfield_input)
print("Fee: %s" % fee)
if request_confirmation:
confirm = input("Confirm (y/n): ")
if confirm != 'y':
print("Transaction cancelled, user confirmation failed")
exit(1)
try:
float(amount_input)
is_float = 1
except ValueError:
is_float = 0
sys.exit(1)
timestamp = '%.2f' % (time.time() - 5) #remote proofing
# TODO: use transaction object, no dup code for buffer assembling
transaction = (str(timestamp), str(address), str(recipient_input), '%.8f' % float(amount_input), str(operation_input), str(openfield_input)) # this is signed
# TODO: use polysign here
h = SHA.new(str(transaction).encode("utf-8"))
signer = PKCS1_v1_5.new(key)
signature = signer.sign(h)
signature_enc = base64.b64encode(signature)
txid = signature_enc[:56]
print(f"Encoded Signature: {signature_enc.decode('utf-8')}")
print(f"Transaction ID: {txid.decode('utf-8')}")
verifier = PKCS1_v1_5.new(key)
if verifier.verify(h, signature):
if float(amount_input) < 0:
print("Signature OK, but cannot use negative amounts")
elif float(amount_input) + float(fee) > float(balance):
print("Mempool: Sending more than owned")
else:
tx_submit = (str (timestamp), str (address), str (recipient_input), '%.8f' % float (amount_input), str (signature_enc.decode ("utf-8")), str (public_key_b64encoded.decode("utf-8")), str (operation_input), str (openfield_input))
while True:
try:
s._send("mpinsert")
s._send (tx_submit)
reply = s._receive()
print ("Client: {}".format (reply))
if reply != "*": # response can be empty due to different timeout setting
break
else:
print("Connection cut, retrying")
except Exception as e:
print(f"A problem occurred: {e}, retrying")
s = connect()
pass
else:
print("Invalid signature")
s.close()