Browse Source

Version 0.9.2rc1

  - update Getting Started guide for Segwit and regtest
philemon 7 years ago
parent
commit
b753ddee5a
10 changed files with 158 additions and 83 deletions
  1. 129 54
      doc/wiki/using-mmgen/Getting-Started-with-MMGen.md
  2. 2 2
      mmgen/addr.py
  3. 4 4
      mmgen/color.py
  4. 1 1
      mmgen/globalvars.py
  5. 1 1
      mmgen/obj.py
  6. 1 1
      mmgen/opts.py
  7. 2 2
      mmgen/tx.py
  8. 1 1
      test/gentest.py
  9. 8 8
      test/test.py
  10. 9 9
      test/tooltest.py

+ 129 - 54
doc/wiki/using-mmgen/Getting-Started-with-MMGen.md

@@ -1,13 +1,13 @@
 ## Table of Contents
 ## Table of Contents
 
 
 #### <a href='#a_i'>Preliminaries</a>
 #### <a href='#a_i'>Preliminaries</a>
+* <a href='#a_bb'>Before you begin</a>
 * <a href='#a_iv'>Invocation</a>
 * <a href='#a_iv'>Invocation</a>
 * <a href='#a_cf'>Configuration file</a>
 * <a href='#a_cf'>Configuration file</a>
-* <a href='#a_ts'>Test setup and testnet</a>
-* <a href='#a_bb'>Before you begin</a>
+* <a href='#a_ts'>Testnet and regtest mode</a>
 
 
 #### <a href='#a_bo'>Basic Operations</a>
 #### <a href='#a_bo'>Basic Operations</a>
-* <a href='#a_gw'>Generate a wallet</a>
+* <a href='#a_gw'>Generate an MMGen wallet</a>
 * <a href='#a_ga'>Generate addresses</a>
 * <a href='#a_ga'>Generate addresses</a>
 * <a href='#a_ia'>Import addresses</a>
 * <a href='#a_ia'>Import addresses</a>
 * <a href='#a_ct'>Create a transaction</a>
 * <a href='#a_ct'>Create a transaction</a>
@@ -29,6 +29,16 @@
 
 
 ### <a name='a_i'>Preliminaries</a>
 ### <a name='a_i'>Preliminaries</a>
 
 
+#### <a name='a_bb'>Before you begin</a>
+
+Before you begin, note that the filenames, seed IDs and Bitcoin addresses used
+in this primer are intentionally invalid and are for purposes of illustration
+only.  As you perform the exercises, you'll naturally substitute real ones in
+their place.
+
+The up arrow (for repeating commands) and tab key (or Ctrl-I) (for completing
+commands and filenames) will speed up your work at the command line greatly.
+
 #### <a name='a_iv'>Invocation</a>
 #### <a name='a_iv'>Invocation</a>
 
 
 The MMGen wallet system is not a single program but a suite of lightweight
 The MMGen wallet system is not a single program but a suite of lightweight
@@ -69,42 +79,81 @@ wish to edit at some point to customize MMGen to your needs.  These settings
 include the maximum transaction fee; the user name, password and hostname
 include the maximum transaction fee; the user name, password and hostname
 used for communicating with bitcoind; and a number of others.
 used for communicating with bitcoind; and a number of others.
 
 
-#### <a name='a_ts'>Test setup and testnet</a>
+#### <a name='a_ts'>Testnet and regtest mode</a>
 
 
 If you just want to quickly try out MMGen, it's possible to perform all wallet
 If you just want to quickly try out MMGen, it's possible to perform all wallet
 generation, wallet format conversion, address and key generation, and address
 generation, wallet format conversion, address and key generation, and address
 import operations on an offline computer with no blockchain and no bitcoin
 import operations on an offline computer with no blockchain and no bitcoin
 balance.
 balance.
 
 
-If you want to practice creating, signing and sending transactions, however,
-as well as tracking balances, you'll need a fully synced blockchain and some
-actual coins to play with.  To avoid risking real funds, it's *highly
-recommended* to practice transaction operations on testnet until you feel
-confident you know what you're doing.  Testnet is just like the real Bitcoin
-network, but testnet coins have no monetary value.  Free testnet coins may be
-obtained at [https://tpfaucet.appspot.com][02].
+If you want to practice creating, signing and sending transactions, however, as
+well as tracking balances, you'll need a fully synced blockchain and some actual
+coins to play with.  To avoid risking real funds, it's *highly recommended* to
+practice transaction operations on [testnet][04] or in [regtest mode][05] until
+you feel confident you know what you're doing.
+
+**Testnet** is just like the real Bitcoin network, but testnet coins have no
+monetary value.  Free testnet coins may be obtained at
+[https://tpfaucet.appspot.com][02].
 
 
 To use MMGen with testnet, you must first start bitcoind with the `-testnet`
 To use MMGen with testnet, you must first start bitcoind with the `-testnet`
 option and sync the testnet blockchain (about 12GB at the time of writing).  To
 option and sync the testnet blockchain (about 12GB at the time of writing).  To
 force any MMGen command to use testnet just add the `--testnet=1` option after
 force any MMGen command to use testnet just add the `--testnet=1` option after
 the command name.  Or just set the `testnet` option to `true` in 'mmgen.cfg' to
 the command name.  Or just set the `testnet` option to `true` in 'mmgen.cfg' to
-make *all* commands use testnet.
-With testnet you can safely practice all the operations below,
-including the offline ones, on an online computer.
+make *all* commands use testnet.  With testnet you can safely practice all the
+operations below, including the offline ones, on an online computer.
 
 
-#### <a name='a_bb'>Before you begin</a>
+**Regtest mode** is a more convenient alternative to testnet that requires no
+Internet connection. In regtest mode, bitcoind creates a private blockchain on
+which you can mine, send and receive transactions.  MMGen commands support
+regtest mode with the `--regtest=1` option or the `regtest` option in
+`mmgen.cfg`.  The following is a brief guide to get you started with regtest
+mode:
 
 
-Before you begin, note that the filenames, seed IDs and Bitcoin addresses used
-in this primer are intentionally invalid and are for purposes of illustration
-only.  As you perform the exercises, you'll naturally substitute real ones in
-their place.
+Start the bitcoin daemon, generate 432 blocks to activate Segwit on the regtest
+chain and stop:
 
 
-The up arrow (for repeating commands) and tab key (or Ctrl-I) (for completing
-commands and filenames) will speed up your work at the command line greatly.
+		$ bitcoind -regtest -daemon
+		$ bitcoin-cli -regtest generate 432
+		$ bitcoin-cli -regtest stop
+
+Move 'wallet.dat' out of harm's way (**important:** it's the 'wallet.dat' in the
+'regtest' directory under your bitcoin data directory being referred to here,
+**not** the one in your bitcoin data directory).  Restart the daemon:
+
+		$ bitcoind -regtest -daemon
+
+A new ‘wallet.dat’ will be created.  This is your tracking wallet.  Create an
+MMGen wallet, generate some MMGen addresses and import them into the tracking
+wallet <a href='#a_bo'>as described below</a>. Stop the daemon again:
+
+		$ bitcoin-cli -regtest stop
+
+Move your tracking wallet (the new 'wallet.dat') out of harm's way and move the
+original 'wallet.dat' back.  Restart the daemon, send some funds to one of your
+tracked addresses, mine a block and stop the daemon:
+
+		$ bitcoind -regtest -daemon
+		$ bitcoin-cli -regtest sendtoaddress <a tracked address> 100.00
+		$ bitcoin-cli -regtest generate 1
+		$ bitcoin-cli -regtest stop
+
+Replace the original 'wallet.dat' with your tracking wallet again, restart
+bitcoind and list your tracked addresses:
+
+		$ bitcoind -regtest -daemon
+		$ mmgen-tool --regtest=1 listaddresses
+
+Your address should now have a balance of 100 BTC.  You may now practice creating
+and sending transactions to yourself <a href='#a_ct'>as described below</a>.
+After sending each transaction, you must mine a new block for the transaction to
+confirm:
+
+		$ bitcoin-cli -regtest generate 1
 
 
 ### <a name='a_bo'>Basic Operations</a>
 ### <a name='a_bo'>Basic Operations</a>
 
 
-#### <a name='a_gw'>Generate a wallet (offline computer)</a>
+#### <a name='a_gw'>Generate an MMGen wallet (offline computer)</a>
 
 
 *NOTE: MMGen supports a “default wallet” feature.  After generating your wallet,
 *NOTE: MMGen supports a “default wallet” feature.  After generating your wallet,
 you'll be prompted to make it your default.  If you answer 'y', the wallet will
 you'll be prompted to make it your default.  If you answer 'y', the wallet will
@@ -119,7 +168,7 @@ as it frees you from having to type your wallet file on the command line.*
 If you haven't, then you must include the path to a wallet file or other seed
 If you haven't, then you must include the path to a wallet file or other seed
 source in all commands where a seed source is required.*
 source in all commands where a seed source is required.*
 
 
-On your offline computer, generate a wallet:
+On your offline computer, generate an MMGen wallet:
 
 
 		$ mmgen-walletgen
 		$ mmgen-walletgen
 		...
 		...
@@ -172,14 +221,23 @@ Now generate ten addresses with your just-created wallet:
 		  10   1H7vVTk4ejUbQXw45I6g5qvPBSe9bsjDqh
 		  10   1H7vVTk4ejUbQXw45I6g5qvPBSe9bsjDqh
 		}
 		}
 
 
+NOTE: As of version 0.9.2, MMGen supports Segwit. To generate Segwit addresses,
+add `--type segwit` to the command line.  Segwit address files are distinguished
+from Legacy ones by the ‘-S’ in the filename:
+
+		$ mmgen-addrgen --type segwit 1-10
+		...
+		$ cat '89ABCDEF-S[1-10].addrs'
+		89ABCDEF SEGWIT {
+		  1   32GiSWo9zIQgkCmjAaLIrbPwXhKry2jHhj
+		...
+
 Note that the address range ‘1-10’ specified on the command line is included in
 Note that the address range ‘1-10’ specified on the command line is included in
-the resulting filename.  MMGen addresses consist of the Seed ID followed by ‘:’
-and an index.  In this example, ‘89ABCDEF:1’ represents the Bitcoin address
-‘16bNmy...’, ‘89ABCDEF:2’ represents ‘1AmkUx...’ and so forth.
+the resulting filename.
 
 
 To fund your MMGen wallet, first import the addresses into your tracking wallet
 To fund your MMGen wallet, first import the addresses into your tracking wallet
-and then spend some bitcoin into any of them.  If you run out of addresses,
-generate more.  To generate a hundred addresses, for example, specify an address
+and then spend some BTC into any of them.  If you run out of addresses, generate
+more.  To generate a hundred addresses, for example, you’d specify an address
 range of ‘1-100’.
 range of ‘1-100’.
 
 
 Let’s say you’ve decided to spend some BTC into the first four addresses above.
 Let’s say you’ve decided to spend some BTC into the first four addresses above.
@@ -233,12 +291,12 @@ empty balances, and `showbtcaddrs` causes Bitcoin addresses to be displayed
 also).
 also).
 
 
 		$ mmgen-tool listaddresses showempty=1 showbtcaddrs=1
 		$ mmgen-tool listaddresses showempty=1 showbtcaddrs=1
-		MMGenID     ADDRESS                             COMMENT    BALANCE
-		89ABCDEF:1  16bNmyYISiptuvJG3X7MPwiiS4HYvD7ksE  Donations    0
-		89ABCDEF:2  1AmkUxrfy5dMrfmeYwTxLxfIswUCcpeysc  Storage 1    0
-		89ABCDEF:3  1HgYCsfqYzIg7LVVfDTp7gYJocJEiDAy6N  Storage 2    0
-		89ABCDEF:4  14Tu3z1tiexXDonNsFIkvzqutE5E3pTK8s  Storage 3    0
-		89ABCDEF:5  1PeI55vtp2bX2uKDkAAR2c6ekHNYe4Hcq7               0
+		MMGenID       ADDRESS                             COMMENT    BALANCE
+		89ABCDEF:L:1  16bNmyYISiptuvJG3X7MPwiiS4HYvD7ksE  Donations    0
+		89ABCDEF:L:2  1AmkUxrfy5dMrfmeYwTxLxfIswUCcpeysc  Storage 1    0
+		89ABCDEF:L:3  1HgYCsfqYzIg7LVVfDTp7gYJocJEiDAy6N  Storage 2    0
+		89ABCDEF:L:4  14Tu3z1tiexXDonNsFIkvzqutE5E3pTK8s  Storage 3    0
+		89ABCDEF:L:5  1PeI55vtp2bX2uKDkAAR2c6ekHNYe4Hcq7               0
 		...
 		...
 		TOTAL: 0 BTC
 		TOTAL: 0 BTC
 
 
@@ -248,17 +306,23 @@ track and spend funds from another wallet using MMGen without having to go
 through the network.  To use it, you must save the keys corresponding to the
 through the network.  To use it, you must save the keys corresponding to the
 addresses where the funds are stored in a separate file to use during signing.*
 addresses where the funds are stored in a separate file to use during signing.*
 
 
+Note that each address has a unique ID (the ‘MMGen ID’) consisting of its Seed
+ID, its address type (‘L’ for Legacy, ‘S’ for Segwit), and its number (index).
+Legacy and Segwit addresses may be imported into the same tracking wallet;
+they're generated from different sub-seeds, so you needn't worry about key
+reuse.
+
 Now that your addresses are being tracked, you may go ahead and send some BTC to
 Now that your addresses are being tracked, you may go ahead and send some BTC to
 them over the Bitcoin network.  If you send 0.1, 0.2, 0.3 and 0.4 BTC
 them over the Bitcoin network.  If you send 0.1, 0.2, 0.3 and 0.4 BTC
-respectively, for example, your address listing will look something like this
-after the transactions have been confirmed:
+respectively, your address listing will look like this after the transactions
+have confirmed:
 
 
 		$ mmgen-tool listaddresses
 		$ mmgen-tool listaddresses
-		MMGenID     COMMENT    BALANCE
-		89ABCDEF:1  Donations    0.1
-		89ABCDEF:2  Storage 1    0.2
-		89ABCDEF:3  Storage 2    0.3
-		89ABCDEF:4  Storage 3    0.4
+		MMGenID       COMMENT    BALANCE
+		89ABCDEF:L:1  Donations    0.1
+		89ABCDEF:L:2  Storage 1    0.2
+		89ABCDEF:L:3  Storage 2    0.3
+		89ABCDEF:L:4  Storage 3    0.4
 		TOTAL: 1 BTC
 		TOTAL: 1 BTC
 
 
 #### <a name='a_ct'>Create a transaction (online computer)</a>
 #### <a name='a_ct'>Create a transaction (online computer)</a>
@@ -266,8 +330,9 @@ after the transactions have been confirmed:
 Now that you have some BTC under MMGen’s control, you’re ready to create a
 Now that you have some BTC under MMGen’s control, you’re ready to create a
 transaction.  Note that transactions are harmless until they’re signed and
 transaction.  Note that transactions are harmless until they’re signed and
 broadcast to the network, so feel free to experiment and create transactions
 broadcast to the network, so feel free to experiment and create transactions
-with different combinations of inputs and outputs.  If you're using testnet,
-then you risk nothing even when broadcasting transactions, of course.
+with different combinations of inputs and outputs.  Of course, if you're using
+testnet or regtest mode, then you risk nothing even when broadcasting
+transactions.
 
 
 To send 0.1 BTC to the a third-party address 1AmkUxrfy5dMrfmeYwTxLxfIswUCcpeysc,
 To send 0.1 BTC to the a third-party address 1AmkUxrfy5dMrfmeYwTxLxfIswUCcpeysc,
 for example, and send the change back to yourself at address 89ABCDEF:5, you’d
 for example, and send the change back to yourself at address 89ABCDEF:5, you’d
@@ -278,6 +343,14 @@ issue the following command:
 Note that 'mmgen-txcreate' accepts either MMGen IDs or Bitcoin addresses as
 Note that 'mmgen-txcreate' accepts either MMGen IDs or Bitcoin addresses as
 arguments.
 arguments.
 
 
+IMPORTANT NOTE: For the time being, Legacy addresses are the default, so
+address ‘89ABCDEF:5’ is equivalent to ‘89ABCDEF:L:5’.  In the future, users will
+have the option to make Segwit addresses the default, so that ‘89ABCDEF:5’ will
+be equivalent to ‘89ABCDEF:S:5’ and the ‘L’ will be required to specify a legacy
+address.  This may seem confusing, but it was the best possible way to make
+the MMGen ID backwards-compatible for now while allowing users the option of
+a non-compatible upgrade in the future.
+
 To send 0.1 BTC to each of your addresses 89ABCDEF:6 and 89ABCDEF:7 and return the
 To send 0.1 BTC to each of your addresses 89ABCDEF:6 and 89ABCDEF:7 and return the
 change to 89ABCDEF:8, you’d do this:
 change to 89ABCDEF:8, you’d do this:
 
 
@@ -299,10 +372,10 @@ will look something like this:
 
 
 		UNSPENT OUTPUTS (sort order: Age)  Total BTC: 1
 		UNSPENT OUTPUTS (sort order: Age)  Total BTC: 1
 		 Num  TX id  Vout    Address                               Amt(BTC) Age(d)
 		 Num  TX id  Vout    Address                               Amt(BTC) Age(d)
-		 1)   e9742b16... 5  1L3kxmi.. 89ABCDEF:1    Donations       0.1    1
-		 2)   fa84d709... 6  1N4dSGj.. 89ABCDEF:2    Storage 1       0.2    1
-		 3)   8dde8ef5... 6  1M1fVDc.. 89ABCDEF:3    Storage 1       0.3    1
-		 4)   c76874c7... 0  1E8MFoC.. 89ABCDEF:4    Storage 3       0.4    1
+		 1)   e9742b16... 5  1L3kxmi.. 89ABCDEF:L:1    Donations       0.1    1
+		 2)   fa84d709... 6  1N4dSGj.. 89ABCDEF:L:2    Storage 1       0.2    1
+		 3)   8dde8ef5... 6  1M1fVDc.. 89ABCDEF:L:3    Storage 1       0.3    1
+		 4)   c76874c7... 0  1E8MFoC.. 89ABCDEF:L:4    Storage 3       0.4    1
 
 
 		Sort options: [t]xid, [a]mount, a[d]dress, [A]ge, [r]everse, [M]mgen addr
 		Sort options: [t]xid, [a]mount, a[d]dress, [A]ge, [r]everse, [M]mgen addr
 		Display options: show [D]ays, [g]roup, show [m]mgen addr, r[e]draw screen
 		Display options: show [D]ays, [g]roup, show [m]mgen addr, r[e]draw screen
@@ -313,8 +386,8 @@ After quitting the menu with 'q', you’ll see the following prompt:
 		Enter a range or space-separated list of outputs to spend:
 		Enter a range or space-separated list of outputs to spend:
 
 
 Here you must choose unspent outputs of sufficient value to cover the send
 Here you must choose unspent outputs of sufficient value to cover the send
-amount of 0.1 BTC, plus the transaction fee (for more on fees, see 'Transaction
-Fees' under 'Advanced Topics' below).  Output #2 is worth 0.2 BTC, which is
+amount of 0.1 BTC, plus the transaction fee (for more on fees, see Transaction
+Fees’ under ‘Advanced Topics’ below).  Output #2 is worth 0.2 BTC, which is
 sufficient, so we’ll choose that.  After several more prompts and confirmations,
 sufficient, so we’ll choose that.  After several more prompts and confirmations,
 your transaction will be saved:
 your transaction will be saved:
 
 
@@ -357,11 +430,11 @@ Once the transaction is broadcast to the network and confirmed, your address
 listing should look something like this:
 listing should look something like this:
 
 
 		$ mmgen-tool listaddresses minconf=1
 		$ mmgen-tool listaddresses minconf=1
-		MMGenID     COMMENT    BALANCE
-		89ABCDEF:1  Donations    0.1
-		89ABCDEF:3  Storage 2    0.3
-		89ABCDEF:4  Storage 3    0.4
-		89ABCDEF:5  Storage 1    0.0999
+		MMGenID       COMMENT    BALANCE
+		89ABCDEF:L:1  Donations    0.1
+		89ABCDEF:L:3  Storage 2    0.3
+		89ABCDEF:L:4  Storage 3    0.4
+		89ABCDEF:L:5  Storage 1    0.0999
 		TOTAL: 0.8999 BTC
 		TOTAL: 0.8999 BTC
 
 
 Since you’ve sent 0.1 BTC to a third party, your balance has declined by 0.1 BTC
 Since you’ve sent 0.1 BTC to a third party, your balance has declined by 0.1 BTC
@@ -810,3 +883,5 @@ them in turn until you get a confirmation:
 [01]: https://github.com/mmgen/mmgen/wiki/Tracking-and-spending-ordinary-Bitcoin-addresses
 [01]: https://github.com/mmgen/mmgen/wiki/Tracking-and-spending-ordinary-Bitcoin-addresses
 [02]: https://tpfaucet.appspot.com
 [02]: https://tpfaucet.appspot.com
 [03]: Recovering-Keys-Without-MMGen
 [03]: Recovering-Keys-Without-MMGen
+[04]: https://bitcoin.org/en/developer-examples#testnet
+[05]: https://bitcoin.org/en/developer-examples#regtest-mode

+ 2 - 2
mmgen/addr.py

@@ -516,7 +516,7 @@ Removed %s duplicate wif key%s from keylist (also in {pnm} key-address file
 				mmtype = MMGenAddrType(mmtype)
 				mmtype = MMGenAddrType(mmtype)
 			except:
 			except:
 				return do_error(u"'{}': invalid address type in address file. Must be one of: {}".format(
 				return do_error(u"'{}': invalid address type in address file. Must be one of: {}".format(
-					mmtype,' '.join(MMGenAddrType.mmtypes.values()).upper()))
+					mmtype.upper(),' '.join(MMGenAddrType.mmtypes.values()).upper()))
 		elif len(ls) == 0:
 		elif len(ls) == 0:
 			mmtype = MMGenAddrType('L')
 			mmtype = MMGenAddrType('L')
 		else:
 		else:
@@ -599,7 +599,7 @@ Record this checksum: it will be used to verify the password file in the future
 			self.data = self.parse_file(infile) # sets self.pw_id_str,self.pw_fmt,self.pw_len
 			self.data = self.parse_file(infile) # sets self.pw_id_str,self.pw_fmt,self.pw_len
 		else:
 		else:
 			for k in seed,pw_idxs: assert chk_params_only or k
 			for k in seed,pw_idxs: assert chk_params_only or k
-			for k in pw_id_str,pw_fmt: assert k
+			for k in (pw_id_str,pw_fmt): assert k
 			self.pw_id_str = MMGenPWIDString(pw_id_str)
 			self.pw_id_str = MMGenPWIDString(pw_id_str)
 			self.set_pw_fmt(pw_fmt)
 			self.set_pw_fmt(pw_fmt)
 			self.set_pw_len(pw_len)
 			self.set_pw_len(pw_len)

+ 4 - 4
mmgen/color.py

@@ -58,11 +58,11 @@ def nocolor(s): return s
 
 
 def init_color(enable_color=True,num_colors='auto'):
 def init_color(enable_color=True,num_colors='auto'):
 	if enable_color:
 	if enable_color:
-		assert num_colors in ['auto',8,16,256]
+		assert num_colors in ('auto',8,16,256)
 		globals()['_reset'] = '\033[0m'
 		globals()['_reset'] = '\033[0m'
-		if num_colors in [8,16]:
+		if num_colors in (8,16):
 			pfx = '_16_'
 			pfx = '_16_'
-		elif num_colors in [256]:
+		elif num_colors in (256,):
 			pfx = '_256_'
 			pfx = '_256_'
 		else:
 		else:
 			try:
 			try:
@@ -87,7 +87,7 @@ def test_color():
 		colorama.init(strip=True,convert=True)
 		colorama.init(strip=True,convert=True)
 	except:
 	except:
 		pass
 		pass
-	for desc,n in ('auto','auto'),('8-color',8),('256-color',256):
+	for desc,n in (('auto','auto'),('8-color',8),('256-color',256)):
 		if n != 'auto': init_color(num_colors=n)
 		if n != 'auto': init_color(num_colors=n)
 		print('{:9}: {}'.format(desc,' '.join([globals()[c](c) for c in sorted(_colors)])))
 		print('{:9}: {}'.format(desc,' '.join([globals()[c](c) for c in sorted(_colors)])))
 
 

+ 1 - 1
mmgen/globalvars.py

@@ -38,7 +38,7 @@ class g(object):
 		sys.exit(ev)
 		sys.exit(ev)
 	# Variables - these might be altered at runtime:
 	# Variables - these might be altered at runtime:
 
 
-	version      = '0.9.199'
+	version      = '0.9.2rc1'
 	release_date = 'July 2017'
 	release_date = 'July 2017'
 
 
 	proj_name = 'MMGen'
 	proj_name = 'MMGen'

+ 1 - 1
mmgen/obj.py

@@ -79,7 +79,7 @@ class MMGenObject(object):
 #		print repr(self.__dict__.keys())
 #		print repr(self.__dict__.keys())
 
 
 		for k in self.__dict__:
 		for k in self.__dict__:
-			if k in ('_OrderedDict__root', '_OrderedDict__map'): continue # exclude these because of recursion
+			if k in ('_OrderedDict__root','_OrderedDict__map'): continue # exclude these because of recursion
 			e = getattr(self,k)
 			e = getattr(self,k)
 			if isList(e) or isDict(e):
 			if isList(e) or isDict(e):
 				out.append(u'{:>{l}}{:<10} {:16}'.format('',k,'<'+type(e).__name__+'>',l=(lvl*8)+4))
 				out.append(u'{:>{l}}{:<10} {:16}'.format('',k,'<'+type(e).__name__+'>',l=(lvl*8)+4))

+ 1 - 1
mmgen/opts.py

@@ -180,7 +180,7 @@ def init(opts_data,add_opts=[],opt_filter=None):
 
 
 	# We don't need this data anymore
 	# We don't need this data anymore
 	del mmgen.share.Opts
 	del mmgen.share.Opts
-	for k in 'prog_name','desc','usage','options','notes':
+	for k in ('prog_name','desc','usage','options','notes'):
 		if k in opts_data: del opts_data[k]
 		if k in opts_data: del opts_data[k]
 
 
 	# Transfer uopts into opt, setting program's opts + required opts to None if not set by user
 	# Transfer uopts into opt, setting program's opts + required opts to None if not set by user

+ 2 - 2
mmgen/tx.py

@@ -449,7 +449,7 @@ class MMGenTX(MMGenObject):
 
 
 		sig_data = []
 		sig_data = []
 		for d in self.inputs:
 		for d in self.inputs:
-			e = dict([(k,getattr(d,k)) for k in 'txid','vout','scriptPubKey','amt'])
+			e = dict([(k,getattr(d,k)) for k in ('txid','vout','scriptPubKey','amt')])
 			e['amount'] = e['amt']
 			e['amount'] = e['amt']
 			del e['amt']
 			del e['amt']
 			wif = keys[d.addr]
 			wif = keys[d.addr]
@@ -477,7 +477,7 @@ class MMGenTX(MMGenObject):
 			return True
 			return True
 		else:
 		else:
 			msg('failed\nBitcoind returned the following errors:')
 			msg('failed\nBitcoind returned the following errors:')
-			pmsg(sig_tx['errors'])
+			msg(repr(sig_tx['errors']))
 			return False
 			return False
 
 
 	def mark_raw(self):
 	def mark_raw(self):

+ 1 - 1
test/gentest.py

@@ -99,7 +99,7 @@ except:
 else:
 else:
 	try:
 	try:
 		a,b = int(a),int(b)
 		a,b = int(a),int(b)
-		for i in a,b: assert 1 <= i <= len(g.key_generators)
+		for i in (a,b): assert 1 <= i <= len(g.key_generators)
 		assert a != b
 		assert a != b
 	except:
 	except:
 		die(1,"%s: invalid generator IDs" % cmd_args[0])
 		die(1,"%s: invalid generator IDs" % cmd_args[0])

+ 8 - 8
test/test.py

@@ -384,7 +384,7 @@ cfgs = {
 }
 }
 
 
 from copy import deepcopy
 from copy import deepcopy
-for a,b in ('6','11'),('7','12'),('8','13'):
+for a,b in (('6','11'),('7','12'),('8','13')):
 	cfgs[b] = deepcopy(cfgs[a])
 	cfgs[b] = deepcopy(cfgs[a])
 	cfgs[b]['tmpdir'] = os.path.join('test','tmp'+b)
 	cfgs[b]['tmpdir'] = os.path.join('test','tmp'+b)
 
 
@@ -540,7 +540,7 @@ for k,v in (
 
 
 cmd_data['info_ref'] = 'reference data',[6,7,8]
 cmd_data['info_ref'] = 'reference data',[6,7,8]
 for a,b in cmd_group['ref']:
 for a,b in cmd_group['ref']:
-	for i,j in (1,128),(2,192),(3,256):
+	for i,j in ((1,128),(2,192),(3,256)):
 		k = a+str(i)
 		k = a+str(i)
 		cmd_list['ref'].append(k)
 		cmd_list['ref'].append(k)
 		cmd_data[k] = (5+i,'%s (%s-bit)' % (b[1],j),[[b[0],5+i]],1)
 		cmd_data[k] = (5+i,'%s (%s-bit)' % (b[1],j),[[b[0],5+i]],1)
@@ -552,14 +552,14 @@ for a,b in cmd_group['ref_other']:
 
 
 cmd_data['info_conv_in'] = 'wallet conversion from reference data',[11,12,13]
 cmd_data['info_conv_in'] = 'wallet conversion from reference data',[11,12,13]
 for a,b in cmd_group['conv_in']:
 for a,b in cmd_group['conv_in']:
-	for i,j in (1,128),(2,192),(3,256):
+	for i,j in ((1,128),(2,192),(3,256)):
 		k = a+str(i)
 		k = a+str(i)
 		cmd_list['conv_in'].append(k)
 		cmd_list['conv_in'].append(k)
 		cmd_data[k] = (10+i,'%s (%s-bit)' % (b,j),[[[],10+i]],1)
 		cmd_data[k] = (10+i,'%s (%s-bit)' % (b,j),[[[],10+i]],1)
 
 
 cmd_data['info_conv_out'] = 'wallet conversion to reference data',[11,12,13]
 cmd_data['info_conv_out'] = 'wallet conversion to reference data',[11,12,13]
 for a,b in cmd_group['conv_out']:
 for a,b in cmd_group['conv_out']:
-	for i,j in (1,128),(2,192),(3,256):
+	for i,j in ((1,128),(2,192),(3,256)):
 		k = a+str(i)
 		k = a+str(i)
 		cmd_list['conv_out'].append(k)
 		cmd_list['conv_out'].append(k)
 		cmd_data[k] = (10+i,'%s (%s-bit)' % (b,j),[[[],10+i]],1)
 		cmd_data[k] = (10+i,'%s (%s-bit)' % (b,j),[[[],10+i]],1)
@@ -574,7 +574,7 @@ addrs_per_wallet = 8
 # total of two outputs must be < 10 BTC
 # total of two outputs must be < 10 BTC
 for k in cfgs:
 for k in cfgs:
 	cfgs[k]['amts'] = [0,0]
 	cfgs[k]['amts'] = [0,0]
-	for idx,mod in (0,6),(1,4):
+	for idx,mod in ((0,6),(1,4)):
 		cfgs[k]['amts'][idx] = '%s.%s' % ((getrandnum(2) % mod), str(getrandnum(4))[:5])
 		cfgs[k]['amts'][idx] = '%s.%s' % ((getrandnum(2) % mod), str(getrandnum(4))[:5])
 
 
 meta_cmds = OrderedDict([
 meta_cmds = OrderedDict([
@@ -611,7 +611,7 @@ del cmd_group
 add_spawn_args = ' '.join(['{} {}'.format(
 add_spawn_args = ' '.join(['{} {}'.format(
 	'--'+k.replace('_','-'),
 	'--'+k.replace('_','-'),
 	getattr(opt,k) if getattr(opt,k) != True else ''
 	getattr(opt,k) if getattr(opt,k) != True else ''
-	) for k in 'testnet','rpc_host','rpc_port','regtest' if getattr(opt,k)]).split()
+	) for k in ('testnet','rpc_host','rpc_port','regtest') if getattr(opt,k)]).split()
 add_spawn_args += ['--data-dir',data_dir]
 add_spawn_args += ['--data-dir',data_dir]
 
 
 if opt.profile: opt.names = True
 if opt.profile: opt.names = True
@@ -1539,7 +1539,7 @@ class MMGenTestSuite(object):
 		t.expect('OK? (Y/n): ','\n')
 		t.expect('OK? (Y/n): ','\n')
 		if seed_args: # sign and send
 		if seed_args: # sign and send
 			t.expect('Edit transaction comment? (y/N): ','\n')
 			t.expect('Edit transaction comment? (y/N): ','\n')
-			for cnum,desc in ('1','incognito data'),('3','MMGen wallet'),('4','MMGen wallet'):
+			for cnum,desc in (('1','incognito data'),('3','MMGen wallet'),('4','MMGen wallet')):
 				t.passphrase(('%s' % desc),cfgs[cnum]['wpasswd'])
 				t.passphrase(('%s' % desc),cfgs[cnum]['wpasswd'])
 			t.expect("Type uppercase 'YES' to confirm: ",'YES\n')
 			t.expect("Type uppercase 'YES' to confirm: ",'YES\n')
 		else:
 		else:
@@ -1839,7 +1839,7 @@ class MMGenTestSuite(object):
 			t.expect('Check key-to-address validity? (y/N): ','y')
 			t.expect('Check key-to-address validity? (y/N): ','y')
 			t.tx_view()
 			t.tx_view()
 
 
-		for cnum,desc in ('1','incognito data'),('3','MMGen wallet'):
+		for cnum,desc in (('1','incognito data'),('3','MMGen wallet')):
 			t.passphrase(('%s' % desc),cfgs[cnum]['wpasswd'])
 			t.passphrase(('%s' % desc),cfgs[cnum]['wpasswd'])
 
 
 		if txdo_handle: return
 		if txdo_handle: return

+ 9 - 9
test/tooltest.py

@@ -140,7 +140,7 @@ spawn_cmd = ['python',os.path.join(os.curdir,'mmgen-tool') if not opt.system els
 add_spawn_args = ' '.join(['{} {}'.format(
 add_spawn_args = ' '.join(['{} {}'.format(
 	'--'+k.replace('_','-'),
 	'--'+k.replace('_','-'),
 	getattr(opt,k) if getattr(opt,k) != True else ''
 	getattr(opt,k) if getattr(opt,k) != True else ''
-	) for k in 'testnet','rpc_host','regtest' if getattr(opt,k)]).split()
+	) for k in ('testnet','rpc_host','regtest') if getattr(opt,k)]).split()
 add_spawn_args += [ '--data-dir', cfg['tmpdir']] # ignore ~/.mmgen
 add_spawn_args += [ '--data-dir', cfg['tmpdir']] # ignore ~/.mmgen
 
 
 if opt.system: sys.path.pop(0)
 if opt.system: sys.path.pop(0)
@@ -329,28 +329,28 @@ class MMGenToolTestSuite(object):
 			ok_or_die(wif,is_wif,'WIF key',skip_ok=True)
 			ok_or_die(wif,is_wif,'WIF key',skip_ok=True)
 			ok_or_die(addr,is_btc_addr,'Bitcoin address')
 			ok_or_die(addr,is_btc_addr,'Bitcoin address')
 	def Wif2addr(self,name,f1,f2,f3):
 	def Wif2addr(self,name,f1,f2,f3):
-		for n,f,k,m in (1,f1,'',''),(2,f2,'','compressed'),(3,f3,'segwit=1','compressed'):
+		for n,f,k,m in ((1,f1,'',''),(2,f2,'','compressed'),(3,f3,'segwit=1','compressed')):
 			wif = read_from_file(f).split()[0]
 			wif = read_from_file(f).split()[0]
 			self.run_cmd_out(name,wif,kwargs=k,fn_idx=n,extra_msg=m)
 			self.run_cmd_out(name,wif,kwargs=k,fn_idx=n,extra_msg=m)
 	def Wif2hex(self,name,f1,f2,f3):
 	def Wif2hex(self,name,f1,f2,f3):
-		for n,f,m in (1,f1,''),(2,f2,'compressed'),(3,f3,'compressed for segwit'):
+		for n,f,m in ((1,f1,''),(2,f2,'compressed'),(3,f3,'compressed for segwit')):
 			wif = read_from_file(f).split()[0]
 			wif = read_from_file(f).split()[0]
 			self.run_cmd_out(name,wif,fn_idx=n,extra_msg=m)
 			self.run_cmd_out(name,wif,fn_idx=n,extra_msg=m)
 	def Privhex2addr(self,name,f1,f2,f3):
 	def Privhex2addr(self,name,f1,f2,f3):
-		keys = [read_from_file(f).rstrip() for f in f1,f2,f3]
+		keys = [read_from_file(f).rstrip() for f in (f1,f2,f3)]
 		for n,k in enumerate(('','compressed=1','compressed=1 segwit=1')):
 		for n,k in enumerate(('','compressed=1','compressed=1 segwit=1')):
 			ret = self.run_cmd(name,[keys[n]],kwargs=k).rstrip()
 			ret = self.run_cmd(name,[keys[n]],kwargs=k).rstrip()
 			iaddr = read_from_tmpfile(cfg,'Randpair{}.out'.format(n+1)).split()[-1]
 			iaddr = read_from_tmpfile(cfg,'Randpair{}.out'.format(n+1)).split()[-1]
 			cmp_or_die(iaddr,ret)
 			cmp_or_die(iaddr,ret)
 	def Hex2wif(self,name,f1,f2,f3,f4):
 	def Hex2wif(self,name,f1,f2,f3,f4):
-		for n,fi,fo,k in (1,f1,f2,''),(2,f3,f4,'compressed=1'):
+		for n,fi,fo,k in ((1,f1,f2,''),(2,f3,f4,'compressed=1')):
 			ret = self.run_cmd_chk(name,fi,fo,kwargs=k)
 			ret = self.run_cmd_chk(name,fi,fo,kwargs=k)
 	def Addr2hexaddr(self,name,f1,f2):
 	def Addr2hexaddr(self,name,f1,f2):
-		for n,f,m in (1,f1,''),(2,f2,'from compressed'):
+		for n,f,m in ((1,f1,''),(2,f2,'from compressed')):
 			addr = read_from_file(f).split()[-1]
 			addr = read_from_file(f).split()[-1]
 			self.run_cmd_out(name,addr,fn_idx=n,extra_msg=m)
 			self.run_cmd_out(name,addr,fn_idx=n,extra_msg=m)
 	def Hexaddr2addr(self,name,f1,f2,f3,f4):
 	def Hexaddr2addr(self,name,f1,f2,f3,f4):
-		for n,fi,fo,m in (1,f1,f2,''),(2,f3,f4,'from compressed'):
+		for n,fi,fo,m in ((1,f1,f2,''),(2,f3,f4,'from compressed')):
 			self.run_cmd_chk(name,fi,fo,extra_msg=m)
 			self.run_cmd_chk(name,fi,fo,extra_msg=m)
 	def Privhex2pubhex(self,name,f1,f2,f3): # from hex2wif
 	def Privhex2pubhex(self,name,f1,f2,f3): # from hex2wif
 		addr = read_from_file(f3).strip()
 		addr = read_from_file(f3).strip()
@@ -388,11 +388,11 @@ class MMGenToolTestSuite(object):
 
 
 	# Mnemonic
 	# Mnemonic
 	def Hex2mn(self,name):
 	def Hex2mn(self,name):
-		for n,size,m in(1,16,'128-bit'),(2,24,'192-bit'),(3,32,'256-bit'):
+		for n,size,m in ((1,16,'128-bit'),(2,24,'192-bit'),(3,32,'256-bit')):
 			hexnum = getrandhex(size)
 			hexnum = getrandhex(size)
 			self.run_cmd_out(name,hexnum,fn_idx=n,extra_msg=m)
 			self.run_cmd_out(name,hexnum,fn_idx=n,extra_msg=m)
 	def Mn2hex(self,name,f1,f2,f3,f4,f5,f6):
 	def Mn2hex(self,name,f1,f2,f3,f4,f5,f6):
-		for f_i,f_o,m in (f1,f2,'128-bit'),(f3,f4,'192-bit'),(f5,f6,'256-bit'):
+		for f_i,f_o,m in ((f1,f2,'128-bit'),(f3,f4,'192-bit'),(f5,f6,'256-bit')):
 			self.run_cmd_chk(name,f_i,f_o,extra_msg=m)
 			self.run_cmd_chk(name,f_i,f_o,extra_msg=m)
 	def Mn_rand128(self,name): self.run_cmd_out(name)
 	def Mn_rand128(self,name): self.run_cmd_out(name)
 	def Mn_rand192(self,name): self.run_cmd_out(name)
 	def Mn_rand192(self,name): self.run_cmd_out(name)