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 wallet_showutxos(wallet, showprivkey):
    unsp = {}
    max_tries = jm_single().config.getint("POLICY", "taker_utxo_retries")
    utxos = wallet.get_utxos_by_mixdepth()
    for md in utxos:
        for u, av in utxos[md].items():
            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:
                unsp[u]['privkey'] = wallet.get_wif_path(av['path'])

    used_commitments, external_commitments = podle.get_podle_commitments()
    for u, ec in iteritems(external_commitments):
        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)
Ejemplo n.º 3
0
    def make_commitment(self):
        """The Taker default commitment function, which uses PoDLE.
        Alternative commitment types should use a different commit type byte.
        This will allow future upgrades to provide different style commitments
        by subclassing Taker and changing the commit_type_byte; existing makers
        will simply not accept this new type of commitment.
        In case of success, return the commitment and its opening.
        In case of failure returns (None, None) and constructs a detailed
        log for the user to read and discern the reason.
        """
        def filter_by_coin_age_amt(utxos, age, amt):
            results = jm_single().bc_interface.query_utxo_set(utxos,
                                                              includeconf=True)
            newresults = []
            too_old = []
            too_small = []
            for i, r in enumerate(results):
                #results return "None" if txo is spent; drop this
                if not r:
                    continue
                valid_age = r['confirms'] >= age
                valid_amt = r['value'] >= amt
                if not valid_age:
                    too_old.append(utxos[i])
                if not valid_amt:
                    too_small.append(utxos[i])
                if valid_age and valid_amt:
                    newresults.append(utxos[i])
            return newresults, too_old, too_small

        def priv_utxo_pairs_from_utxos(utxos, age, amt):
            #returns pairs list of (priv, utxo) for each valid utxo;
            #also returns lists "too_old" and "too_small" for any
            #utxos that did not satisfy the criteria for debugging.
            priv_utxo_pairs = []
            new_utxos, too_old, too_small = filter_by_coin_age_amt(
                list(utxos.keys()), age, amt)
            new_utxos_dict = {k: v for k, v in utxos.items() if k in new_utxos}
            for k, v in new_utxos_dict.items():
                addr = self.wallet_service.script_to_addr(v["script"])
                priv = self.wallet_service.get_key_from_addr(addr)
                if priv:  #can be null from create-unsigned
                    priv_utxo_pairs.append((priv, k))
            return priv_utxo_pairs, too_old, too_small

        commit_type_byte = "P"
        tries = jm_single().config.getint("POLICY", "taker_utxo_retries")
        age = jm_single().config.getint("POLICY", "taker_utxo_age")
        #Minor rounding errors don't matter here
        amt = int(
            self.cjamount *
            jm_single().config.getint("POLICY", "taker_utxo_amtpercent") /
            100.0)
        priv_utxo_pairs, to, ts = priv_utxo_pairs_from_utxos(
            self.input_utxos, age, amt)

        #For podle data format see: podle.PoDLE.reveal()
        #In first round try, don't use external commitments
        podle_data = generate_podle(priv_utxo_pairs, tries)
        if not podle_data:
            #Pre-filter the set of external commitments that work for this
            #transaction according to its size and age.
            dummy, extdict = get_podle_commitments()
            if len(extdict) > 0:
                ext_valid, ext_to, ext_ts = filter_by_coin_age_amt(
                    list(extdict.keys()), age, amt)
            else:
                ext_valid = None
            #We defer to a second round to try *all* utxos in spending mixdepth;
            #this is because it's much cleaner to use the utxos involved
            #in the transaction, about to be consumed, rather than use
            #random utxos that will persist after. At this step we also
            #allow use of external utxos in the json file.
            mixdepth_utxos = self.wallet_service.get_utxos_by_mixdepth()[
                self.mixdepth]
            if len(self.input_utxos) == len(mixdepth_utxos):
                # Already tried the whole mixdepth
                podle_data = generate_podle([], tries, ext_valid)
            else:
                priv_utxo_pairs, to, ts = priv_utxo_pairs_from_utxos(
                    mixdepth_utxos, age, amt)
                podle_data = generate_podle(priv_utxo_pairs, tries, ext_valid)
        if podle_data:
            jlog.debug("Generated PoDLE: " + repr(podle_data))
            return (commit_type_byte + bintohex(podle_data.commitment),
                    podle_data.serialize_revelation(), "Commitment sourced OK")
        else:
            errmsgheader, errmsg = generate_podle_error_string(
                priv_utxo_pairs, to, ts, self.wallet_service, self.cjamount,
                jm_single().config.get("POLICY", "taker_utxo_age"),
                jm_single().config.get("POLICY", "taker_utxo_amtpercent"))

            with open("commitments_debug.txt", "wb") as f:
                errmsgfileheader = (b"THIS IS A TEMPORARY FILE FOR DEBUGGING; "
                                    b"IT CAN BE SAFELY DELETED ANY TIME.\n")
                errmsgfileheader += (b"***\n")
                f.write(errmsgfileheader + errmsg.encode('utf-8'))

            return (None, (priv_utxo_pairs, to, ts), errmsgheader + errmsg)