def test_imported_privkey(setup_wallets): for n in ["mainnet", "testnet"]: privkey = "7d998b45c219a1e38e99e7cbd312ef67f77a455a9b50c730c27f02c6f730dfb401" jm_single().config.set("BLOCKCHAIN", "network", n) password = "******" password_key = bitcoin.bin_dbl_sha256(password) wifprivkey = bitcoin.wif_compressed_privkey(privkey, get_p2pk_vbyte()) #mainnet is "L1RrrnXkcKut5DEMwtDthjwRcTTwED36thyL1DebVrKuwvohjMNi" #to verify use from_wif_privkey and privkey_to_address if n == "mainnet": iaddr = "1LDsjB43N2NAQ1Vbc2xyHca4iBBciN8iwC" else: iaddr = "mzjq2E92B3oRB7yDKbwM7XnPaAnKfRERw2" privkey_bin = bitcoin.from_wif_privkey( wifprivkey, vbyte=get_p2pk_vbyte()).decode('hex')[:-1] encrypted_privkey = encryptData(password_key, privkey_bin) encrypted_privkey_bad = encryptData(password_key, privkey_bin[:6]) walletdir = "wallets" testwalletname = "test" + n pathtowallet = os.path.join(walletdir, testwalletname) seed = bitcoin.sha256("\xaa" * 64)[:32] encrypted_seed = encryptData(password_key, seed.decode('hex')) timestamp = datetime.datetime.now().strftime("%Y/%m/%d %H:%M:%S") for ep in [encrypted_privkey, encrypted_privkey_bad]: walletfilejson = { 'creator': 'joinmarket project', 'creation_time': timestamp, 'encrypted_seed': encrypted_seed.encode('hex'), 'network': n, 'index_cache': [[0, 0]] * 5, 'imported_keys': [{ 'encrypted_privkey': ep.encode('hex'), 'mixdepth': 0 }] } walletfile = json.dumps(walletfilejson) if not os.path.exists(walletdir): os.makedirs(walletdir) with open(pathtowallet, "wb") as f: f.write(walletfile) if ep == encrypted_privkey_bad: with pytest.raises(Exception) as e_info: Wallet(testwalletname, password, 5, 6, False, False) continue newwallet = Wallet(testwalletname, password, 5, 6, False, False) assert newwallet.seed == seed #test accessing the key from the addr assert newwallet.get_key_from_addr( iaddr) == bitcoin.from_wif_privkey(wifprivkey, vbyte=get_p2pk_vbyte()) if n == "testnet": jm_single().bc_interface.sync_wallet(newwallet) load_program_config()
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) break 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 cs_single().config.options('POLICY'): cs_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) total_balance = 0