Input range capability added to mmgen-txcreate
This commit is contained in:
parent
5171abf97f
commit
caef53909e
5 changed files with 58 additions and 49 deletions
|
|
@ -148,6 +148,8 @@ else: usage(help_data)
|
|||
|
||||
addr_list = parse_address_list(addr_list_arg)
|
||||
|
||||
if not addr_list: sys.exit(2)
|
||||
|
||||
if not 'quiet' in opts: do_license_msg()
|
||||
|
||||
# Interact with user:
|
||||
|
|
|
|||
|
|
@ -90,31 +90,21 @@ msg("Total unspent: %s BTC" % total)
|
|||
if 'info' in opts: sys.exit(0)
|
||||
|
||||
send_amt = sum(tx_out.values())
|
||||
msg("Total amount to spend: %s BTC" % send_amt)
|
||||
msg("%s unspent outputs total" % len(unspent))
|
||||
msg("Total amount to spend: %s BTC\n%s unspent outputs total" %
|
||||
(send_amt, len(unspent)))
|
||||
|
||||
while True:
|
||||
sel_nums = select_outputs(unspent,"Choose the outputs to spend: ")
|
||||
sel_unspent = [unspent[i] for i in sel_nums]
|
||||
mmgen_sel,other_sel = [],[]
|
||||
for i in sel_nums:
|
||||
if verify_mmgen_label(unspent[i].account,check_label_len=True):
|
||||
mmgen_sel.append(i)
|
||||
else:
|
||||
other_sel.append(i)
|
||||
msg("Selected outputs: %s" % " ".join(str(i) for i in sel_nums))
|
||||
sel_unspent = [unspent[i-1] for i in sel_nums]
|
||||
|
||||
if mmgen_sel and other_sel:
|
||||
keygen_args = [unspent[i].account.split()[0][9:] for i in mmgen_sel]
|
||||
msg("""
|
||||
NOTE: This transaction uses a mixture of both mmgen and non-mmgen inputs,
|
||||
which makes the signing process more complicated. When signing the
|
||||
transaction, keys for the non-mmgen inputs must be supplied in a separate
|
||||
file using mmgen-txsign's '-k' option. Alternatively, you may import the
|
||||
mmgen keys into the wallet.dat of your offline bitcoind, first running
|
||||
mmgen-keygen with address list '%s' to generate the keys. Finally, run
|
||||
mmgen-txsign with the '-f' option to force the use of wallet.dat as the
|
||||
key source.
|
||||
""".strip() % ",".join(sorted(keygen_args)))
|
||||
lbls = set([verify_mmgen_label(
|
||||
i.account,return_str=True,check_label_len=True)
|
||||
for i in sel_unspent])
|
||||
lbls.discard("")
|
||||
|
||||
if lbls and len(lbls) < len(sel_unspent):
|
||||
msg(txmsg['mixed_inputs'] % ", ".join(sorted(lbls)))
|
||||
if not user_confirm("Accept?"):
|
||||
continue
|
||||
|
||||
|
|
@ -138,8 +128,7 @@ for i in tx_out.keys(): tx_out[i] = float(tx_out[i])
|
|||
if change: tx_out[change_addr] = float(change)
|
||||
tx_hex = c.createrawtransaction(tx_in,tx_out)
|
||||
|
||||
msg("Transaction successfully created")
|
||||
prompt = "View decoded transaction?"
|
||||
prompt = "Transaction successfully created\nView decoded transaction?"
|
||||
if user_confirm(prompt,default_yes=False):
|
||||
view_tx_data(c,[i.__dict__ for i in sel_unspent],tx_hex)
|
||||
|
||||
|
|
|
|||
|
|
@ -149,7 +149,8 @@ def format_addr_data(addrlist, seed_chksum, opts):
|
|||
# allowed characters: A-Za-z0-9, plus '{}').
|
||||
""".format(max_wallet_addr_label_len,
|
||||
"', '".join(wallet_addr_label_symbols)).strip()
|
||||
data = [header + "\n"]
|
||||
data = []
|
||||
if not 'stdout' in opts: data.append(header + "\n")
|
||||
data.append("%s {" % seed_chksum.upper())
|
||||
|
||||
for el in addrlist:
|
||||
|
|
|
|||
40
mmgen/tx.py
40
mmgen/tx.py
|
|
@ -32,7 +32,19 @@ ERROR: This transaction produces change (%s BTC); however, no change
|
|||
address was specified. Total inputs - transaction fee = %s BTC.
|
||||
To create a valid transaction with no change address, send this sum to the
|
||||
specified recipient address.
|
||||
""".strip()
|
||||
""".strip(),
|
||||
'mixed_inputs': """
|
||||
NOTE: This transaction uses a mixture of both mmgen and non-mmgen inputs,
|
||||
which makes the signing process more complicated. When signing the
|
||||
transaction, keys for the non-mmgen inputs must be supplied in a separate
|
||||
file using the '-k' option of mmgen-txsign.
|
||||
|
||||
Alternatively, you may import the mmgen keys into the wallet.dat of your
|
||||
offline bitcoind, first generating the required keys with mmgen-keygen and
|
||||
then running mmgen-txsign with the '-f' option to force the use of
|
||||
wallet.dat as the key source.
|
||||
|
||||
Selected mmgen inputs: %s"""
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -321,22 +333,20 @@ def select_outputs(unspent,prompt):
|
|||
|
||||
while True:
|
||||
reply = my_raw_input(prompt).strip()
|
||||
if reply:
|
||||
selected = []
|
||||
try:
|
||||
selected = [int(i) - 1 for i in reply.split()]
|
||||
except: pass
|
||||
else:
|
||||
for i in selected:
|
||||
if i < 0 or i >= len(unspent):
|
||||
msg(
|
||||
"Input must be a number or numbers between 1 and %s" % len(unspent))
|
||||
break
|
||||
else: break
|
||||
|
||||
msg("'%s': Invalid input" % reply)
|
||||
if not reply: continue
|
||||
|
||||
from mmgen.utils import parse_address_list
|
||||
selected = parse_address_list(reply,sep=None)
|
||||
|
||||
if not selected: continue
|
||||
|
||||
if selected[-1] > len(unspent):
|
||||
msg("Inputs must be less than %s" % len(unspent))
|
||||
continue
|
||||
|
||||
return selected
|
||||
|
||||
return list(set(selected))
|
||||
|
||||
|
||||
def make_tx_out(rcpt_arg):
|
||||
|
|
|
|||
|
|
@ -277,38 +277,45 @@ def check_infile(f):
|
|||
msg("Requested input file '%s' is unreadable by you. Aborting" % f)
|
||||
sys.exit(1)
|
||||
|
||||
def validate_addr_num(n):
|
||||
|
||||
def _validate_addr_num(n):
|
||||
|
||||
try: n = int(n)
|
||||
except:
|
||||
msg("'%s': invalid argument for address" % n)
|
||||
sys.exit(2)
|
||||
return False
|
||||
|
||||
if n < 1:
|
||||
msg("'%s': address must be greater than zero" % n)
|
||||
sys.exit(2)
|
||||
return False
|
||||
|
||||
return n
|
||||
|
||||
|
||||
def parse_address_list(arg):
|
||||
def parse_address_list(arg,sep=","):
|
||||
|
||||
ret = []
|
||||
|
||||
for i in (arg.split(",")):
|
||||
for i in (arg.split(sep)):
|
||||
|
||||
j = i.split("-")
|
||||
|
||||
if len(j) == 1:
|
||||
i = validate_addr_num(i)
|
||||
i = _validate_addr_num(i)
|
||||
if not i: return False
|
||||
ret.append(i)
|
||||
elif len(j) == 2:
|
||||
beg = validate_addr_num(j[0])
|
||||
end = validate_addr_num(j[1])
|
||||
beg = _validate_addr_num(j[0])
|
||||
if not beg: return False
|
||||
end = _validate_addr_num(j[1])
|
||||
if not end: return False
|
||||
if end < beg:
|
||||
msg("'%s-%s': end of range less than beginning" % (beg,end))
|
||||
return False
|
||||
for k in range(beg,end+1): ret.append(k)
|
||||
else:
|
||||
msg("'%s': invalid argument for address range" % j)
|
||||
sys.exit(2)
|
||||
return False
|
||||
|
||||
return sorted(set(ret))
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue