From 4912d086a2a2240fec29865333faf45723356bbf Mon Sep 17 00:00:00 2001 From: philemon Date: Thu, 5 Dec 2013 22:28:01 +0400 Subject: [PATCH] Improved tx scripts; bug fix in password-handling code; whitespace cleanups modified: mmgen-txcreate modified: mmgen-txsend modified: mmgen-txsign modified: mmgen/config.py modified: mmgen/license.py modified: mmgen/tx.py modified: mmgen/utils.py --- mmgen-txcreate | 46 -------------------- mmgen-txsend | 48 --------------------- mmgen-txsign | 42 ------------------ mmgen/config.py | 4 -- mmgen/license.py | 15 ------- mmgen/tx.py | 108 ----------------------------------------------- mmgen/utils.py | 40 ------------------ 7 files changed, 303 deletions(-) diff --git a/mmgen-txcreate b/mmgen-txcreate index 64d7724d..3983fb01 100755 --- a/mmgen-txcreate +++ b/mmgen-txcreate @@ -36,17 +36,6 @@ help_data = { 'desc': "Send BTC from specified outputs to specified addresses", 'usage': "[opts] ", 'options': """ -<<<<<<< HEAD --h, --help Print this help message --d, --outdir d Specify an alternate directory 'd' for output --e, --echo-passphrase Print passphrase to screen when typing it --q, --quiet Suppress warnings; overwrite files without asking -""" -} - -short_opts = "hd:eq" -long_opts = "help","outdir=","echo_passphrase","quiet" -======= -h, --help Print this help message -d, --outdir d Specify an alternate directory 'd' for output -e, --echo-passphrase Print passphrase to screen when typing it @@ -60,7 +49,6 @@ time of %s minutes. short_opts = "hd:eiq" long_opts = "help","outdir=","echo_passphrase","info","quiet" ->>>>>>> my opts,cmd_args = process_opts(sys.argv,help_data,short_opts,long_opts) @@ -77,13 +65,6 @@ if len(cmd_args) == 4: elif len(cmd_args) == 3: rcpt_addr,send_amt,tx_fee = cmd_args change_addr = "" -<<<<<<< HEAD -else: usage(help_data) - -check_address(rcpt_addr) -send_amt = check_btc_amt(send_amt) -tx_fee = check_btc_amt(tx_fee) -======= elif len(cmd_args) == 0 and 'info' in opts: pass else: usage(help_data) @@ -92,32 +73,10 @@ if not 'info' in opts: check_address(rcpt_addr) send_amt = check_btc_amt(send_amt) tx_fee = check_btc_amt(tx_fee) ->>>>>>> my # Begin execution c = connect_to_bitcoind() -<<<<<<< HEAD -if not 'quiet' in opts: do_license_msg() - -unspent = sort_and_view(c.listunspent()) - -total = remove_exponent(sum([i.amount for i in unspent])) - -msg("Total unspent: %s BTC" % total) -msg("Amount to spend: %s BTC" % send_amt) -msg("%s unspent outputs total" % len(unspent)) - -sel_unspent = select_outputs(unspent,"Choose the outputs to spend: ") - -total_in = remove_exponent(sum([o.amount for o in sel_unspent])) -change = remove_exponent(total_in - (send_amt + tx_fee)) - -if change < 0: - msg(txmsg['not_enough_btc'] % change) - sys.exit(2) -elif change > 0 and not change_addr: -======= if not 'quiet' in opts and not 'info' in opts: do_license_msg() unspent = sort_and_view(c.listunspent()) @@ -144,7 +103,6 @@ while True: msg(txmsg['not_enough_btc'] % change) if change > 0 and not change_addr: ->>>>>>> my msg(txmsg['throwaway_change'] % (change, total_in-tx_fee)) sys.exit(2) @@ -152,11 +110,7 @@ tx_in = [{"txid":i.txid, "vout":i.vout} for i in sel_unspent] tx_out = {rcpt_addr:float(send_amt), change_addr:float(change)} tx_hex = c.createrawtransaction(tx_in,tx_out) -<<<<<<< HEAD -msg("Transaction successfully created\n") -======= msg("Transaction successfully created") ->>>>>>> my prompt = "View decoded transaction?" if user_confirm(prompt,default_yes=False): view_tx_data(c,[i.__dict__ for i in sel_unspent],tx_hex) diff --git a/mmgen-txsend b/mmgen-txsend index 6f45f2e4..00c383ec 100755 --- a/mmgen-txsend +++ b/mmgen-txsend @@ -20,40 +20,17 @@ mmgen-txsend: Broadcast a Bitcoin transaction to the network """ import sys -<<<<<<< HEAD -#from hashlib import sha256 -======= ->>>>>>> my from mmgen.Opts import * from mmgen.license import * from mmgen.config import * from mmgen.tx import * -<<<<<<< HEAD -from mmgen.utils import msg,check_infile,get_lines_from_file,confirm_or_exit -======= from mmgen.utils import msg,check_opts,check_infile,get_lines_from_file,confirm_or_exit ->>>>>>> my prog_name = sys.argv[0].split("/")[-1] help_data = { 'prog_name': prog_name, -<<<<<<< HEAD - 'desc': "Sign a Bitcoin transaction generated by mmgen-txcreate", - 'usage': "[opts] ", - 'options': """ --h, --help Print this help message --q, --quiet Suppress warnings; overwrite files without asking -""" -} - -short_opts = "hq" -long_opts = "help","quiet" - -opts,cmd_args = process_opts(sys.argv,help_data,short_opts,long_opts) - -======= 'desc': "Send a Bitcoin transaction signed by mmgen-txsign", 'usage': "[opts] ", 'options': """ @@ -71,7 +48,6 @@ opts,cmd_args = process_opts(sys.argv,help_data,short_opts,long_opts) # Exits on invalid input check_opts(opts, ('outdir',)) ->>>>>>> my if len(cmd_args) == 1: infile = cmd_args[0] check_infile(infile) @@ -79,11 +55,6 @@ else: usage(help_data) # Begin execution -<<<<<<< HEAD -c = connect_to_bitcoind() - -tx_sig = get_lines_from_file(infile,"signed transaction")[0] -======= try: metadata,tx_sig = get_lines_from_file(infile,"signed transaction") except: @@ -94,24 +65,10 @@ metadata = metadata.split() if len(metadata) != 3: msg("Invalid file header") sys.exit(3) ->>>>>>> my from binascii import unhexlify try: unhexlify(tx_sig) except: -<<<<<<< HEAD - msg("Invalid transaction data") - sys.exit(3) - -msg("Successfully opened signed transaction file '%s'" % infile) - -confirm_or_exit("", "broadcast this transaction to the network") - -msg("Sending transaction") - -try: - tx = c.sendrawtransaction(tx_sig) -======= msg("Invalid signed transaction data") sys.exit(3) @@ -131,15 +88,10 @@ c = connect_to_bitcoind() try: tx = c.sendrawtransaction(tx_sig) # tx = "deadbeef" ->>>>>>> my except: msg("Unable to send transaction") sys.exit(3) msg("Transaction sent: %s" % tx) -<<<<<<< HEAD -print_sent_tx_to_file(tx) -======= print_sent_tx_to_file(tx,metadata,opts) ->>>>>>> my diff --git a/mmgen-txsign b/mmgen-txsign index f4f465a3..be4f22b8 100755 --- a/mmgen-txsign +++ b/mmgen-txsign @@ -35,19 +35,11 @@ help_data = { 'desc': "Sign a Bitcoin transaction generated by mmgen-txcreate", 'usage': "[opts] ", 'options': """ -<<<<<<< HEAD --h, --help Print this help message --d, --outdir d Specify an alternate directory 'd' for output --e, --echo-passphrase Print passphrase to screen when typing it --i, --info Just show info about the transaction and exit --q, --quiet Suppress warnings; overwrite files without asking -======= -h, --help Print this help message -d, --outdir d Specify an alternate directory 'd' for output -e, --echo-passphrase Print passphrase to screen when typing it -i, --info Display information about the transaction and exit -q, --quiet Suppress warnings; overwrite files without asking ->>>>>>> my """ } @@ -74,17 +66,10 @@ c = connect_to_bitcoind() tx_data = get_lines_from_file(infile,"transaction data") -<<<<<<< HEAD -timestamp,tx_hex,sig_data,inputs_data = parse_tx_data(tx_data) - -if 'info' in opts: - view_tx_data(c,inputs_data,tx_hex,timestamp) -======= metadata,tx_hex,sig_data,inputs_data = parse_tx_data(tx_data) if 'info' in opts: view_tx_data(c,inputs_data,tx_hex,metadata) ->>>>>>> my sys.exit(0) if not 'quiet' in opts and not 'info' in opts: do_license_msg() @@ -92,15 +77,9 @@ if not 'quiet' in opts and not 'info' in opts: do_license_msg() msg("Successfully opened transaction file '%s'" % infile) if user_confirm("View transaction data? ",default_yes=False): -<<<<<<< HEAD - view_tx_data(c,inputs_data,tx_hex,timestamp) - -prompt = "Enter bitcoind passphrase: " -======= view_tx_data(c,inputs_data,tx_hex,metadata) prompt = "Enter passphrase for bitcoind wallet: " ->>>>>>> my if 'echo_passphrase' in opts: password = my_raw_input(prompt) else: @@ -119,26 +98,6 @@ except exceptions.WalletPassphraseIncorrect: sys.exit(3) except exceptions.WalletAlreadyUnlocked: msg("WARNING: Wallet already unlocked!") -<<<<<<< HEAD - -# signrawtransaction [{"txid":txid,"vout":n,"scriptPubKey":hex,"redeemScript":hex},...] [,...] [sighashtype="ALL"] -try: - sig_tx = c.signrawtransaction(tx_hex,sig_data) -except: - msg("Failed to sign transaction") - if wallet_enc: c.walletlock() - sys.exit(3) -finally: - if wallet_enc: c.walletlock() - -if not sig_tx['complete']: - msg("signrawtransaction() returned failure") - sys.exit(3) - -prompt = "Save signed transaction?" -if user_confirm(prompt,default_yes=True): - print_signed_tx_to_file(tx_hex,sig_tx['hex'],opts) -======= else: msg("Passphrase OK") @@ -165,4 +124,3 @@ else: prompt = "Save signed transaction?" if user_confirm(prompt,default_yes=True): print_signed_tx_to_file(tx_hex,sig_tx['hex'],metadata,opts) ->>>>>>> my diff --git a/mmgen/config.py b/mmgen/config.py index 608d77cc..040c5c19 100755 --- a/mmgen/config.py +++ b/mmgen/config.py @@ -31,11 +31,7 @@ mnemonic_lens = [i / 32 * 3 for i in seed_lens] from os import getenv debug = True if getenv("MMGEN_DEBUG") else False -<<<<<<< HEAD -mins_per_block = 9 -======= mins_per_block = 8.5 ->>>>>>> my passwd_max_tries = 5 max_randlen,min_randlen = 80,5 usr_randlen = 20 diff --git a/mmgen/license.py b/mmgen/license.py index faad107b..3f251585 100755 --- a/mmgen/license.py +++ b/mmgen/license.py @@ -25,17 +25,10 @@ from mmgen.utils import msg, msg_r, get_char gpl = { 'warning': """ -<<<<<<< HEAD -{} Copyright (C) 2013 by Philemon . This program -comes with ABSOLUTELY NO WARRANTY. This is free software, and you are -welcome to redistribute it under certain conditions. -""".format(proj_name), -======= MMGen Copyright (C) 2013 by Philemon . This program comes with ABSOLUTELY NO WARRANTY. This is free software, and you are welcome to redistribute it under certain conditions. """, ->>>>>>> my 'prompt': """ Press 'c' for conditions, 'w' for warranty info, or ENTER to continue: """, @@ -636,11 +629,7 @@ def do_pager(text): def do_license_msg(): -<<<<<<< HEAD - msg("%s\n" % gpl['warning'].strip()) -======= msg(gpl['warning']) ->>>>>>> my while True: @@ -649,8 +638,4 @@ def do_license_msg(): if reply == 'c': do_pager(gpl['conditions']) elif reply == 'w': do_pager(gpl['warranty']) -<<<<<<< HEAD - else: msg("\n"); break -======= else: msg(""); break ->>>>>>> my diff --git a/mmgen/tx.py b/mmgen/tx.py index 821c7f3a..e964530b 100755 --- a/mmgen/tx.py +++ b/mmgen/tx.py @@ -50,17 +50,10 @@ def connect_to_bitcoind(): return c -<<<<<<< HEAD -def remove_exponent(d): - '''Remove exponent and trailing zeros. - ''' - return d.quantize(Decimal(1)) if d == d.to_integral() else d.normalize() -======= def trim_exponent(d): '''Remove exponent and trailing zeros. ''' return d.quantize(Decimal(1)) if d == d.to_integral() else d.normalize() ->>>>>>> my def check_address(rcpt_address): from mmgen.bitcoin import verify_addr @@ -80,11 +73,7 @@ def check_btc_amt(send_amt): msg("%s: Too many decimal places in amount" % send_amt) sys.exit(3) -<<<<<<< HEAD - return remove_exponent(retval) -======= return trim_exponent(retval) ->>>>>>> my def get_cfg_options(cfg_keys): @@ -120,37 +109,15 @@ def print_tx_to_file(tx,sel_unspent,send_amt,opts): outfile = "%s[%s].tx" % (tx_id,send_amt) if 'outdir' in opts: outfile = "%s/%s" % (opts['outdir'], outfile) -<<<<<<< HEAD - input_data = sel_unspent - data = "%s\n%s\n%s\n%s\n" % ( - make_timestamp(), tx, repr(sig_data), -======= metadata = "%s %s %s" % (tx_id, send_amt, make_timestamp()) data = "%s\n%s\n%s\n%s\n" % ( metadata, tx, repr(sig_data), ->>>>>>> my repr([i.__dict__ for i in sel_unspent]) ) write_to_file(outfile,data,confirm=False) msg("Transaction data saved to file '%s'" % outfile) -<<<<<<< HEAD -def print_signed_tx_to_file(tx,sig_tx,opts): - tx_id = make_chksum_8(unhexlify(tx)) - outfile = "%s.txsig" % tx_id - if 'outdir' in opts: - outfile = "%s/%s" % (opts['outdir'], outfile) - write_to_file(outfile,sig_tx+"\n",confirm=False) - msg("Signed transaction saved to file '%s'" % outfile) - - -def print_sent_tx_to_file(tx): - outfile = "tx.out" - write_to_file(outfile,tx+"\n",confirm=False) - msg("Transaction ID saved to file '%s'" % outfile) - -======= def print_signed_tx_to_file(tx,sig_tx,metadata,opts): tx_id = make_chksum_8(unhexlify(tx)) outfile = "{}[{}].txsig".format(*metadata[:2]) @@ -169,7 +136,6 @@ def print_sent_tx_to_file(tx,metadata,opts): msg("Transaction ID saved to file '%s'" % outfile) ->>>>>>> my def sort_and_view(unspent): def s_amt(a,b): return cmp(a.amount,b.amount) @@ -178,19 +144,12 @@ def sort_and_view(unspent): def s_addr(a,b): return cmp(a.address,b.address) def s_age(a,b): return cmp(b.confirmations,a.confirmations) -<<<<<<< HEAD - fs = "%-4s %-11s %-2s %-34s %13s" - sort,group,reverse = "",False,False - - from copy import deepcopy -======= fs = " %-4s %-11s %-2s %-34s %13s %-s" fs_hdr = " %-4s %-11s %-4s %-35s %-9s %-s" sort,group,reverse = "",False,False from copy import deepcopy msg("") ->>>>>>> my while True: out = deepcopy(unspent) for i in out: i.skip = "" @@ -203,26 +162,11 @@ def sort_and_view(unspent): out[n+1].skip = "t" output = [] -<<<<<<< HEAD - output.append("Sort order: %s%s%s" % ( -======= output.append("UNSPENT OUTPUTS (sort order: %s%s%s)" % ( ->>>>>>> my "reverse " if reverse else "", sort if sort else "None", " (grouped)" if group and (sort == "address" or sort == "txid") else "" )) -<<<<<<< HEAD - output.append(fs % ("Num","TX id","Vout","Address","Amount ")) - - for n,i in enumerate(out): - amt = str(remove_exponent(i.amount)) - fill = 8 - len(amt.split(".")[-1]) if "." in amt else 9 - addr = " |" + "-"*32 if i.skip == "d" else i.address - txid = " |---" if i.skip == "t" else i.txid[:8]+"..." - - output.append(fs % (str(n+1)+")", txid,i.vout,addr,amt+(" "*fill))) -======= output.append(fs_hdr % ("Num","TX id","Vout","Address","Amount", "Age (days)")) @@ -234,7 +178,6 @@ def sort_and_view(unspent): days = int(i.confirmations * mins_per_block / (60*24)) output.append(fs % (str(n+1)+")", txid,i.vout,addr,amt+(" "*fill),days)) ->>>>>>> my while True: reply = get_char("\n".join(output) + @@ -259,82 +202,48 @@ Sort options: [t]xid, [a]mount, a[d]dress, [A]ge, [r]everse, [g]roup return unspent -<<<<<<< HEAD -def view_tx_data(c,inputs_data,tx_hex,timestamp=""): -======= def view_tx_data(c,inputs_data,tx_hex,metadata=[]): ->>>>>>> my td = c.decoderawtransaction(tx_hex) msg("TRANSACTION DATA:\n") -<<<<<<< HEAD - if timestamp: msg("Timestamp: %s\n" % timestamp) -======= if metadata: msg( "Header: [ID: {}] [Amount: {} BTC] [Time: {}]\n".format(*metadata)) ->>>>>>> my msg("Inputs:") total_in = 0 for n,i in enumerate(td['vin']): for j in inputs_data: if j['txid'] == i['txid'] and j['vout'] == i['vout']: -<<<<<<< HEAD - days = j['confirmations'] * mins_per_block / (60*24) - total_in += j['amount'] - msg(""" -%-3s tx,vout: %s,%s -======= days = int(j['confirmations'] * mins_per_block / (60*24)) total_in += j['amount'] msg(" " + """ %-2s tx,vout: %s,%s ->>>>>>> my address: %s amount: %s BTC confirmations: %s (around %s days) """.strip() % (n+1,i['txid'],i['vout'],j['address'], -<<<<<<< HEAD - remove_exponent(j['amount']),j['confirmations'],days)+"\n") - break - - msg("Total input: %s BTC\n" % remove_exponent(total_in)) -======= trim_exponent(j['amount']),j['confirmations'],days)+"\n") break msg("Total input: %s BTC\n" % trim_exponent(total_in)) ->>>>>>> my total_out = 0 msg("Outputs:") for n,i in enumerate(td['vout']): total_out += i['value'] -<<<<<<< HEAD - msg(""" -%-3s address: %s -======= msg(" " + """ %-2s address: %s ->>>>>>> my amount: %s BTC """.strip() % ( n, i['scriptPubKey']['addresses'][0], -<<<<<<< HEAD - remove_exponent(i['value'])) - + "\n") - msg("Total output: %s BTC" % remove_exponent(total_out)) - msg("TX fee: %s BTC\n" % remove_exponent(total_in-total_out)) -======= trim_exponent(i['value'])) + "\n") msg("Total output: %s BTC" % trim_exponent(total_out)) msg("TX fee: %s BTC\n" % trim_exponent(total_in-total_out)) ->>>>>>> my def parse_tx_data(tx_data): @@ -343,11 +252,6 @@ def parse_tx_data(tx_data): msg("'%s': not a transaction file" % infile) sys.exit(2) -<<<<<<< HEAD - try: unhexlify(tx_data[1]) - except: - msg("Transaction data is invalid") -======= err_fmt = "Transaction %s is invalid" if len(tx_data[0].split()) != 3: @@ -357,33 +261,21 @@ def parse_tx_data(tx_data): try: unhexlify(tx_data[1]) except: msg(err_fmt % "hex data") ->>>>>>> my sys.exit(2) try: sig_data = eval(tx_data[2]) except: -<<<<<<< HEAD - msg("Signature data is invalid") -======= msg(err_fmt % "signature data") ->>>>>>> my sys.exit(2) try: inputs_data = eval(tx_data[3]) except: -<<<<<<< HEAD - msg("Inputs data is invalid") - sys.exit(2) - - return tx_data[0],tx_data[1],sig_data,inputs_data -======= msg(err_fmt % "inputs data") sys.exit(2) return tx_data[0].split(),tx_data[1],sig_data,inputs_data ->>>>>>> my def select_outputs(unspent,prompt): diff --git a/mmgen/utils.py b/mmgen/utils.py index 581cda76..1fa78681 100755 --- a/mmgen/utils.py +++ b/mmgen/utils.py @@ -192,11 +192,6 @@ future, you must continue using these same parameters def confirm_or_exit(message, question, expect="YES"): -<<<<<<< HEAD - m = message.strip() - if m: msg(m) -======= ->>>>>>> my msg("") m = message.strip() @@ -209,13 +204,8 @@ def confirm_or_exit(message, question, expect="YES"): else: prompt = "Are you sure you want to %s?\n%s" % (question,conf_msg) -<<<<<<< HEAD - if my_raw_input(prompt).strip() != "YES": - msg("Program aborted by user") -======= if my_raw_input(prompt).strip() != expect: msg("Exiting at user request") ->>>>>>> my sys.exit(2) msg("") @@ -330,18 +320,6 @@ just hit ENTER twice. return ret for i in range(passwd_max_tries): -<<<<<<< HEAD - if 'echo_passphrase' in opts: - return my_raw_input("Enter %s: " % what) - else: - ret = my_getpass("Enter %s: " % what) - if ret == my_getpass("Repeat %s: " % what): - s = " (empty)" if not len(ret) else "" - msg("%ss match%s" % (what.capitalize(),s)) - return ret - else: - msg("%ss do not match" % what.capitalize()) -======= ret = " ".join(_get_words_from_user(opts,"Enter %s: " % what)) ret2 = " ".join(_get_words_from_user(opts,"Repeat %s: " % what)) if debug: print "Passphrases: [%s] [%s]" % (ret,ret2) @@ -351,7 +329,6 @@ just hit ENTER twice. return ret else: msg("%ss do not match" % what.capitalize()) ->>>>>>> my msg("User failed to duplicate passphrase in %s attempts" % passwd_max_tries) sys.exit(2) @@ -538,11 +515,7 @@ def write_wallet_to_file(seed, passwd, key_id, salt, enc_seed, opts): esf = b58encode_pad(enc_seed) metadata = seed_id.lower(),key_id.lower(),\ -<<<<<<< HEAD - seed_len,pw_status,make_timestamp() -======= seed_len,pw_status,make_timestamp() ->>>>>>> my lines = ( label, @@ -678,11 +651,7 @@ def _get_words_from_user(opts, prompt): def _get_words_from_file(infile,what): msg("Getting %s from file '%s'" % (what,infile)) f = open_file_or_exit(infile, 'r') -<<<<<<< HEAD - lines = f.readlines(); f.close() -======= data = f.read(); f.close() ->>>>>>> my # split() also strips return data.split() @@ -694,15 +663,6 @@ def get_lines_from_file(infile,what): return [i.strip("\n") for i in lines] - -def get_lines_from_file(infile,what): - msg("Getting %s from file '%s'" % (what,infile)) - f = open_file_or_exit(infile,'r') - data = f.read(); f.close() - # split() doesn't strip final newline - return data.strip().split("\n") - - def get_words(infile,what,prompt,opts): if infile: words = _get_words_from_file(infile,what)