Пример #1
0
def cli_receive(filename):
    wif_privkey = raw_input("Enter private key in WIF compressed format: ")
    try:
        privkey = btc.from_wif_privkey(wif_privkey, vbyte=get_p2pk_vbyte())
    except:
        print("Could not parse WIF privkey, quitting.")
        return
    amount = raw_input("Enter amount of utxo being spent, in satoshis: ")
    valid_coinjoins = scan_for_coinjoins(privkey, int(amount), filename)
    if not valid_coinjoins:
        print("Found no valid coinjoins")
        return
    for vc in valid_coinjoins:
        addr, priv, tx = vc
        print("Found signable coinjoin with destination address: ", addr)
        #TODO find a more sensible file naming
        fn = btc.txhash(tx) + ".txt"
        with open(fn, "wb") as f:
            f.write("SNICKER output file for receiver\n"
                    "================================\n")
            f.write("The serialized transaction in hex:\n")
            f.write(tx + "\n")
            f.write("YOUR DESTINATION: " + addr + "\n")
            f.write("PRIVATE KEY FOR THIS DESTINATION ADDRESS:\n")
            f.write(
                btc.wif_compressed_privkey(priv, vbyte=get_p2pk_vbyte()) +
                "\n")
            f.write("The decoded transaction:\n")
            f.write(pformat(btc.deserialize(tx)) + "\n")
        print("The partially signed transaction and the private key for your "
              "output are stored in the file: " + fn)
        print(
            "Pass the transaction hex to `signrawtransaction` in Bitcoin Core "
            "or similar if you wish to broadcast the transaction.")
def validate_utxo_data(utxo_datas, retrieve=False, segwit=False):
    """For each txid: N, privkey, first
    convert the privkey and convert to address,
    then use the blockchain instance to look up
    the utxo and check that its address field matches.
    If retrieve is True, return the set of utxos and their values.
    """
    results = []
    for u, priv in utxo_datas:
        print('validating this utxo: ' + str(u))
        hexpriv = btc.from_wif_privkey(priv, vbyte=get_p2pk_vbyte())
        if segwit:
            addr = btc.pubkey_to_p2sh_p2wpkh_address(
                btc.privkey_to_pubkey(hexpriv), get_p2sh_vbyte())
        else:
            addr = btc.privkey_to_address(hexpriv, magicbyte=get_p2pk_vbyte())
        print('claimed address: ' + addr)
        res = jm_single().bc_interface.query_utxo_set([u])
        print('blockchain shows this data: ' + str(res))
        if len(res) != 1 or None in res:
            print("utxo not found on blockchain: " + str(u))
            return False
        if res[0]['address'] != addr:
            print("privkey corresponds to the wrong address for utxo: " +
                  str(u))
            print("blockchain returned address: {}".format(res[0]['address']))
            print("your privkey gave this address: " + addr)
            return False
        if retrieve:
            results.append((u, res[0]['value']))
    print('all utxos validated OK')
    if retrieve:
        return results
    return True
Пример #3
0
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()
Пример #4
0
def test_verify_tx_input(setup_tx_creation, signall, mktxlist):
    priv = "aa" * 32 + "01"
    addr = bitcoin.privkey_to_address(priv, magicbyte=get_p2pk_vbyte())
    wallet = make_wallets(1, [[2, 0, 0, 0, 0]], 1)[0]['wallet']
    sync_wallet(wallet)
    insfull = wallet.select_utxos(0, 110000000)
    print(insfull)
    if not mktxlist:
        outs = [{"address": addr, "value": 1000000}]
        ins = insfull.keys()
        tx = bitcoin.mktx(ins, outs)
    else:
        out1 = addr + ":1000000"
        ins0, ins1 = insfull.keys()
        print("INS0 is: " + str(ins0))
        print("INS1 is: " + str(ins1))
        tx = bitcoin.mktx(ins0, ins1, out1)
    desertx = bitcoin.deserialize(tx)
    print(desertx)
    if signall:
        privdict = {}
        for index, ins in enumerate(desertx['ins']):
            utxo = ins['outpoint']['hash'] + ':' + str(
                ins['outpoint']['index'])
            ad = insfull[utxo]['address']
            priv = wallet.get_key_from_addr(ad)
            privdict[utxo] = priv
        tx = bitcoin.signall(tx, privdict)
    else:
        for index, ins in enumerate(desertx['ins']):
            utxo = ins['outpoint']['hash'] + ':' + str(
                ins['outpoint']['index'])
            ad = insfull[utxo]['address']
            priv = wallet.get_key_from_addr(ad)
            if index % 2:
                tx = binascii.unhexlify(tx)
            tx = bitcoin.sign(tx, index, priv)
            if index % 2:
                tx = binascii.hexlify(tx)
    desertx2 = bitcoin.deserialize(tx)
    print(desertx2)
    sig, pub = bitcoin.deserialize_script(desertx2['ins'][0]['script'])
    print(sig, pub)
    pubscript = bitcoin.address_to_script(
        bitcoin.pubkey_to_address(pub, magicbyte=get_p2pk_vbyte()))
    sig = binascii.unhexlify(sig)
    pub = binascii.unhexlify(pub)
    sig_good = bitcoin.verify_tx_input(tx, 0, pubscript, sig, pub)
    assert sig_good
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
Пример #6
0
def test_mktx(setup_tx_creation):
    """Testing exceptional conditions; not guaranteed
    to create valid tx objects"""
    #outpoint structure must be {"outpoint":{"hash":hash, "index": num}}
    ins = [{
        'outpoint': {
            "hash": x * 32,
            "index": 0
        },
        "script": "",
        "sequence": 4294967295
    } for x in ["a", "b", "c"]]
    pub = vpubs[0]
    addr = bitcoin.pubkey_to_address(pub, magicbyte=get_p2pk_vbyte())
    script = bitcoin.address_to_script(addr)
    outs = [
        script + ":1000", addr + ":2000", {
            "script": script,
            "value": 3000
        }
    ]
    tx = bitcoin.mktx(ins, outs)
    print(tx)
    #rewrite with invalid output
    outs.append({"foo": "bar"})
    with pytest.raises(Exception) as e_info:
        tx = bitcoin.mktx(ins, outs)
def get_utxo_info(upriv):
    """Verify that the input string parses correctly as (utxo, priv)
    and return that.
    """
    try:
        u, priv = upriv.split(',')
        u = u.strip()
        priv = priv.strip()
        txid, n = u.split(':')
        assert len(txid) == 64
        assert len(n) in range(1, 4)
        n = int(n)
        assert n in range(256)
    except:
        #not sending data to stdout in case privkey info
        jmprint("Failed to parse utxo information for utxo", "error")
        raise
    try:
        hexpriv = btc.from_wif_privkey(priv, vbyte=get_p2pk_vbyte())
    except:
        jmprint(
            "failed to parse privkey, make sure it's WIF compressed format.",
            "error")
        raise
    return u, priv
Пример #8
0
def sign(utxo, priv, destaddrs, segwit=True):
    """Sign a tx sending the amount amt, from utxo utxo,
    equally to each of addresses in list destaddrs,
    after fees; the purpose is to create a large
    number of utxos. If segwit=True the (single) utxo is assumed to
    be of type segwit p2sh/p2wpkh.
    """
    results = validate_utxo_data([(utxo, priv)], retrieve=True, segwit=segwit)
    if not results:
        return False
    assert results[0][0] == utxo
    amt = results[0][1]
    ins = [utxo]
    txtype = 'p2sh-p2wpkh' if segwit else 'p2pkh'
    estfee = estimate_tx_fee(1, len(destaddrs), txtype=txtype)
    outs = []
    share = int((amt - estfee) / len(destaddrs))
    fee = amt - share * len(destaddrs)
    assert fee >= estfee
    log.info("Using fee: " + str(fee))
    for i, addr in enumerate(destaddrs):
        outs.append({'address': addr, 'value': share})
    unsigned_tx = btc.mktx(ins, outs)
    amtforsign = amt if segwit else None
    return btc.sign(unsigned_tx,
                    0,
                    btc.from_wif_privkey(priv, vbyte=get_p2pk_vbyte()),
                    amount=amtforsign)
Пример #9
0
def wallet_importprivkey(wallet, mixdepth):
    print('WARNING: This imported key will not be recoverable with your 12 ' +
          'word mnemonic phrase. Make sure you have backups.')
    print('WARNING: Handling of raw ECDSA bitcoin private keys can lead to '
          'non-intuitive behaviour and loss of funds.\n  Recommended instead '
          'is to use the \'sweep\' feature of sendpayment.py ')
    privkeys = raw_input('Enter private key(s) to import: ')
    privkeys = privkeys.split(',') if ',' in privkeys else privkeys.split()
    # TODO read also one key for each line
    for privkey in privkeys:
        # TODO is there any point in only accepting wif format? check what
        # other wallets do
        privkey_bin = btc.from_wif_privkey(privkey,
                                        vbyte=get_p2pk_vbyte()).decode('hex')[:-1]
        encrypted_privkey = encryptData(wallet.password_key, privkey_bin)
        if 'imported_keys' not in wallet.walletdata:
            wallet.walletdata['imported_keys'] = []
        wallet.walletdata['imported_keys'].append(
            {'encrypted_privkey': encrypted_privkey.encode('hex'),
             'mixdepth': mixdepth})
    if wallet.walletdata['imported_keys']:
        fd = open(wallet.path, 'w')
        fd.write(json.dumps(wallet.walletdata))
        fd.close()
        print('Private key(s) successfully imported')
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_key_from_addr(self, addr):
     if self.ewallet.has_password() and self.password is None:
         raise Exception("Cannot extract private key without password")
     key = self.ewallet.get_private_key(addr, self.password)
     #Convert from wif compressed to hex compressed
     #TODO check if compressed
     hex_key = btc.from_wif_privkey(key[0], vbyte=get_p2pk_vbyte())
     return hex_key
Пример #12
0
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"
Пример #13
0
 def generate_single_podle_sig(u, priv, i):
     """Make a podle entry for key priv at index i, using a dummy utxo value.
     This calls the underlying 'raw' code based on the class PoDLE, not the
     library 'generate_podle' which intelligently searches and updates commitments.
     """
     #Convert priv to hex
     hexpriv = btc.from_wif_privkey(priv, vbyte=get_p2pk_vbyte())
     podle = PoDLE(u, hexpriv)
     r = podle.generate_podle(i)
     return (r['P'], r['P2'], r['sig'], r['e'], r['commit'])
Пример #14
0
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"
Пример #15
0
def test_all_same_priv(setup_tx_creation):
    #recipient
    priv = "aa" * 32 + "01"
    addr = bitcoin.privkey_to_address(priv, magicbyte=get_p2pk_vbyte())
    wallet = make_wallets(1, [[1, 0, 0, 0, 0]], 1)[0]['wallet']
    #make another utxo on the same address
    addrinwallet = wallet.get_addr(0, 0, 0)
    jm_single().bc_interface.grab_coins(addrinwallet, 1)
    sync_wallet(wallet)
    insfull = wallet.select_utxos(0, 110000000)
    outs = [{"address": addr, "value": 1000000}]
    ins = insfull.keys()
    tx = bitcoin.mktx(ins, outs)
    tx = bitcoin.signall(tx, wallet.get_key_from_addr(addrinwallet))
Пример #16
0
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
Пример #17
0
def create_recipient_address(bob_pubkey, tweak=None, segwit=False):
    """Create a p2pkh receiving address
    from an existing pubkey, tweaked by a random 32 byte scalar.
    Returns the tweak, the new pubkey point and the new address.
    The recipient can set the tweak parameter.
    """
    if not tweak:
        tweak = binascii.hexlify(os.urandom(32))
    tweak_point = btc.privkey_to_pubkey(tweak + "01")
    destination_point = btc.add_pubkeys([tweak_point, bob_pubkey], True)
    if segwit:
        destination_address = btc.pubkey_to_p2sh_p2wpkh_address(
            destination_point, magicbyte=get_p2sh_vbyte())
    else:
        destination_address = btc.pubkey_to_address(destination_point,
                                                    magicbyte=get_p2pk_vbyte())
    return (tweak, destination_point, destination_address)
Пример #18
0
def test_blockr_sync(setup_blockr, net, seed, gaplimit, showprivkey, method):
    jm_single().config.set("BLOCKCHAIN", "network", net)
    wallet = Wallet(seed, None, max_mix_depth=5)
    sync_wallet(wallet)

    #copy pasted from wallet-tool; some boiled down form of
    #this should really be in wallet.py in the joinmarket module.
    def cus_print(s):
        print s

    total_balance = 0
    for m in range(wallet.max_mix_depth):
        cus_print('mixing depth %d m/0/%d/' % (m, m))
        balance_depth = 0
        for forchange in [0, 1]:
            cus_print(' ' + ('external' if forchange == 0 else 'internal') +
                      ' addresses m/0/%d/%d/' % (m, forchange))

            for k in range(wallet.index[m][forchange] + gaplimit):
                addr = wallet.get_addr(m, forchange, k)
                balance = 0.0
                for addrvalue in wallet.unspent.values():
                    if addr == addrvalue['address']:
                        balance += addrvalue['value']
                balance_depth += balance
                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 (method == 'displayall' or balance > 0
                        or (used == ' new' and forchange == 0)):
                    cus_print(
                        '  m/0/%d/%d/%03d %-35s%s %.8f btc %s' %
                        (m, forchange, k, addr, used, balance / 1e8, privkey))
        total_balance += balance_depth
        print('for mixdepth=%d balance=%.8fbtc' % (m, balance_depth / 1e8))
    assert total_balance == 96085297
Пример #19
0
def sign(utxo, priv, destaddrs):
    """Sign a tx sending the amount amt, from utxo utxo,
    equally to each of addresses in list destaddrs,
    after fees; the purpose is to create a large
    number of utxos.
    """
    results = validate_utxo_data([(utxo, priv)], retrieve=True)
    if not results:
        return False
    assert results[0][0] == utxo
    amt = results[0][1]
    ins = [utxo]
    estfee = estimate_tx_fee(1, len(destaddrs))
    outs = []
    share = int((amt - estfee) / len(destaddrs))
    fee = amt - share*len(destaddrs)
    assert fee >= estfee
    log.info("Using fee: " + str(fee))
    for i, addr in enumerate(destaddrs):
        outs.append({'address': addr, 'value': share})
    unsigned_tx = btc.mktx(ins, outs)
    return btc.sign(unsigned_tx, 0, btc.from_wif_privkey(
        priv, vbyte=get_p2pk_vbyte()))
Пример #20
0
        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)
Пример #21
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
    for m in range(wallet.max_mix_depth):
Пример #22
0
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)
Пример #23
0
def address_p2pkh_generator():
    return get_address_generator(b'\x76\xa9\x14', b'\x88\xac',
                                 get_p2pk_vbyte())