Version 0.8.1

This commit is contained in:
The MMGen Project 2015-05-01 22:04:07 +03:00
commit 85d94eaec1
13 changed files with 275 additions and 165 deletions

View file

@ -74,7 +74,14 @@ This is a workaround for a dependency issue with the package's setup script.
If your Python is installed in a different location, you'll have to adjust the
destination path accordingly.
#### 7. Install MMGen:
#### 7. Install the colorama Python module (optional but recommended):
Grab the [tarball][14] and unpack it. At the MSYS prompt, run:
$ cd /c/colorama-0.3.3
$ python setup.py install
#### 8. Install MMGen:
Get the [zip archive][10] from GitHub and unpack it. At the MSYS prompt, run:
@ -103,3 +110,4 @@ a new MSYS window to update your path.
[11]: http://slproweb.com/download/Win32OpenSSL-1_0_1f.exe
[12]: http://www.openssl.org/related/binaries.html
[13]: Getting-Started-with-MMGen
[14]: https://pypi.python.org/pypi/colorama

View file

@ -67,7 +67,7 @@ def decrypt_seed(enc_seed, key, seed_id, key_id):
chk1 = make_chksum_8(key)
if key_id:
if not compare_chksums(key_id,"key ID",chk1,"computed"):
msg("Incorrect passphrase")
msg("Incorrect passphrase or hash preset")
return False
dec_seed = decrypt_data(enc_seed, key, iv=1, desc="seed")
@ -83,7 +83,7 @@ def decrypt_seed(enc_seed, key, seed_id, key_id):
if compare_chksums(key_id,"key ID",chk1,"computed"):
msg("Key ID is correct but decryption of seed failed")
else:
msg("Incorrect passphrase")
msg("Incorrect passphrase or hash preset")
vmsg("")
return False

View file

@ -49,7 +49,7 @@ prog_name = os.path.basename(sys.argv[0])
author = "Philemon"
email = "<mmgen-py@yandex.com>"
Cdates = '2013-2015'
version = '0.8.1rc1'
version = '0.8.1'
required_opts = [
"quiet","verbose","debug","outdir","echo_passphrase","passwd_file",

View file

@ -97,8 +97,7 @@ program now and rerun it using the '--rescan' option. Otherwise you may ignore
this message and continue.
""".strip()
if opt.quiet: m = ""
confirm_or_exit(m, "continue", expect="YES")
if not opt.quiet: confirm_or_exit(m, "continue", expect="YES")
err_flag = False

View file

@ -61,7 +61,7 @@ import math
import mmgen.globalvars as g
import mmgen.opt as opt
from mmgen.util import msg,mdie,mmsg
from mmgen.util import msg,mdie,mmsg,write_data_to_file
max_version = 60000
addrtype = 0
@ -73,15 +73,16 @@ opts_data = {
'desc': "Dump contents of a bitcoind wallet to file",
'usage': "[opts] <bitcoind wallet file>",
'options': """
-h, --help Print this help message
-d, --outdir= d Specify an alternate directory 'd' for output
-e, --echo-passphrase Display passphrase on screen upon entry
-j, --json Dump wallet in json format
-k, --keys Dump all private keys (flat list)
-a, --addrs Dump all addresses (flat list)
-K, --keysforaddrs= f Dump private keys for addresses listed in file 'f'
-P, --passwd-file= f Get passphrase from file 'f'
-S, --stdout Dump to stdout rather than file
-h, --help Print this help message.
-d, --outdir= d Specify an alternate directory 'd' for output.
-e, --echo-passphrase Display passphrase on screen upon entry.
-j, --json Dump wallet in json format.
-k, --keys Dump all private keys (flat list).
-a, --addrs Dump all addresses (flat list).
-K, --keysforaddrs= f Dump private keys for addresses listed in file 'f'.
-P, --passwd-file= f Get passphrase from file 'f'.
-q, --quiet Produce quieter output; suppress some warnings.
-S, --stdout Dump to stdout rather than file.
"""
}
@ -1540,9 +1541,13 @@ def read_wallet(json_db, db_env, db_file, print_wallet, print_wallet_transaction
mkey['vchOtherDerivationParameters'] = d['vchOtherDerivationParameters'].encode('hex')
json_db['mkey'] = mkey
if password == None and (opt.json or opt.keysforaddr or opt.keys):
from mmgen.util import get_bitcoind_passphrase
password = get_bitcoind_passphrase("Enter password: ")
if password == None and (opt.json or opt.keysforaddrs or opt.keys):
if opt.passwd_file:
from mmgen.util import get_data_from_file
password = get_data_from_file(opt.passwd_file).rstrip()
else:
from mmgen.util import get_bitcoind_passphrase
password = get_bitcoind_passphrase("Enter password: ")
if password != None:
global crypter
@ -1665,9 +1670,15 @@ wallet_id = make_chksum_8(str(sorted(wallet_addrs)))
data = "\n".join(data) + "\n"
# Output data
if opt.stdout or not sys.stdout.isatty():
conf = not (opt.addrs or not sys.stdout.isatty())
write_to_stdout(data,"secret keys",conf)
else:
of = "wd_%s[%s].%s" % (wallet_id,len_arg,ext)
write_to_file(of, data, what, confirm_overwrite=True,verbose=True)
of = "wd_%s[%s].%s" % (wallet_id,len_arg,ext)
write_data_to_file(of, data, what, ask_overwrite=not opt.quiet)
# outfile,
# data,
# desc="data",
# ask_write=False,
# ask_write_prompt="",
# ask_write_default_yes=False,
# ask_overwrite=True,
# ask_tty=True,
# no_tty=False,
# silent=False

View file

@ -155,6 +155,8 @@ class SeedSource(MMGenObject):
def _decrypt_retry(self):
while True:
if self._decrypt(): break
if opt.passwd_file:
die(2,"Passphrase from password file, so exiting")
msg("Trying again...")
subclasses = []

View file

@ -30,8 +30,10 @@ import mmgen.globalvars as g
pnm = g.proj_name
_red,_grn,_yel,_cya,_reset = (
["\033[%sm" % c for c in "31;1","32;1","33;1","36;1","0"]
)
["\033[%sm" % c for c in "31;1","32;1","33;1","36;1","0"],
["","","","",""]
)[int(sys.platform[:3] == "win")]
def red(s): return _red+s+_reset
def green(s): return _grn+s+_reset
def yellow(s): return _yel+s+_reset
@ -456,10 +458,10 @@ def write_data_to_file(
hush = False
if file_exists(outfile):
if ask_overwrite:
q = "File '%s' already exists\nOverwrite?" % outfile
confirm_or_exit("",q)
if not silent: msg("Overwriting file '%s'" % outfile)
if ask_overwrite and not silent:
q = "File '%s' already exists\nOverwrite?" % outfile
confirm_or_exit("",q)
msg("Overwriting file '%s'" % outfile)
hush = True
f = open_file_or_exit(outfile,'wb')

View file

@ -21,7 +21,7 @@ from distutils.core import setup
setup(
name = 'mmgen',
description = 'A complete Bitcoin cold-storage solution for the command line',
version = '0.8.1rc1',
version = '0.8.1',
author = 'Philemon',
author_email = 'mmgen-py@yandex.com',
url = 'https://github.com/mmgen/mmgen',

View file

@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/env python
# Chdir to repo root.
# Since script is not in repo root, fix sys.path so that modules are

BIN
test/ref/wallet-enc.dat Normal file

Binary file not shown.

BIN
test/ref/wallet-unenc.dat Normal file

Binary file not shown.

View file

@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/env python
# Chdir to repo root.
# Since script is not in repo root, fix sys.path so that modules are
@ -8,11 +8,26 @@ pn = os.path.dirname(sys.argv[0])
os.chdir(os.path.join(pn,os.pardir))
sys.path.__setitem__(0,os.path.abspath(os.curdir))
scripts = (
"addrgen", "addrimport", "keygen",
"passchg", "pywallet", "tool",
"txcreate", "txsend", "txsign",
"walletchk", "walletconv", "walletgen"
)
import mmgen.globalvars as g
import mmgen.opt as opt
from mmgen.util import mmsg,mdie,Msg,die,capfirst
from mmgen.util import mmsg,mdie,Msg,die,capfirst,write_data_to_file
from mmgen.test import *
if sys.platform[:3] == "win":
try:
import colorama
colorama.init(strip=True,convert=True)
except:
def nocolor(s): return s
red = green = yellow = cyan = nocolor
tb_cmd = "scripts/traceback.py"
hincog_fn = "rand_data"
hincog_bytes = 1024*1024
@ -21,6 +36,7 @@ hincog_seedlen = 256
incog_id_fn = "incog_id"
non_mmgen_fn = "btckey"
pwfile = "passwd_file"
ref_dir = os.path.join("test","ref")
@ -41,6 +57,74 @@ sample_text = \
"The Times 03/Jan/2009 Chancellor on brink of second bailout for banks\n"
cfgs = {
'1': {
'tmpdir': os.path.join("test","tmp1"),
'wpasswd': "Dorian",
'kapasswd': "Grok the blockchain",
'addr_idx_list': "12,99,5-10,5,12", # 8 addresses
'dep_generators': {
pwfile: "walletgen",
'mmdat': "walletgen",
'addrs': "addrgen",
'raw': "txcreate",
'sig': "txsign",
'mmwords': "export_mnemonic",
'mmseed': "export_seed",
'mmincog': "export_incog",
'mmincox': "export_incog_hex",
hincog_fn: "export_incog_hidden",
incog_id_fn: "export_incog_hidden",
'akeys.mmenc': "keyaddrgen"
},
},
'2': {
'tmpdir': os.path.join("test","tmp2"),
'wpasswd': "Hodling away",
'addr_idx_list': "37,45,3-6,22-23", # 8 addresses
'seed_len': 128,
'dep_generators': {
'mmdat': "walletgen2",
'addrs': "addrgen2",
'raw': "txcreate2",
'sig': "txsign2",
'mmwords': "export_mnemonic2",
},
},
'3': {
'tmpdir': os.path.join("test","tmp3"),
'wpasswd': "Major miner",
'addr_idx_list': "73,54,1022-1023,2-5", # 8 addresses
'dep_generators': {
'mmdat': "walletgen3",
'addrs': "addrgen3",
'raw': "txcreate3",
'sig': "txsign3"
},
},
'4': {
'tmpdir': os.path.join("test","tmp4"),
'wpasswd': "Hashrate rising",
'addr_idx_list': "63,1004,542-544,7-9", # 8 addresses
'seed_len': 192,
'dep_generators': {
'mmdat': "walletgen4",
'mmbrain': "walletgen4",
'addrs': "addrgen4",
'raw': "txcreate4",
'sig': "txsign4",
},
'bw_filename': "brainwallet.mmbrain",
'bw_params': "192,1",
},
'5': {
'tmpdir': os.path.join("test","tmp5"),
'wpasswd': "My changed password",
'hash_preset': '2',
'dep_generators': {
'mmdat': "passchg",
pwfile: "passchg",
},
},
'6': {
'name': "reference wallet check (128-bit)",
'seed_len': 128,
@ -122,75 +206,11 @@ cfgs = {
'akeys.mmenc': "refkeyaddrgen3"
},
},
'1': {
'tmpdir': os.path.join("test","tmp1"),
'wpasswd': "Dorian",
'kapasswd': "Grok the blockchain",
'addr_idx_list': "12,99,5-10,5,12", # 8 addresses
'dep_generators': {
'mmdat': "walletgen",
'addrs': "addrgen",
'raw': "txcreate",
'sig': "txsign",
'mmwords': "export_mnemonic",
'mmseed': "export_seed",
'mmincog': "export_incog",
'mmincox': "export_incog_hex",
hincog_fn: "export_incog_hidden",
incog_id_fn: "export_incog_hidden",
'akeys.mmenc': "keyaddrgen"
},
},
'2': {
'tmpdir': os.path.join("test","tmp2"),
'wpasswd': "Hodling away",
'addr_idx_list': "37,45,3-6,22-23", # 8 addresses
'seed_len': 128,
'dep_generators': {
'mmdat': "walletgen2",
'addrs': "addrgen2",
'raw': "txcreate2",
'sig': "txsign2",
'mmwords': "export_mnemonic2",
},
},
'3': {
'tmpdir': os.path.join("test","tmp3"),
'wpasswd': "Major miner",
'addr_idx_list': "73,54,1022-1023,2-5", # 8 addresses
'dep_generators': {
'mmdat': "walletgen3",
'addrs': "addrgen3",
'raw': "txcreate3",
'sig': "txsign3"
},
},
'4': {
'tmpdir': os.path.join("test","tmp4"),
'wpasswd': "Hashrate rising",
'addr_idx_list': "63,1004,542-544,7-9", # 8 addresses
'seed_len': 192,
'dep_generators': {
'mmdat': "walletgen4",
'mmbrain': "walletgen4",
'addrs': "addrgen4",
'raw': "txcreate4",
'sig': "txsign4",
},
'bw_filename': "brainwallet.mmbrain",
'bw_params': "192,1",
},
'5': {
'tmpdir': os.path.join("test","tmp5"),
'wpasswd': "My changed password",
'dep_generators': {
'mmdat': "passchg",
},
},
'9': {
'tmpdir': os.path.join("test","tmp9"),
'tool_enc_infn': "tool_encrypt.in",
# 'tool_enc_ref_infn': "tool_encrypt_ref.in",
'wpasswd': "reference password",
'dep_generators': {
'tool_encrypt.in': "tool_encrypt",
'tool_encrypt.in.mmenc': "tool_encrypt",
@ -208,14 +228,15 @@ for a,b in ('6','11'),('7','12'),('8','13'):
from collections import OrderedDict
cmd_data = OrderedDict([
# test description depends
['walletgen', (1,'wallet generation', [[[],1]])],
['helpscreens', (1,'help screens', [],1)],
['walletgen', (1,'wallet generation', [[[],1]],1)],
# ['walletchk', (1,'wallet check', [[["mmdat"],1]])],
['passchg', (5,'password, label and hash preset change',[[["mmdat"],1]])],
['walletchk_newpass',(5,'wallet check with new pw, label and hash preset',[[["mmdat"],5]])],
['addrgen', (1,'address generation', [[["mmdat"],1]])],
['addrimport', (1,'address import', [[["addrs"],1]])],
['txcreate', (1,'transaction creation', [[["addrs"],1]])],
['txsign', (1,'transaction signing', [[["mmdat","raw"],1]])],
['passchg', (5,'password, label and hash preset change',[[["mmdat",pwfile],1]],1)],
['walletchk_newpass',(5,'wallet check with new pw, label and hash preset',[[["mmdat",pwfile],5]],1)],
['addrgen', (1,'address generation', [[["mmdat",pwfile],1]],1)],
['addrimport', (1,'address import', [[["addrs"],1]],1)],
['txcreate', (1,'transaction creation', [[["addrs"],1]],1)],
['txsign', (1,'transaction signing', [[["mmdat","raw",pwfile],1]],1)],
['txsend', (1,'transaction sending', [[["sig"],1]])],
['export_seed', (1,'seed export to mmseed format', [[["mmdat"],1]])],
@ -252,6 +273,7 @@ cmd_data = OrderedDict([
['tool_decrypt', (9,"'mmgen-tool decrypt' (random data)", [[[cfgs['9']['tool_enc_infn'],cfgs['9']['tool_enc_infn']+".mmenc"],9]])],
# ['tool_encrypt_ref', (9,"'mmgen-tool encrypt' (reference text)", [])],
['tool_find_incog_data', (9,"'mmgen-tool find_incog_data'", [[[hincog_fn],1],[[incog_id_fn],1]])],
['pywallet', (9,"'mmgen-pywallet'", [],1)],
])
# saved reference data
@ -349,7 +371,7 @@ meta_cmds = OrderedDict([
['3', [k for k in cmd_data if cmd_data[k][0] == 3]],
['4', [k for k in cmd_data if cmd_data[k][0] == 4]],
['tool', ("tool_encrypt","tool_decrypt","tool_find_incog_data")],
['tool', ("tool_encrypt","tool_decrypt","tool_find_incog_data","pywallet")],
['saved_ref1', [c[0]+"1" for c in cmd_data_ref]],
['saved_ref2', [c[0]+"2" for c in cmd_data_ref]],
@ -367,23 +389,25 @@ meta_cmds = OrderedDict([
])
opts_data = {
# 'sets': [('non_interactive',bool,'verbose',None)],
'desc': "Test suite for the MMGen suite",
'usage':"[options] [command(s) or metacommand(s)]",
'options': """
-h, --help Print this help message
-b, --buf-keypress Use buffered keypresses as with real human input
-d, --debug-scripts Turn on debugging output in executed scripts
-h, --help Print this help message.
-b, --buf-keypress Use buffered keypresses as with real human input.
-d, --debug-scripts Turn on debugging output in executed scripts.
-D, --direct-exec Bypass pexpect and execute a command directly (for
debugging only)
-e, --exact-output Show the exact output of the MMGen script(s) being run
-l, --list-cmds List and describe the tests and commands in the test suite
-n, --names Display command names instead of descriptions
-p, --pause Pause between tests, resuming on keypress
-q, --quiet Produce minimal output. Suppress dependency info
-s, --system Test scripts and modules installed on system rather than
those in the repo root
-t, --traceback Run the command inside the '{tb_cmd}' script
-v, --verbose Produce more verbose output
debugging only).
-e, --exact-output Show the exact output of the MMGen script(s) being run.
-l, --list-cmds List and describe the commands in the test suite.
-n, --names Display command names instead of descriptions.
-I, --non-interactive Non-interactive operation (MS Windows mode)
-p, --pause Pause between tests, resuming on keypress.
-q, --quiet Produce minimal output. Suppress dependency info.
-s, --system Test scripts and modules installed on system rather
than those in the repo root.
-t, --traceback Run the command inside the '{tb_cmd}' script.
-v, --verbose Produce more verbose output.
""".format(tb_cmd=tb_cmd),
'notes': """
@ -394,6 +418,7 @@ If no command is given, the whole suite of tests is run.
cmd_args = opt.opts.init(opts_data)
if opt.system: sys.path.pop(0)
ni = bool(opt.non_interactive)
# temporary
#os.environ["MMGEN_USE_OLD_SCRIPTS"] = "1"
@ -421,7 +446,8 @@ stderr_save = sys.stderr
def silence():
if not (opt.verbose or opt.exact_output):
sys.stderr = open("/dev/null","a")
f = ("/dev/null","stderr.out")[int(sys.platform[:3] == "win")]
sys.stderr = open(f,"a")
def end_silence():
if not (opt.verbose or opt.exact_output):
@ -453,7 +479,13 @@ if opt.list_cmds:
Msg(fs.format(cmd,utils[cmd],w=w))
sys.exit()
import pexpect,time,re
import time,re
try:
import pexpect
except: # Windows
msg(red("MS Windows detected (or missing pexpect module). Running in non-interactive mode"))
ni = True
from mmgen.util import get_data_from_file,write_to_file,get_lines_from_file
def my_send(p,t,delay=send_delay,s=False):
@ -527,7 +559,7 @@ def verify_checksum_or_exit(checksum,chk):
class MMGenExpect(object):
def __init__(self,name,mmgen_cmd,cmd_args=[],extra_desc=""):
def __init__(self,name,mmgen_cmd,cmd_args=[],extra_desc="",no_output=False):
if not opt.system:
mmgen_cmd = os.path.join(os.curdir,mmgen_cmd)
desc = (cmd_data[name][1],name)[int(bool(opt.names))]
@ -540,9 +572,11 @@ class MMGenExpect(object):
else:
msg_r("Testing %s: " % desc)
if opt.direct_exec:
os.system(" ".join([mmgen_cmd] + cmd_args))
sys.exit()
if opt.direct_exec or ni:
msg("")
from subprocess import check_call,check_output
f = (check_call,check_output)[int(no_output)]
f(["python", mmgen_cmd] + cmd_args)
else:
if opt.traceback:
cmd_args = [mmgen_cmd] + cmd_args
@ -825,6 +859,8 @@ class MMGenTestSuite(object):
def do_cmd(self,cmd):
if ni and (len(cmd_data[cmd]) < 4 or cmd_data[cmd][3] != 1): return
d = [(str(num),ext) for exts,num in cmd_data[cmd][2] for ext in exts]
al = [get_file_with_ext(ext,cfgs[num]['tmpdir']) for num,ext in d]
@ -839,10 +875,21 @@ class MMGenTestSuite(object):
def generate_cmd_deps(self,fdeps):
return [cfgs[str(n)]['dep_generators'][ext] for n,ext in fdeps]
def helpscreens(self,name):
for s in scripts:
t = MMGenExpect(name,("mmgen-"+s),["--help"],
extra_desc="(mmgen-%s)"%s,no_output=True)
if not ni:
t.read(); ok()
def walletgen(self,name,seed_len=None):
args = ["-d",cfg['tmpdir'],"-p1","-r10"]
write_to_tmpfile(cfg,pwfile,cfg['wpasswd']+"\n")
add_args = (["-r10"],
["-q","-r0","-L","NI Wallet","-P",get_tmpfile_fn(cfg,pwfile)])[int(ni)]
args = ["-d",cfg['tmpdir'],"-p1"]
if seed_len: args += ["-l",str(seed_len)]
t = MMGenExpect(name,"mmgen-walletgen", args)
t = MMGenExpect(name,"mmgen-walletgen", args + add_args)
if ni: return
t.license()
t.usr_rand(10)
t.passphrase_new("new MMGen wallet",cfg['wpasswd'])
@ -868,10 +915,15 @@ class MMGenTestSuite(object):
refwalletgen1 = refwalletgen2 = refwalletgen3 = refwalletgen
def passchg(self,name,walletfile):
t = MMGenExpect(name,"mmgen-passchg",
["-d",cfg['tmpdir'],"-p","2","-L","New Label","-r","16",walletfile])
def passchg(self,name,wf,pf):
# ni: reuse password, since there's no way to change it non-interactively
silence()
write_to_tmpfile(cfg,pwfile,get_data_from_file(pf))
end_silence()
add_args = (["-r16"],["-q","-r0","-P",pf])[int(ni)]
t = MMGenExpect(name,"mmgen-passchg", add_args +
["-d",cfg['tmpdir'],"-p","2","-L","New Label",wf])
if ni: return
t.license()
t.passphrase("MMGen wallet",cfgs['1']['wpasswd'],pwtype="old")
t.expect_getend("Hash preset changed to ")
@ -883,22 +935,24 @@ class MMGenTestSuite(object):
t.written_to_file("MMGen wallet")
ok()
def walletchk_beg(self,name,args):
t = MMGenExpect(name,"mmgen-walletchk", args)
t.expect("Getting MMGen wallet from file '%s'" % args[-1])
def walletchk(self,name,wf,pf):
args = ["-P",pf,"-q"] if ni and pf else []
hp = cfg['hash_preset'] if 'hash_preset' in cfg else '1'
t = MMGenExpect(name,"mmgen-walletchk", args + ["-p",hp] + [wf])
if ni: return
t.expect("Getting MMGen wallet from file '%s'" % wf)
t.passphrase("MMGen wallet",cfg['wpasswd'])
t.expect("Passphrase is OK")
t.expect_getend("Valid MMGen wallet for seed ID ")
return t
def walletchk(self,name,walletfile):
self.walletchk_beg(name,[walletfile])
ok()
walletchk_newpass = walletchk
def addrgen(self,name,walletfile,check_ref=False):
t = MMGenExpect(name,"mmgen-addrgen",["-d",cfg['tmpdir'],walletfile,cfg['addr_idx_list']])
def addrgen(self,name,wf,pf,check_ref=False):
add_args = ["-P",pf,"-q"] if ni else []
t = MMGenExpect(name,"mmgen-addrgen", add_args +
["-d",cfg['tmpdir'],wf,cfg['addr_idx_list']])
if ni: return
t.license()
t.passphrase("MMGen wallet",cfg['wpasswd'])
t.expect("Passphrase is OK")
@ -909,16 +963,18 @@ class MMGenTestSuite(object):
t.written_to_file("Addresses",oo=True)
ok()
def refaddrgen(self,name,walletfile):
def refaddrgen(self,name,wf):
d = " (%s-bit seed)" % cfg['seed_len']
self.addrgen(name,walletfile,check_ref=True)
self.addrgen(name,wf,pf="",check_ref=True)
refaddrgen1 = refaddrgen2 = refaddrgen3 = refaddrgen
def addrimport(self,name,addrfile):
add_args = ["-q","-t"] if ni else []
outfile = os.path.join(cfg['tmpdir'],"addrfile_w_comments")
add_comments_to_addr_file(addrfile,outfile)
t = MMGenExpect(name,"mmgen-addrimport",[outfile])
t = MMGenExpect(name,"mmgen-addrimport", add_args + [outfile])
if ni: return
t.expect_getend(r"Checksum for address data .*\[.*\]: ",regex=True)
t.expect_getend("Validating addresses...OK. ")
t.expect("Type uppercase 'YES' to confirm: ","\n")
@ -976,7 +1032,13 @@ class MMGenTestSuite(object):
end_silence()
if opt.verbose or opt.exact_output: sys.stderr.write("\n")
t = MMGenExpect(name,"mmgen-txcreate",cmd_args)
add_args = ["-q"] if ni else []
if ni:
m = "Answer the interactive prompts as follows:\n" + \
" 'y', 'y', 'q', '1-8', ENTER, ENTER, ENTER, 'y'"
msg(green(m))
t = MMGenExpect(name,"mmgen-txcreate",add_args + cmd_args)
if ni: return
t.license()
for num in tx_data.keys():
t.expect_getend("Getting address data from file ")
@ -1014,9 +1076,14 @@ class MMGenTestSuite(object):
add = " #" + tnum if tnum else ""
t.written_to_file("Signed transaction" + add)
def txsign(self,name,txfile,walletfile,save=True):
t = MMGenExpect(name,"mmgen-txsign",
["-d",cfg['tmpdir'],txfile,walletfile])
def txsign(self,name,txfile,wf,pf="",save=True):
add_args = ["-q","-P",pf] if ni else []
if ni:
m = "Answer the interactive prompts as follows:\n ENTER, ENTER, 'y'"
msg(green(m))
t = MMGenExpect(name,"mmgen-txsign", add_args +
["-d",cfg['tmpdir'],txfile,wf])
if ni: return
t.license()
t.tx_view()
t.passphrase("MMGen wallet",cfg['wpasswd'])
@ -1088,11 +1155,11 @@ class MMGenTestSuite(object):
self.export_incog(
name,wf,desc="hidden incognito data",out_fmt="hi",add_args=add_args)
def addrgen_seed(self,name,walletfile,foo,desc="seed data",in_fmt="seed"):
def addrgen_seed(self,name,wf,foo,desc="seed data",in_fmt="seed"):
stdout = (False,True)[int(desc=="seed data")] #capture output to screen once
add_arg = ([],["-S"])[int(stdout)]
t = MMGenExpect(name,"mmgen-addrgen", add_arg +
["-i"+in_fmt,"-d",cfg['tmpdir'],walletfile,cfg['addr_idx_list']])
["-i"+in_fmt,"-d",cfg['tmpdir'],wf,cfg['addr_idx_list']])
t.license()
t.expect_getend("Valid %s for seed ID " % desc)
vmsg("Comparing generated checksum with checksum from previous address file")
@ -1130,9 +1197,9 @@ class MMGenTestSuite(object):
self.addrgen_incog(name,[],"",in_fmt="hi",desc="hidden incognito data",
args=["-H","%s,%s"%(rf,hincog_offset),"-l",str(hincog_seedlen)])
def keyaddrgen(self,name,walletfile,check_ref=False):
def keyaddrgen(self,name,wf,check_ref=False):
t = MMGenExpect(name,"mmgen-keygen",
["-d",cfg['tmpdir'],walletfile,cfg['addr_idx_list']])
["-d",cfg['tmpdir'],wf,cfg['addr_idx_list']])
t.license()
t.passphrase("MMGen wallet",cfg['wpasswd'])
chk = t.expect_getend(r"Checksum for key-address data .*?: ",regex=True)
@ -1145,8 +1212,8 @@ class MMGenTestSuite(object):
t.written_to_file("Secret keys",oo=True)
ok()
def refkeyaddrgen(self,name,walletfile):
self.keyaddrgen(name,walletfile,check_ref=True)
def refkeyaddrgen(self,name,wf):
self.keyaddrgen(name,wf,check_ref=True)
refkeyaddrgen1 = refkeyaddrgen2 = refkeyaddrgen3 = refkeyaddrgen
@ -1163,8 +1230,8 @@ class MMGenTestSuite(object):
def walletgen2(self,name):
self.walletgen(name,seed_len=128)
def addrgen2(self,name,walletfile):
self.addrgen(name,walletfile)
def addrgen2(self,name,wf):
self.addrgen(name,wf,pf="")
def txcreate2(self,name,addrfile):
self.txcreate_common(name,sources=['2'])
@ -1178,14 +1245,14 @@ class MMGenTestSuite(object):
self.txsign_end(t,cnum)
ok()
def export_mnemonic2(self,name,walletfile):
self.export_mnemonic(name,walletfile)
def export_mnemonic2(self,name,wf):
self.export_mnemonic(name,wf)
def walletgen3(self,name):
self.walletgen(name)
def addrgen3(self,name,walletfile):
self.addrgen(name,walletfile)
def addrgen3(self,name,wf):
self.addrgen(name,wf,pf="")
def txcreate3(self,name,addrfile1,addrfile2):
self.txcreate_common(name,sources=['1','3'])
@ -1215,8 +1282,8 @@ class MMGenTestSuite(object):
def walletgen4(self,name): self.brainwalletgen_pwfile(name)
def addrgen4(self,name,walletfile):
self.addrgen(name,walletfile)
def addrgen4(self,name,wf):
self.addrgen(name,wf,pf="")
def txcreate4(self,name,f1,f2,f3,f4):
self.txcreate_common(name,sources=['1','2','3','4'],non_mmgen_input='4')
@ -1272,6 +1339,27 @@ class MMGenTestSuite(object):
os.unlink(f1)
cmp_or_die(hincog_offset,int(o))
def pywallet(self,name): # TODO - check output
pf = get_tmpfile_fn(cfg,pwfile)
write_data_to_file(pf,cfg['wpasswd']+"\n",silent=True)
args = ["-q","-P",pf] if ni else []
unenc_wf = os.path.join(ref_dir,"wallet-unenc.dat")
enc_wf = os.path.join(ref_dir,"wallet-enc.dat")
for wf,enc in (unenc_wf,False),(enc_wf,True):
for w,o,pk in (
("addresses","a",False),
("private keys","k",True),
("json dump","j",True)
):
ed = "(%sencrypted wallet, %s)" % (("un","")[int(enc)],w)
t = MMGenExpect(name,"mmgen-pywallet", args +
["-"+o,"-d",cfg['tmpdir']] + [wf], extra_desc=ed)
if ni: continue
if pk and enc and not ni:
t.expect("Enter password: ",cfg['wpasswd']+"\n")
t.written_to_file(capfirst(w),oo=True)
if not ni: ok()
def walletconv_out(self,name,desc,out_fmt="w",uopts=[],uopts_chk=[],pw=False):
opts = ["-d",cfg['tmpdir'],"-r10","-p1","-o",out_fmt] + uopts
infile = os.path.join(ref_dir,cfg['seed_id']+".mmwords")
@ -1397,7 +1485,7 @@ class MMGenTestSuite(object):
def ref_wallet_chk(self,name):
wf = os.path.join(ref_dir,cfg['ref_wallet'])
self.walletchk(name,wf)
self.walletchk(name,wf,pf="")
ref_wallet_chk1 = ref_wallet_chk2 = ref_wallet_chk3 = ref_wallet_chk

View file

@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/env python
# Chdir to repo root.
# Since script is not in repo root, fix sys.path so that modules are