def wallet_showutxos(wallet, showprivkey): unsp = {} max_tries = jm_single().config.getint("POLICY", "taker_utxo_retries") for u, av in wallet.unspent.iteritems(): key = wallet.get_key_from_addr(av['address']) tries = podle.get_podle_tries(u, key, max_tries) tries_remaining = max(0, max_tries - tries) unsp[u] = { 'address': av['address'], 'value': av['value'], 'tries': tries, 'tries_remaining': tries_remaining, 'external': False } if showprivkey: wifkey = btc.wif_compressed_privkey(key, vbyte=get_p2pk_vbyte()) unsp[u]['privkey'] = wifkey used_commitments, external_commitments = podle.get_podle_commitments() for u, ec in external_commitments.iteritems(): tries = podle.get_podle_tries(utxo=u, max_tries=max_tries, external=True) tries_remaining = max(0, max_tries - tries) unsp[u] = { 'tries': tries, 'tries_remaining': tries_remaining, 'external': True } return json.dumps(unsp, indent=4)
def get_imported_privkey_branch(wallet, m, showprivkey): if m in wallet.imported_privkeys: entries = [] for i, privkey in enumerate(wallet.imported_privkeys[m]): pub = btc.privkey_to_pubkey(privkey) addr = btc.pubkey_to_p2sh_p2wpkh_address( pub, magicbyte=get_p2sh_vbyte()) balance = 0.0 for addrvalue in wallet.unspent.values(): if addr == addrvalue['address']: balance += addrvalue['value'] used = ('used' if balance > 0.0 else 'empty') if showprivkey: wip_privkey = btc.wif_compressed_privkey( privkey, get_p2pk_vbyte()) else: wip_privkey = '' entries.append( WalletViewEntry("m/0", m, -1, i, addr, [balance, balance], used=used, priv=wip_privkey)) return WalletViewBranch("m/0", m, -1, branchentries=entries) return None
def wallet_dumpprivkey(wallet, hdpath): pathlist = bip32pathparse(hdpath) print('got pathlist: ' + str(pathlist)) if pathlist and len(pathlist) == 5: cointype, purpose, m, forchange, k = pathlist key = wallet.get_key(m, forchange, k) wifkey = btc.wif_compressed_privkey(key, vbyte=get_p2pk_vbyte()) return wifkey else: return hdpath + " is not a valid hd wallet path"
def wallet_dumpprivkey(wallet, hdpath): pathlist = bip32pathparse(hdpath) print('got pathlist: ' + str(pathlist)) if pathlist and len(pathlist) in [5, 4]: #note here we assume the path conforms to Wallet or SegwitWallet(BIP49) standard m, forchange, k = pathlist[-3:] key = wallet.get_key(m, forchange, k) wifkey = btc.wif_compressed_privkey(key, vbyte=get_p2pk_vbyte()) return wifkey else: return hdpath + " is not a valid hd wallet path"
def wallet_display(wallet, gaplimit, showprivkey, displayall=False, serialized=True, summarized=False): """build the walletview object, then return its serialization directly if serialized, else return the WalletView object. """ acctlist = [] rootpath = wallet.get_root_path() for m in range(wallet.max_mix_depth): branchlist = [] for forchange in [0, 1]: entrylist = [] if forchange == 0: xpub_key = btc.bip32_privtopub(wallet.keys[m][forchange]) else: xpub_key = "" for k in range(wallet.index[m][forchange] + gaplimit): addr = wallet.get_addr(m, forchange, k) balance = 0 for addrvalue in wallet.unspent.values(): if addr == addrvalue['address']: balance += addrvalue['value'] used = 'used' if k < wallet.index[m][forchange] else 'new' if showprivkey: privkey = btc.wif_compressed_privkey( wallet.get_key(m, forchange, k), get_p2pk_vbyte()) else: privkey = '' if (displayall or balance > 0 or (used == 'new' and forchange == 0)): entrylist.append(WalletViewEntry(rootpath, m, forchange, k, addr, [balance, balance], priv=privkey, used=used)) branchlist.append(WalletViewBranch(rootpath, m, forchange, entrylist, xpub=xpub_key)) ipb = get_imported_privkey_branch(wallet, m, showprivkey) if ipb: branchlist.append(ipb) #get the xpub key of the whole account xpub_account = btc.bip32_privtopub( wallet.get_mixing_depth_keys(wallet.get_master_key())[m]) acctlist.append(WalletViewAccount(rootpath, m, branchlist, xpub=xpub_account)) walletview = WalletView(rootpath, acctlist) if serialized: return walletview.serialize(summarize=summarized) else: return walletview
def main(): parser = OptionParser( usage='usage: %prog [options] [txid:n]', description= "Adds one or more utxos to the list that can be used to make " "commitments for anti-snooping. Note that this utxo, and its " "PUBkey, will be revealed to makers, so consider the privacy " "implication. " "It may be useful to those who are having trouble making " "coinjoins due to several unsuccessful attempts (especially " "if your joinmarket wallet is new). " "'Utxo' means unspent transaction output, it must not " "already be spent. " "The options -w, -r and -R offer ways to load these utxos " "from a file or wallet. " "If you enter a single utxo without these options, you will be " "prompted to enter the private key here - it must be in " "WIF compressed format. " "BE CAREFUL about handling private keys! " "Don't do this in insecure environments. " "Also note this ONLY works for standard (p2pkh) utxos.") parser.add_option( '-r', '--read-from-file', action='store', type='str', dest='in_file', help= 'name of plain text csv file containing utxos, one per line, format: ' 'txid:N, WIF-compressed-privkey') parser.add_option( '-R', '--read-from-json', action='store', type='str', dest='in_json', help= 'name of json formatted file containing utxos with private keys, as ' 'output from "python wallet-tool.py -u -p walletname showutxos"') parser.add_option( '-w', '--load-wallet', action='store', type='str', dest='loadwallet', help='name of wallet from which to load utxos and use as commitments.') parser.add_option( '-g', '--gap-limit', action='store', type='int', dest='gaplimit', default=6, help= 'Only to be used with -w; gap limit for Joinmarket wallet, default 6.') parser.add_option( '-M', '--max-mixdepth', action='store', type='int', dest='maxmixdepth', default=5, help= 'Only to be used with -w; number of mixdepths for wallet, default 5.') parser.add_option( '-d', '--delete-external', action='store_true', dest='delete_ext', help='deletes the current list of external commitment utxos', default=False) parser.add_option( '-v', '--validate-utxos', action='store_true', dest='validate', help='validate the utxos and pubkeys provided against the blockchain', default=False) parser.add_option( '-o', '--validate-only', action='store_true', dest='vonly', help='only validate the provided utxos (file or command line), not add', default=False) parser.add_option('--fast', action='store_true', dest='fastsync', default=False, help=('choose to do fast wallet sync, only for Core and ' 'only for previously synced wallet')) (options, args) = parser.parse_args() load_program_config() #TODO; sort out "commit file location" global so this script can #run without this hardcoding: utxo_data = [] if options.delete_ext: other = options.in_file or options.in_json or options.loadwallet if len(args) > 0 or other: if raw_input( "You have chosen to delete commitments, other arguments " "will be ignored; continue? (y/n)") != 'y': print "Quitting" sys.exit(0) c, e = get_podle_commitments() print pformat(e) if raw_input( "You will remove the above commitments; are you sure? (y/n): " ) != 'y': print "Quitting" sys.exit(0) update_commitments(external_to_remove=e) print "Commitments deleted." sys.exit(0) #Three options (-w, -r, -R) for loading utxo and privkey pairs from a wallet, #csv file or json file. if options.loadwallet: while True: pwd = get_password("Enter wallet decryption passphrase: ") try: wallet = Wallet(options.loadwallet, pwd, options.maxmixdepth, options.gaplimit) except WalletError: print("Wrong password, try again.") continue except Exception as e: print("Failed to load wallet, error message: " + repr(e)) sys.exit(0) break sync_wallet(wallet, fast=options.fastsync) unsp = {} for u, av in wallet.unspent.iteritems(): addr = av['address'] key = wallet.get_key_from_addr(addr) wifkey = btc.wif_compressed_privkey(key, vbyte=get_p2pk_vbyte()) unsp[u] = { 'address': av['address'], 'value': av['value'], 'privkey': wifkey } for u, pva in unsp.iteritems(): utxo_data.append((u, pva['privkey'])) elif options.in_file: with open(options.in_file, "rb") as f: utxo_info = f.readlines() for ul in utxo_info: ul = ul.rstrip() if ul: u, priv = get_utxo_info(ul) if not u: quit(parser, "Failed to parse utxo info: " + str(ul)) utxo_data.append((u, priv)) elif options.in_json: if not os.path.isfile(options.in_json): print "File: " + options.in_json + " not found." sys.exit(0) with open(options.in_json, "rb") as f: try: utxo_json = json.loads(f.read()) except: print "Failed to read json from " + options.in_json sys.exit(0) for u, pva in utxo_json.iteritems(): utxo_data.append((u, pva['privkey'])) elif len(args) == 1: u = args[0] priv = raw_input('input private key for ' + u + ', in WIF compressed format : ') u, priv = get_utxo_info(','.join([u, priv])) if not u: quit(parser, "Failed to parse utxo info: " + u) utxo_data.append((u, priv)) else: quit(parser, 'Invalid syntax') if options.validate or options.vonly: if not validate_utxo_data(utxo_data): quit(parser, "Utxos did not validate, quitting") if options.vonly: sys.exit(0) #We are adding utxos to the external list assert len(utxo_data) add_ext_commitments(utxo_data)
sys.exit(0) if method not in noscan_methods: # if nothing was configured, we override bitcoind's options so that # unconfirmed balance is included in the wallet display by default if 'listunspent_args' not in jm_single().config.options('POLICY'): jm_single().config.set('POLICY', 'listunspent_args', '[0]') sync_wallet(wallet, fast=options.fastsync) if method == 'showutxos': unsp = {} if options.showprivkey: for u, av in wallet.unspent.iteritems(): addr = av['address'] key = wallet.get_key_from_addr(addr) wifkey = btc.wif_compressed_privkey(key, vbyte=get_p2pk_vbyte()) unsp[u] = { 'address': av['address'], 'value': av['value'], 'privkey': wifkey } else: unsp = wallet.unspent print(json.dumps(unsp, indent=4)) sys.exit(0) if method == 'display' or method == 'displayall' or method == 'summary': def cus_print(s): if method != 'summary': print(s)