Browse Source

Added address list+range capability to mmgen-addrimport
Bugfixes, cleanups

philemon 11 years ago
parent
commit
149121994e
21 changed files with 195 additions and 177 deletions
  1. 19 17
      mmgen-addrgen
  2. 8 12
      mmgen-addrimport
  3. 5 5
      mmgen-passchg
  4. 6 6
      mmgen-txcreate
  5. 4 4
      mmgen-txsend
  6. 3 3
      mmgen-txsign
  7. 3 3
      mmgen-walletchk
  8. 3 3
      mmgen-walletgen
  9. 3 3
      mmgen/Opts.py
  10. 3 3
      mmgen/__init__.py
  11. 12 9
      mmgen/addr.py
  12. 4 4
      mmgen/bitcoin.py
  13. 4 3
      mmgen/config.py
  14. 3 3
      mmgen/license.py
  15. 3 3
      mmgen/mn_electrum.py
  16. 7 7
      mmgen/mn_tirosh.py
  17. 3 3
      mmgen/mnemonic.py
  18. 4 4
      mmgen/rpc/proxy.py
  19. 64 17
      mmgen/tx.py
  20. 31 62
      mmgen/utils.py
  21. 3 3
      mmgen/walletgen.py

+ 19 - 17
mmgen-addrgen

@@ -2,23 +2,23 @@
 #
 #
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
-# 
+#
 # This program is free software: you can redistribute it and/or modify
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation, either version 3 of the License, or
 # the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 # (at your option) any later version.
-# 
+#
 # This program is distributed in the hope that it will be useful,
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 # GNU General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU General Public License
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 
 """
 """
-mmgen-addrgen: Generate a range of addresses from a mmgen deterministic 
-               wallet.
+mmgen-addrgen: Generate a list or range of addresses from a mmgen
+               deterministic wallet.
                Call as 'btc-keygen' to allow key generation as well.
                Call as 'btc-keygen' to allow key generation as well.
 """
 """
 
 
@@ -37,21 +37,21 @@ if invoked_as == "keygen":
 	extra_help_data = (
 	extra_help_data = (
 		"\n-A, --no-addresses       Print only secret keys, no addresses",
 		"\n-A, --no-addresses       Print only secret keys, no addresses",
 		"\n-x, --b16                Print secret keys in hexadecimal too",
 		"\n-x, --b16                Print secret keys in hexadecimal too",
-		".\nBy default, both addresses and secret keys are generated"
+		"\nBy default, both addresses and secret keys are generated."
 	)
 	)
 else: extra_help_data = ("","","")
 else: extra_help_data = ("","","")
 
 
 help_data = {
 help_data = {
 	'prog_name': sys.argv[0].split("/")[-1],
 	'prog_name': sys.argv[0].split("/")[-1],
-	'desc': """Generate a range of {} from a {} wallet, mnemonic,
-                  seed or password""".format(gen_what,proj_name),
-	'usage':"[opts] [infile] <address range>",
+	'desc': """Generate a list or range of {} from a {} wallet,
+	              mnemonic, seed or password""".format(gen_what,proj_name),
+	'usage':"[opts] [infile] <address list>",
 	'options': """
 	'options': """
 -h, --help               Print this help message{}
 -h, --help               Print this help message{}
 -d, --outdir          d  Specify an alternate directory 'd' for output
 -d, --outdir          d  Specify an alternate directory 'd' for output
 -e, --echo-passphrase    Display passphrase or mnemonic on screen upon entry
 -e, --echo-passphrase    Display passphrase or mnemonic on screen upon entry
 -K, --no-keyconv         Use internal libraries for address generation
 -K, --no-keyconv         Use internal libraries for address generation
-                         instead of 'keyconv' 
+                         instead of 'keyconv'
 -l, --seed-len        N  Length of seed.  Options: {}
 -l, --seed-len        N  Length of seed.  Options: {}
                          (default: {})
                          (default: {})
 -p, --hash-preset     p  Use scrypt.hash() parameters from preset 'p'
 -p, --hash-preset     p  Use scrypt.hash() parameters from preset 'p'
@@ -67,9 +67,11 @@ help_data = {
 -m, --from-mnemonic      Generate {W} from an electrum-like mnemonic
 -m, --from-mnemonic      Generate {W} from an electrum-like mnemonic
 -s, --from-seed          Generate {W} from a seed in .{S} format
 -s, --from-seed          Generate {W} from a seed in .{S} format
 
 
-Address range may be a single number or a range in the form XXX-YYY{}
+Addresses are given in a comma-separated list.  Hyphen-separated
+ranges are also allowed.{}
 
 
-If available, external 'keyconv' program will be used for address generation
+If available, the external 'keyconv' program will be used for address
+generation.
 
 
 Data for the --from-<what> options will be taken from <infile> if <infile>
 Data for the --from-<what> options will be taken from <infile> if <infile>
 is specified.  Otherwise, the user will be prompted to enter the data.
 is specified.  Otherwise, the user will be prompted to enter the data.
@@ -138,13 +140,13 @@ if   len(cmd_args) == 1 and (
 			'from_mnemonic' in opts or
 			'from_mnemonic' in opts or
 			'from_brain' in opts or
 			'from_brain' in opts or
 			'from_seed' in opts
 			'from_seed' in opts
-		): infile,addr_range = "",cmd_args[0]
+		): infile,addr_list_arg = "",cmd_args[0]
 elif len(cmd_args) == 2:
 elif len(cmd_args) == 2:
-	infile,addr_range = cmd_args
+	infile,addr_list_arg = cmd_args
 	check_infile(infile)
 	check_infile(infile)
 else: usage(help_data)
 else: usage(help_data)
 
 
-start,end = parse_address_range(addr_range)
+addr_list = parse_address_list(addr_list_arg)
 
 
 if not 'quiet' in opts: do_license_msg()
 if not 'quiet' in opts: do_license_msg()
 
 
@@ -161,7 +163,7 @@ else:
 
 
 seed          = get_seed(infile,opts)
 seed          = get_seed(infile,opts)
 seed_id       = make_chksum_8(seed)
 seed_id       = make_chksum_8(seed)
-addr_data     = generate_addrs(seed, range(start, end+1), opts)
+addr_data     = generate_addrs(seed, addr_list, opts)
 addr_data_str = format_addr_data(addr_data, seed_id, opts)
 addr_data_str = format_addr_data(addr_data, seed_id, opts)
 
 
 # Output data:
 # Output data:
@@ -173,4 +175,4 @@ if 'stdout' in opts:
 elif not sys.stdout.isatty():
 elif not sys.stdout.isatty():
 	write_to_stdout(addr_data_str,"secret keys",confirm=False)
 	write_to_stdout(addr_data_str,"secret keys",confirm=False)
 else:
 else:
-	write_addr_data_to_file(seed, addr_data_str, start, end, opts)
+	write_addr_data_to_file(seed, addr_data_str, addr_list, opts)

+ 8 - 12
mmgen-addrimport

@@ -2,17 +2,17 @@
 #
 #
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
-# 
+#
 # This program is free software: you can redistribute it and/or modify
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation, either version 3 of the License, or
 # the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 # (at your option) any later version.
-# 
+#
 # This program is distributed in the hope that it will be useful,
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 # GNU General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU General Public License
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 
@@ -25,7 +25,8 @@ import sys
 from mmgen.Opts   import *
 from mmgen.Opts   import *
 from mmgen.config import *
 from mmgen.config import *
 from mmgen.license import *
 from mmgen.license import *
-from mmgen.utils import check_infile,parse_addrs_file,confirm_or_exit
+from mmgen.utils import check_infile,confirm_or_exit
+from mmgen.tx import connect_to_bitcoind,parse_addrs_file
 
 
 help_data = {
 help_data = {
 	'prog_name': sys.argv[0].split("/")[-1],
 	'prog_name': sys.argv[0].split("/")[-1],
@@ -50,22 +51,17 @@ check_infile(cmd_args[0])
 
 
 seed_id,addr_data = parse_addrs_file(cmd_args[0])
 seed_id,addr_data = parse_addrs_file(cmd_args[0])
 
 
-from mmgen.tx import check_wallet_addr_label,connect_to_bitcoind
-
-for i in addr_data:
-	i[2] = " ".join(i[2:]) if len(i) > 2 else ""
-	check_wallet_addr_label(i[2])
-
 c = connect_to_bitcoind(http_timeout=3600)
 c = connect_to_bitcoind(http_timeout=3600)
 
 
 message = """
 message = """
-Importing addresses can take a long time, up to 30 min. per address on a
+Importing addresses can take a long time - up to 30 min. per address on a
 low-powered computer such as a netbook.
 low-powered computer such as a netbook.
 """
 """
 confirm_or_exit(message, "continue", expect="YES")
 confirm_or_exit(message, "continue", expect="YES")
 
 
 for n,i in enumerate(addr_data):
 for n,i in enumerate(addr_data):
-	label = "%s:%s %s" % (seed_id,str(i[0]),i[2])
+	comment = " " + i[2] if len(i) == 3 else ""
+	label = "%s:%s%s" % (seed_id,i[0],comment)
 	msg("Importing %-6s %-34s (%s)" % (
 	msg("Importing %-6s %-34s (%s)" % (
 				("%s/%s:" % (n+1,len(addr_data))),
 				("%s/%s:" % (n+1,len(addr_data))),
 				i[1], label)
 				i[1], label)

+ 5 - 5
mmgen-passchg

@@ -2,17 +2,17 @@
 #
 #
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
-# 
+#
 # This program is free software: you can redistribute it and/or modify
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation, either version 3 of the License, or
 # the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 # (at your option) any later version.
-# 
+#
 # This program is distributed in the hope that it will be useful,
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 # GNU General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU General Public License
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 """
 """
@@ -33,7 +33,7 @@ help_data = {
 	'options': """
 	'options': """
 -h, --help                  Print this help message
 -h, --help                  Print this help message
 -d, --outdir             d  Specify an alternate directory 'd' for output
 -d, --outdir             d  Specify an alternate directory 'd' for output
--k, --keep-old-passphrase   Keep old passphrase (use when changing hash 
+-k, --keep-old-passphrase   Keep old passphrase (use when changing hash
                             strength or label only)
                             strength or label only)
 -L, --label              l  Change the wallet's label to 'l'
 -L, --label              l  Change the wallet's label to 'l'
 -p, --hash-preset        p  Change scrypt.hash() parameters to preset 'p'
 -p, --hash-preset        p  Change scrypt.hash() parameters to preset 'p'
@@ -70,7 +70,7 @@ passwd = " ".join(get_words("","",("Enter %spassphrase: " % oldp),opts))
 key = make_key(passwd, salt, hash_preset)
 key = make_key(passwd, salt, hash_preset)
 seed = decrypt_seed(enc_seed, key, seed_id, key_id)
 seed = decrypt_seed(enc_seed, key, seed_id, key_id)
 
 
-changed = {} 
+changed = {}
 
 
 if 'label' in opts:
 if 'label' in opts:
 	if opts['label'] != label:
 	if opts['label'] != label:

+ 6 - 6
mmgen-txcreate

@@ -2,17 +2,17 @@
 #
 #
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
-# 
+#
 # This program is free software: you can redistribute it and/or modify
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation, either version 3 of the License, or
 # the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 # (at your option) any later version.
-# 
+#
 # This program is distributed in the hope that it will be useful,
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 # GNU General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU General Public License
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 """
 """
@@ -62,10 +62,10 @@ if debug:
 	print "Cmd args:              %s" % repr(cmd_args)
 	print "Cmd args:              %s" % repr(cmd_args)
 
 
 if len(cmd_args) == 3:
 if len(cmd_args) == 3:
-	rcpt_arg,tx_fee,change_addr = cmd_args	
+	rcpt_arg,tx_fee,change_addr = cmd_args
 	check_address(change_addr)
 	check_address(change_addr)
 elif len(cmd_args) == 2:
 elif len(cmd_args) == 2:
-	rcpt_arg,tx_fee = cmd_args	
+	rcpt_arg,tx_fee = cmd_args
 	change_addr = ""
 	change_addr = ""
 elif len(cmd_args) == 0 and 'info' in opts:
 elif len(cmd_args) == 0 and 'info' in opts:
 	pass
 	pass
@@ -98,7 +98,7 @@ while True:
 	sel_unspent = [unspent[i] for i in sel_nums]
 	sel_unspent = [unspent[i] for i in sel_nums]
 	mmgen_sel,other_sel = [],[]
 	mmgen_sel,other_sel = [],[]
 	for i in sel_nums:
 	for i in sel_nums:
-		if verify_mmgen_label(unspent[i].account):
+		if verify_mmgen_label(unspent[i].account,check_label_len=True):
 			mmgen_sel.append(i)
 			mmgen_sel.append(i)
 		else:
 		else:
 			other_sel.append(i)
 			other_sel.append(i)

+ 4 - 4
mmgen-txsend

@@ -2,21 +2,21 @@
 #
 #
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
-# 
+#
 # This program is free software: you can redistribute it and/or modify
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation, either version 3 of the License, or
 # the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 # (at your option) any later version.
-# 
+#
 # This program is distributed in the hope that it will be useful,
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 # GNU General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU General Public License
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 """
 """
-mmgen-txsend: Broadcast a Bitcoin transaction to the network 
+mmgen-txsend: Broadcast a Bitcoin transaction to the network
 """
 """
 
 
 import sys
 import sys

+ 3 - 3
mmgen-txsign

@@ -2,17 +2,17 @@
 #
 #
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
-# 
+#
 # This program is free software: you can redistribute it and/or modify
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation, either version 3 of the License, or
 # the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 # (at your option) any later version.
-# 
+#
 # This program is distributed in the hope that it will be useful,
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 # GNU General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU General Public License
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 """
 """

+ 3 - 3
mmgen-walletchk

@@ -2,17 +2,17 @@
 #
 #
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
-# 
+#
 # This program is free software: you can redistribute it and/or modify
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation, either version 3 of the License, or
 # the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 # (at your option) any later version.
-# 
+#
 # This program is distributed in the hope that it will be useful,
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 # GNU General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU General Public License
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 """
 """

+ 3 - 3
mmgen-walletgen

@@ -2,17 +2,17 @@
 #
 #
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
-# 
+#
 # This program is free software: you can redistribute it and/or modify
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation, either version 3 of the License, or
 # the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 # (at your option) any later version.
-# 
+#
 # This program is distributed in the hope that it will be useful,
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 # GNU General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU General Public License
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 """
 """

+ 3 - 3
mmgen/Opts.py

@@ -2,17 +2,17 @@
 #
 #
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
-# 
+#
 # This program is free software: you can redistribute it and/or modify
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation, either version 3 of the License, or
 # the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 # (at your option) any later version.
-# 
+#
 # This program is distributed in the hope that it will be useful,
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 # GNU General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU General Public License
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 

+ 3 - 3
mmgen/__init__.py

@@ -2,17 +2,17 @@
 #
 #
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
-# 
+#
 # This program is free software: you can redistribute it and/or modify
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation, either version 3 of the License, or
 # the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 # (at your option) any later version.
-# 
+#
 # This program is distributed in the hope that it will be useful,
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 # GNU General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU General Public License
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 """
 """

+ 12 - 9
mmgen/addr.py

@@ -2,17 +2,17 @@
 #
 #
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
-# 
+#
 # This program is free software: you can redistribute it and/or modify
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation, either version 3 of the License, or
 # the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 # (at your option) any later version.
-# 
+#
 # This program is distributed in the hope that it will be useful,
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 # GNU General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU General Public License
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 """
 """
@@ -60,7 +60,7 @@ def generate_addrs(seed, addrnums, opts):
 
 
 	Supported options:
 	Supported options:
 		print_secret, no_addresses, no_keyconv, gen_what
 		print_secret, no_addresses, no_keyconv, gen_what
-	
+
 	Addresses are returned in a list of dictionaries with the following keys:
 	Addresses are returned in a list of dictionaries with the following keys:
 		num, sec, wif, addr
 		num, sec, wif, addr
 	"""
 	"""
@@ -145,9 +145,10 @@ def format_addr_data(addrlist, seed_chksum, opts):
 # This file is editable.
 # This file is editable.
 # Everything following a hash symbol '#' is ignored.
 # Everything following a hash symbol '#' is ignored.
 # A label may be added to the right of each address, and it will be
 # A label may be added to the right of each address, and it will be
-# appended to the bitcoind wallet label upon import (max. 24 characters,
+# appended to the bitcoind wallet label upon import (max. {} characters,
 # allowed characters: A-Za-z0-9, plus '{}').
 # allowed characters: A-Za-z0-9, plus '{}').
-""".format("', '".join(wallet_addr_label_symbols)).strip()
+""".format(max_wallet_addr_label_len,
+		"', '".join(wallet_addr_label_symbols)).strip()
 	data = [header + "\n"]
 	data = [header + "\n"]
 	data.append("%s {" % seed_chksum.upper())
 	data.append("%s {" % seed_chksum.upper())
 
 
@@ -175,16 +176,18 @@ def format_addr_data(addrlist, seed_chksum, opts):
 	return "\n".join(data) + "\n"
 	return "\n".join(data) + "\n"
 
 
 
 
-def write_addr_data_to_file(seed, data, start, end, opts):
+def write_addr_data_to_file(seed, data, addr_list, opts):
 
 
 	if 'print_addresses_only' in opts: ext = "addrs"
 	if 'print_addresses_only' in opts: ext = "addrs"
 	elif 'no_addresses' in opts:       ext = "keys"
 	elif 'no_addresses' in opts:       ext = "keys"
 	else:                              ext = "akeys"
 	else:                              ext = "akeys"
 
 
 	if 'b16' in opts: ext = ext.replace("keys","xkeys")
 	if 'b16' in opts: ext = ext.replace("keys","xkeys")
-
+	beg = addr_list[0]
+	end = addr_list[-1]
+	sep = "-" if (end - beg == len(addr_list) - 1) else ".."
 	from mmgen.utils import write_to_file, make_chksum_8, msg
 	from mmgen.utils import write_to_file, make_chksum_8, msg
-	addr_range = str(start) if start == end else "%s-%s" % (start,end)
+	addr_range = beg if beg == end else "%s%s%s" % (beg,sep,end)
 	outfile = "{}[{}].{}".format(make_chksum_8(seed),addr_range,ext)
 	outfile = "{}[{}].{}".format(make_chksum_8(seed),addr_range,ext)
 	if 'outdir' in opts:
 	if 'outdir' in opts:
 		outfile = "%s/%s" % (opts['outdir'], outfile)
 		outfile = "%s/%s" % (opts['outdir'], outfile)

+ 4 - 4
mmgen/bitcoin.py

@@ -2,17 +2,17 @@
 #
 #
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
-# 
+#
 # This program is free software: you can redistribute it and/or modify
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation, either version 3 of the License, or
 # the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 # (at your option) any later version.
-# 
+#
 # This program is distributed in the hope that it will be useful,
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 # GNU General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU General Public License
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 """
 """
@@ -74,7 +74,7 @@ def verify_addr(addr):
 
 
 # 	addr,lz = addr[1:],0
 # 	addr,lz = addr[1:],0
 # 	while addr[0] == "1": addr = addr[1:]; lz += 1
 # 	while addr[0] == "1": addr = addr[1:]; lz += 1
-# 		
+#
 #  	addr_hex = lz * "00" + hex(_b58tonum(addr))[2:].rstrip("L")
 #  	addr_hex = lz * "00" + hex(_b58tonum(addr))[2:].rstrip("L")
 
 
 # 	if len(addr_hex) != 48:
 # 	if len(addr_hex) != 48:

+ 4 - 3
mmgen/config.py

@@ -2,17 +2,17 @@
 #
 #
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
-# 
+#
 # This program is free software: you can redistribute it and/or modify
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation, either version 3 of the License, or
 # the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 # (at your option) any later version.
-# 
+#
 # This program is distributed in the hope that it will be useful,
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 # GNU General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU General Public License
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 """
 """
@@ -49,3 +49,4 @@ hash_presets = {
 	'5': [16, 8, 16],
 	'5': [16, 8, 16],
 }
 }
 wallet_addr_label_symbols = ".","_",",","-"," "
 wallet_addr_label_symbols = ".","_",",","-"," "
+max_wallet_addr_label_len = 16

+ 3 - 3
mmgen/license.py

@@ -2,17 +2,17 @@
 #
 #
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
-# 
+#
 # This program is free software: you can redistribute it and/or modify
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation, either version 3 of the License, or
 # the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 # (at your option) any later version.
-# 
+#
 # This program is distributed in the hope that it will be useful,
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 # GNU General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU General Public License
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 """
 """

+ 3 - 3
mmgen/mn_electrum.py

@@ -2,17 +2,17 @@
 #
 #
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
-# 
+#
 # This program is free software: you can redistribute it and/or modify
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation, either version 3 of the License, or
 # the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 # (at your option) any later version.
-# 
+#
 # This program is distributed in the hope that it will be useful,
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 # GNU General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU General Public License
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 # ------------------------------------------------------------------------------
 # ------------------------------------------------------------------------------

+ 7 - 7
mmgen/mn_tirosh.py

@@ -2,17 +2,17 @@
 #
 #
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
-# 
+#
 # This program is free software: you can redistribute it and/or modify
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation, either version 3 of the License, or
 # the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 # (at your option) any later version.
-# 
+#
 # This program is distributed in the hope that it will be useful,
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 # GNU General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU General Public License
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 # ------------------------------------------------------------------------------
 # ------------------------------------------------------------------------------
@@ -21,7 +21,7 @@
 # ------------------------------------------------------------------------------
 # ------------------------------------------------------------------------------
 # Oren Tirosh is no longer maintaining the original version of this
 # Oren Tirosh is no longer maintaining the original version of this
 # project.
 # project.
-# 
+#
 # Stephen Paul Weber likes it and is making it accessible on GitHub.
 # Stephen Paul Weber likes it and is making it accessible on GitHub.
 # https://github.com/singpolyma/mnemonicode
 # https://github.com/singpolyma/mnemonicode
 # ------------------------------------------------------------------------------
 # ------------------------------------------------------------------------------
@@ -29,17 +29,17 @@
 # ------------------------------------------------------------------------------
 # ------------------------------------------------------------------------------
 # Oren Tirosh wordlist
 # Oren Tirosh wordlist
 # Copyright (c) 2000  Oren Tirosh <oren@hishome.net>
 # Copyright (c) 2000  Oren Tirosh <oren@hishome.net>
-# 
+#
 # Permission is hereby granted, free of charge, to any person obtaining a copy
 # Permission is hereby granted, free of charge, to any person obtaining a copy
 # of this software and associated documentation files (the "Software"), to deal
 # of this software and associated documentation files (the "Software"), to deal
 # in the Software without restriction, including without limitation the rights
 # in the Software without restriction, including without limitation the rights
 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 # copies of the Software, and to permit persons to whom the Software is
 # copies of the Software, and to permit persons to whom the Software is
 # furnished to do so, subject to the following conditions:
 # furnished to do so, subject to the following conditions:
-# 
+#
 # The above copyright notice and this permission notice shall be included in
 # The above copyright notice and this permission notice shall be included in
 # all copies or substantial portions of the Software.
 # all copies or substantial portions of the Software.
-# 
+#
 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE

+ 3 - 3
mmgen/mnemonic.py

@@ -2,17 +2,17 @@
 #
 #
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
-# 
+#
 # This program is free software: you can redistribute it and/or modify
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation, either version 3 of the License, or
 # the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 # (at your option) any later version.
-# 
+#
 # This program is distributed in the hope that it will be useful,
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 # GNU General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU General Public License
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 """
 """

+ 4 - 4
mmgen/rpc/proxy.py

@@ -72,11 +72,11 @@ class AuthServiceProxy(object):
         authpair = authpair.encode('utf8')
         authpair = authpair.encode('utf8')
         self.__authhdr = "Basic ".encode('utf8') + base64.b64encode(authpair)
         self.__authhdr = "Basic ".encode('utf8') + base64.b64encode(authpair)
         if self.__url.scheme == 'https':
         if self.__url.scheme == 'https':
-            self.__conn = httplib.HTTPSConnection(self.__url.hostname, port, None, None,False,
-                                             http_timeout)
+            self.__conn = httplib.HTTPSConnection(self.__url.hostname, port,
+					None, None, False, http_timeout)
         else:
         else:
-            self.__conn = httplib.HTTPConnection(self.__url.hostname, port, False,
-                                             http_timeout)
+            self.__conn = httplib.HTTPConnection(self.__url.hostname, port,
+					False, http_timeout)
 
 
     def __getattr__(self, name):
     def __getattr__(self, name):
         if self.__serviceName != None:
         if self.__serviceName != None:

+ 64 - 17
mmgen/tx.py

@@ -2,17 +2,17 @@
 #
 #
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
-# 
+#
 # This program is free software: you can redistribute it and/or modify
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation, either version 3 of the License, or
 # the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 # (at your option) any later version.
-# 
+#
 # This program is distributed in the hope that it will be useful,
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 # GNU General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU General Public License
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 """
 """
@@ -73,11 +73,11 @@ def check_btc_amt(send_amt):
 	except:
 	except:
 		msg("%s: Invalid amount" % send_amt)
 		msg("%s: Invalid amount" % send_amt)
 		sys.exit(3)
 		sys.exit(3)
-	
+
 	if retval.as_tuple()[-1] < -8:
 	if retval.as_tuple()[-1] < -8:
 		msg("%s: Too many decimal places in amount" % send_amt)
 		msg("%s: Too many decimal places in amount" % send_amt)
 		sys.exit(3)
 		sys.exit(3)
-	
+
 	return trim_exponent(retval)
 	return trim_exponent(retval)
 
 
 
 
@@ -111,7 +111,7 @@ def print_tx_to_file(tx,sel_unspent,send_amt,opts):
 	sig_data = [{"txid":i.txid,"vout":i.vout,"scriptPubKey":i.scriptPubKey}
 	sig_data = [{"txid":i.txid,"vout":i.vout,"scriptPubKey":i.scriptPubKey}
 					for i in sel_unspent]
 					for i in sel_unspent]
 	tx_id = make_chksum_6(unhexlify(tx)).upper()
 	tx_id = make_chksum_6(unhexlify(tx)).upper()
-	outfile = "%s[%s].tx" % (tx_id,send_amt)
+	outfile = "tx_%s[%s].raw" % (tx_id,send_amt)
 	if 'outdir' in opts:
 	if 'outdir' in opts:
 		outfile = "%s/%s" % (opts['outdir'], outfile)
 		outfile = "%s/%s" % (opts['outdir'], outfile)
 	metadata = "%s %s %s" % (tx_id, send_amt, make_timestamp())
 	metadata = "%s %s %s" % (tx_id, send_amt, make_timestamp())
@@ -125,7 +125,7 @@ def print_tx_to_file(tx,sel_unspent,send_amt,opts):
 
 
 def print_signed_tx_to_file(tx,sig_tx,metadata,opts):
 def print_signed_tx_to_file(tx,sig_tx,metadata,opts):
 	tx_id = make_chksum_6(unhexlify(tx)).upper()
 	tx_id = make_chksum_6(unhexlify(tx)).upper()
-	outfile = "{}[{}].txsig".format(*metadata[:2])
+	outfile = "tx_{}[{}].sig".format(*metadata[:2])
 	if 'outdir' in opts:
 	if 'outdir' in opts:
 		outfile = "%s/%s" % (opts['outdir'], outfile)
 		outfile = "%s/%s" % (opts['outdir'], outfile)
 	data = "%s\n%s\n" % (" ".join(metadata),sig_tx)
 	data = "%s\n%s\n" % (" ".join(metadata),sig_tx)
@@ -134,7 +134,7 @@ def print_signed_tx_to_file(tx,sig_tx,metadata,opts):
 
 
 
 
 def print_sent_tx_to_file(tx,metadata,opts):
 def print_sent_tx_to_file(tx,metadata,opts):
-	outfile = "{}[{}].txout".format(*metadata[:2])
+	outfile = "tx_{}[{}].out".format(*metadata[:2])
 	if 'outdir' in opts:
 	if 'outdir' in opts:
 		outfile = "%s/%s" % (opts['outdir'], outfile)
 		outfile = "%s/%s" % (opts['outdir'], outfile)
 	write_to_file(outfile,tx+"\n",confirm=False)
 	write_to_file(outfile,tx+"\n",confirm=False)
@@ -205,7 +205,7 @@ View options: [g]roup, show [m]mgen addr
 			elif reply == 'd': unspent.sort(s_addr); sort = "address"; break
 			elif reply == 'd': unspent.sort(s_addr); sort = "address"; break
 			elif reply == 'A': unspent.sort(s_age);  sort = "age"; break
 			elif reply == 'A': unspent.sort(s_age);  sort = "age"; break
 			elif reply == 'M': unspent.sort(s_mmgen); mmaddr,sort=True,"mmgen"; break
 			elif reply == 'M': unspent.sort(s_mmgen); mmaddr,sort=True,"mmgen"; break
-			elif reply == 'r': 
+			elif reply == 'r':
 				reverse = False if reverse else True
 				reverse = False if reverse else True
 				unspent.reverse()
 				unspent.reverse()
 				break
 				break
@@ -220,20 +220,23 @@ View options: [g]roup, show [m]mgen addr
 	return tuple(unspent)
 	return tuple(unspent)
 
 
 
 
-def verify_mmgen_label(s,return_str=False):
+def verify_mmgen_label(s,return_str=False,check_label_len=False):
 
 
 	fail    = "" if return_str else False
 	fail    = "" if return_str else False
 	success = s  if return_str else True
 	success = s  if return_str else True
 
 
 	if not s: return fail
 	if not s: return fail
 
 
-	label = s.split()[0]
-	if label[8] != ':': return fail
-	for i in label[:8]:
+	mminfo,comment = s.split(None,1)
+	if mminfo[8] != ':': return fail
+	for i in mminfo[:8]:
 		if not i in "01234567890ABCDEF": return fail
 		if not i in "01234567890ABCDEF": return fail
-	for i in label[9:]:
+	for i in mminfo[9:]:
 		if not i in "0123456789": return fail
 		if not i in "0123456789": return fail
 
 
+	if check_label_len:
+		check_wallet_addr_comment(comment)
+
 	return success
 	return success
 
 
 
 
@@ -355,10 +358,11 @@ def make_tx_out(rcpt_arg):
 
 
 	return tx_out
 	return tx_out
 
 
-def check_wallet_addr_label(label):
+def check_wallet_addr_comment(label):
 
 
-	if len(label) > 16:
-		msg("'%s': illegal label (length must be <= 16 characters)" % label)
+	if len(label) > max_wallet_addr_label_len:
+		msg("'%s': overlong label (length must be <=%s)" %
+				(label,max_wallet_addr_label_len))
 		sys.exit(3)
 		sys.exit(3)
 
 
 	from string import ascii_letters, digits
 	from string import ascii_letters, digits
@@ -369,3 +373,46 @@ def check_wallet_addr_label(label):
 			msg("Permitted characters: A-Za-z0-9, plus '%s'" %
 			msg("Permitted characters: A-Za-z0-9, plus '%s'" %
 					"', '".join(wallet_addr_label_symbols))
 					"', '".join(wallet_addr_label_symbols))
 			sys.exit(3)
 			sys.exit(3)
+
+
+def parse_addrs_file(f):
+	lines = get_lines_from_file(f,"address data")
+	lines = remove_blanks_comments(lines)
+
+	seed_id,obrace = lines[0].split()
+	cbrace = lines[-1]
+
+	if   obrace != '{':
+		msg("'%s': invalid first line" % lines[0])
+	elif cbrace != '}':
+		msg("'%s': invalid last line" % cbrace)
+	elif len(seed_id) != 8:
+		msg("'%s': invalid Seed ID" % seed_id)
+	else:
+		try:
+			unhexlify(seed_id)
+		except:
+			msg("'%s': invalid Seed ID" % seed_id)
+			sys.exit(3)
+
+		ret = []
+		for i in lines[1:-1]:
+			d = i.split(None,2)
+
+			try: d[0] = int(d[0])
+			except:
+				msg("'%s': invalid address num. in line: %s" % (d[0],d))
+				sys.exit(3)
+
+			from mmgen.bitcoin import verify_addr
+			if not verify_addr(d[1]):
+				msg("'%s': invalid address" % d[1])
+				sys.exit(3)
+
+			if len(d) == 3: check_wallet_addr_comment(d[2])
+
+			ret.append(d)
+
+		return seed_id,ret
+
+	sys.exit(3)

+ 31 - 62
mmgen/utils.py

@@ -2,17 +2,17 @@
 #
 #
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
-# 
+#
 # This program is free software: you can redistribute it and/or modify
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation, either version 3 of the License, or
 # the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 # (at your option) any later version.
-# 
+#
 # This program is distributed in the hope that it will be useful,
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 # GNU General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU General Public License
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 """
 """
@@ -143,7 +143,7 @@ def check_opts(opts,keys):
 				sys.exit(1)
 				sys.exit(1)
 
 
 			if int(l) not in seed_lens:
 			if int(l) not in seed_lens:
-				msg("'%s': invalid 'l' %s.  Options: %s" % 
+				msg("'%s': invalid 'l' %s.  Options: %s" %
 						(l, what, ", ".join([str(i) for i in seed_lens])))
 						(l, what, ", ".join([str(i) for i in seed_lens])))
 				sys.exit(1)
 				sys.exit(1)
 
 
@@ -277,27 +277,40 @@ def check_infile(f):
 		msg("Requested input file '%s' is unreadable by you.  Aborting" % f)
 		msg("Requested input file '%s' is unreadable by you.  Aborting" % f)
 		sys.exit(1)
 		sys.exit(1)
 
 
+def validate_addr_num(n):
 
 
-def parse_address_range(arg):
-
-	import re
-	m = re.match(r'^(\d+)(-(\d+))*$', arg)
+	try: n = int(n)
+	except:
+		msg("'%s': invalid argument for address" % n)
+		sys.exit(2)
 
 
-	if m == None:
-		msg(arg + ": invalid argument for address range")
+	if n < 1:
+		msg("'%s': address must be greater than zero" % n)
 		sys.exit(2)
 		sys.exit(2)
 
 
-	start,end = int(m.group(1)), int(m.group(3) or m.group(1))
+	return n
 
 
-	if start < 1:
-		msg(args + ": First address must be >= 1")
-		sys.exit(2)
 
 
-	if end < start:
-		msg(arg + ": Last address must be >= first address")
-		sys.exit(2)
+def parse_address_list(arg):
+
+	ret = []
+
+	for i in (arg.split(",")):
+
+		j = i.split("-")
+
+		if len(j) == 1:
+			i = validate_addr_num(i)
+			ret.append(i)
+		elif len(j) == 2:
+			beg = validate_addr_num(j[0])
+			end = validate_addr_num(j[1])
+			for k in range(beg,end+1): ret.append(k)
+		else:
+			msg("'%s': invalid argument for address range" % j)
+			sys.exit(2)
 
 
-	return start,end
+	return sorted(set(ret))
 
 
 
 
 def get_first_passphrase_from_user(what, opts):
 def get_first_passphrase_from_user(what, opts):
@@ -795,49 +808,5 @@ def remove_blanks_comments(lines):
 
 
 	return ret
 	return ret
 
 
-def parse_addrs_file(f):
-	lines = get_lines_from_file(f,"address data")
-	lines = remove_blanks_comments(lines)
-
-	seed_id,obrace = lines[0].split()
- 	cbrace = lines[-1]
-
-	if   obrace != '{':
-		msg("'%s': invalid first line" % lines[0])
-	elif cbrace != '}':
-		msg("'%s': invalid last line" % cbrace)
-	elif len(seed_id) != 8:
-		msg("'%s': invalid Seed ID" % seed_id)
-	else:
-		try:
-			unhexlify(seed_id)
-		except:
-			msg("'%s': invalid Seed ID" % seed_id)
-			sys.exit(3)
-		
-		ret = []
-		for i in lines[1:-1]:
-			d = i.split()
-
-			try: d[0] = int(d[0])
-			except:
-				msg("'%s': invalid address num. in line: %s" % (d[0],d))
-				sys.exit(3)
-
-			from mmgen.bitcoin import verify_addr
-			if not verify_addr(d[1]):
-				msg("'%s': invalid address" % d[1])
-				sys.exit(3)
-
-			ret.append(d)
-
-		return seed_id,ret
-
-	sys.exit(3)
-
-
-
-
-
 if __name__ == "__main__":
 if __name__ == "__main__":
 	print get_lines_from_file("/tmp/lines","test file")
 	print get_lines_from_file("/tmp/lines","test file")

+ 3 - 3
mmgen/walletgen.py

@@ -2,17 +2,17 @@
 #
 #
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # mmgen = Multi-Mode GENerator, command-line Bitcoin cold storage solution
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
 # Copyright (C) 2013 by philemon <mmgen-py@yandex.com>
-# 
+#
 # This program is free software: you can redistribute it and/or modify
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
 # it under the terms of the GNU General Public License as published by
 # the Free Software Foundation, either version 3 of the License, or
 # the Free Software Foundation, either version 3 of the License, or
 # (at your option) any later version.
 # (at your option) any later version.
-# 
+#
 # This program is distributed in the hope that it will be useful,
 # This program is distributed in the hope that it will be useful,
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # but WITHOUT ANY WARRANTY; without even the implied warranty of
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 # GNU General Public License for more details.
 # GNU General Public License for more details.
-# 
+#
 # You should have received a copy of the GNU General Public License
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 """
 """