diff --git a/doc/wiki/using-mmgen/Getting-Started-with-MMGen.md b/doc/wiki/using-mmgen/Getting-Started-with-MMGen.md index 1d55c99b..8120c32b 100644 --- a/doc/wiki/using-mmgen/Getting-Started-with-MMGen.md +++ b/doc/wiki/using-mmgen/Getting-Started-with-MMGen.md @@ -1,13 +1,13 @@ ## Table of Contents #### Preliminaries +* Before you begin * Invocation * Configuration file -* Test setup and testnet -* Before you begin +* Testnet and regtest mode #### Basic Operations -* Generate a wallet +* Generate an MMGen wallet * Generate addresses * Import addresses * Create a transaction @@ -29,6 +29,16 @@ ### Preliminaries +#### Before you begin + +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. + #### Invocation 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 used for communicating with bitcoind; and a number of others. -#### Test setup and testnet +#### Testnet and regtest mode 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 import operations on an offline computer with no blockchain and no bitcoin 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` 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 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. -#### Before you begin +**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 as described below. 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 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 as described below. +After sending each transaction, you must mine a new block for the transaction to +confirm: + + $ bitcoin-cli -regtest generate 1 ### Basic Operations -#### Generate a wallet (offline computer) +#### Generate an MMGen wallet (offline computer) *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 @@ -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 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 ... @@ -172,14 +221,23 @@ Now generate ten addresses with your just-created wallet: 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 -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 -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’. 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). $ 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 @@ -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 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 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 - 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 #### Create a transaction (online computer) @@ -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 transaction. Note that transactions are harmless until they’re signed and 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, 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 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 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 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 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: 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, 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: $ 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 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 [02]: https://tpfaucet.appspot.com [03]: Recovering-Keys-Without-MMGen +[04]: https://bitcoin.org/en/developer-examples#testnet +[05]: https://bitcoin.org/en/developer-examples#regtest-mode diff --git a/mmgen/addr.py b/mmgen/addr.py index fd3b9423..35df9314 100755 --- a/mmgen/addr.py +++ b/mmgen/addr.py @@ -516,7 +516,7 @@ Removed %s duplicate wif key%s from keylist (also in {pnm} key-address file mmtype = MMGenAddrType(mmtype) except: 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: mmtype = MMGenAddrType('L') 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 else: 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.set_pw_fmt(pw_fmt) self.set_pw_len(pw_len) diff --git a/mmgen/color.py b/mmgen/color.py index 4d7d8a7e..139964f4 100755 --- a/mmgen/color.py +++ b/mmgen/color.py @@ -58,11 +58,11 @@ def nocolor(s): return s def init_color(enable_color=True,num_colors='auto'): if enable_color: - assert num_colors in ['auto',8,16,256] + assert num_colors in ('auto',8,16,256) globals()['_reset'] = '\033[0m' - if num_colors in [8,16]: + if num_colors in (8,16): pfx = '_16_' - elif num_colors in [256]: + elif num_colors in (256,): pfx = '_256_' else: try: @@ -87,7 +87,7 @@ def test_color(): colorama.init(strip=True,convert=True) except: 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) print('{:9}: {}'.format(desc,' '.join([globals()[c](c) for c in sorted(_colors)]))) diff --git a/mmgen/globalvars.py b/mmgen/globalvars.py index f1d7d1cd..a2099b9a 100755 --- a/mmgen/globalvars.py +++ b/mmgen/globalvars.py @@ -38,7 +38,7 @@ class g(object): sys.exit(ev) # Variables - these might be altered at runtime: - version = '0.9.199' + version = '0.9.2rc1' release_date = 'July 2017' proj_name = 'MMGen' diff --git a/mmgen/obj.py b/mmgen/obj.py index ef3d6768..92a95690 100755 --- a/mmgen/obj.py +++ b/mmgen/obj.py @@ -79,7 +79,7 @@ class MMGenObject(object): # print repr(self.__dict__.keys()) 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) if isList(e) or isDict(e): out.append(u'{:>{l}}{:<10} {:16}'.format('',k,'<'+type(e).__name__+'>',l=(lvl*8)+4)) diff --git a/mmgen/opts.py b/mmgen/opts.py index 4f434e07..61bfdf3a 100755 --- a/mmgen/opts.py +++ b/mmgen/opts.py @@ -180,7 +180,7 @@ def init(opts_data,add_opts=[],opt_filter=None): # We don't need this data anymore 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] # Transfer uopts into opt, setting program's opts + required opts to None if not set by user diff --git a/mmgen/tx.py b/mmgen/tx.py index 9c9a86a1..a943b340 100755 --- a/mmgen/tx.py +++ b/mmgen/tx.py @@ -449,7 +449,7 @@ class MMGenTX(MMGenObject): sig_data = [] 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'] del e['amt'] wif = keys[d.addr] @@ -477,7 +477,7 @@ class MMGenTX(MMGenObject): return True else: msg('failed\nBitcoind returned the following errors:') - pmsg(sig_tx['errors']) + msg(repr(sig_tx['errors'])) return False def mark_raw(self): diff --git a/test/gentest.py b/test/gentest.py index 49faff61..95b7fd97 100755 --- a/test/gentest.py +++ b/test/gentest.py @@ -99,7 +99,7 @@ except: else: try: 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 except: die(1,"%s: invalid generator IDs" % cmd_args[0]) diff --git a/test/test.py b/test/test.py index 906e3ad2..05013959 100755 --- a/test/test.py +++ b/test/test.py @@ -384,7 +384,7 @@ cfgs = { } 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]['tmpdir'] = os.path.join('test','tmp'+b) @@ -540,7 +540,7 @@ for k,v in ( cmd_data['info_ref'] = 'reference data',[6,7,8] 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) cmd_list['ref'].append(k) 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] 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) cmd_list['conv_in'].append(k) 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] 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) cmd_list['conv_out'].append(k) 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 for k in cfgs: 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]) meta_cmds = OrderedDict([ @@ -611,7 +611,7 @@ del cmd_group add_spawn_args = ' '.join(['{} {}'.format( '--'+k.replace('_','-'), 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] if opt.profile: opt.names = True @@ -1539,7 +1539,7 @@ class MMGenTestSuite(object): t.expect('OK? (Y/n): ','\n') if seed_args: # sign and send 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.expect("Type uppercase 'YES' to confirm: ",'YES\n') else: @@ -1839,7 +1839,7 @@ class MMGenTestSuite(object): t.expect('Check key-to-address validity? (y/N): ','y') 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']) if txdo_handle: return diff --git a/test/tooltest.py b/test/tooltest.py index bfaa516f..76a1bbc5 100755 --- a/test/tooltest.py +++ b/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( '--'+k.replace('_','-'), 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 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(addr,is_btc_addr,'Bitcoin address') 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] self.run_cmd_out(name,wif,kwargs=k,fn_idx=n,extra_msg=m) 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] self.run_cmd_out(name,wif,fn_idx=n,extra_msg=m) 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')): ret = self.run_cmd(name,[keys[n]],kwargs=k).rstrip() iaddr = read_from_tmpfile(cfg,'Randpair{}.out'.format(n+1)).split()[-1] cmp_or_die(iaddr,ret) 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) 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] self.run_cmd_out(name,addr,fn_idx=n,extra_msg=m) 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) def Privhex2pubhex(self,name,f1,f2,f3): # from hex2wif addr = read_from_file(f3).strip() @@ -388,11 +388,11 @@ class MMGenToolTestSuite(object): # Mnemonic 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) self.run_cmd_out(name,hexnum,fn_idx=n,extra_msg=m) 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) def Mn_rand128(self,name): self.run_cmd_out(name) def Mn_rand192(self,name): self.run_cmd_out(name)