Exemplo n.º 1
0
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:
        jmprint('validating this utxo: ' + str(u), "info")
        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())
        jmprint('claimed address: ' + addr, "info")
        res = jm_single().bc_interface.query_utxo_set([u])
        if len(res) != 1 or None in res:
            jmprint("utxo not found on blockchain: " + str(u), "error")
            return False
        if res[0]['address'] != addr:
            jmprint("privkey corresponds to the wrong address for utxo: " + str(u), "error")
            jmprint("blockchain returned address: {}".format(res[0]['address']), "error")
            jmprint("your privkey gave this address: " + addr, "error")
            return False
        if retrieve:
            results.append((u, res[0]['value']))
    jmprint('all utxos validated OK', "success")
    if retrieve:
        return results
    return True
Exemplo n.º 2
0
 def build_outs_from_template(self):
     """Build the outputs for this transaction based on
     the template, which must exist due to the constructor.
     Unlike build_ins, this has no dependencies but
     constructs appropriate output scripts based on the
     text flag "p2sh-p2wpkh" or "NN" in the template.
     It is necessary to fill out the keys template
     self.keys, before calling this.
     """
     for i, t in enumerate(self.template.outs):
         if t.spk_type == "p2sh-p2wpkh":
             self.outs.append({
                 "address":
                 btc.pubkey_to_p2sh_p2wpkh_address(
                     self.keys["outs"][i][t.counterparty],
                     get_p2sh_vbyte()),
                 "value":
                 t.amount
             })
         elif t.spk_type == "NN":
             #check if all the necessary keys are available
             if not all([
                     j in self.keys["outs"][i]
                     for j in range(self.n_counterparties)
             ]):
                 raise Exception("Incomplete key data to construct outputs")
             self.outs.append({
                 "address":
                 btc.pubkeys_to_p2wsh_address(self.keys["outs"][i].values(),
                                              vbyte=100),
                 "value":
                 t.amount
             })
def test_spend_p2sh_p2wpkh_multi(setup_segwit, wallet_structure, in_amt,
                                 amount, segwit_amt, segwit_ins, o_ins):
    """Creates a wallet from which non-segwit inputs/
    outputs can be created, constructs one or more
    p2wpkh in p2sh spendable utxos (by paying into the
    corresponding address) and tests spending them
    in combination.
    wallet_structure is in accordance with commontest.make_wallets, see docs there
    in_amt is the amount to pay into each address into the wallet (non-segwit adds)
    amount (in satoshis) is how much we will pay to the output address
    segwit_amt in BTC is the amount we will fund each new segwit address with
    segwit_ins is a list of input indices (where to place the funding segwit utxos)
    other_ins is a list of input indices (where to place the funding non-sw utxos)
    """
    wallet = make_wallets(1, wallet_structure, in_amt,
                          walletclass=Wallet)[0]['wallet']
    jm_single().bc_interface.sync_wallet(wallet)
    other_ins = {}
    ctr = 0
    for k, v in wallet.unspent.iteritems():
        #only extract as many non-segwit utxos as we need;
        #doesn't matter which they are
        if ctr == len(o_ins):
            break
        other_ins[k] = (v["value"], wallet.get_key_from_addr(v["address"]),
                        o_ins[ctr])
        ctr += 1
    ins_sw = {}
    for i in range(len(segwit_ins)):
        #build segwit ins from "deterministic-random" keys;
        #intended to be the same for each run with the same parameters
        seed = json.dumps(
            [i, wallet_structure, in_amt, amount, segwit_ins, other_ins])
        priv = btc.sha256(seed) + "01"
        pub = btc.privtopub(priv)
        #magicbyte is testnet p2sh
        addr1 = btc.pubkey_to_p2sh_p2wpkh_address(pub, magicbyte=196)
        print "got address for p2shp2wpkh: " + addr1
        txid = jm_single().bc_interface.grab_coins(addr1, segwit_amt)
        #TODO - int cast, fix?
        ins_sw[get_utxo_from_txid(txid, addr1)] = (int(segwit_amt * 100000000),
                                                   priv, segwit_ins[i])
    #make_sign_and_push will sanity check the received amount is correct
    txid = make_sign_and_push(ins_sw, wallet, amount, other_ins)
    #will always be False if it didn't push.
    assert txid
Exemplo n.º 4
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)
 def query_utxo_set(self, txouts,includeconf=False):
     if self.qusfail:
         #simulate failure to find the utxo
         return [None]
     if self.fake_query_results:
         result = []
         for x in self.fake_query_results:
             for y in txouts:
                 if y == x['utxo']:
                     result.append(x)
         return result
     result = []
     #external maker utxos
     known_outs = {"03243f4a659e278a1333f8308f6aaf32db4692ee7df0340202750fd6c09150f6:1": "03a2d1cbe977b1feaf8d0d5cc28c686859563d1520b28018be0c2661cf1ebe4857",
                   "498faa8b22534f3b443c6b0ce202f31e12f21668b4f0c7a005146808f250d4c3:0": "02b4b749d54e96b04066b0803e372a43d6ffa16e75a001ae0ed4b235674ab286be",
                   "3f3ea820d706e08ad8dc1d2c392c98facb1b067ae4c671043ae9461057bd2a3c:1": "023bcbafb4f68455e0d1d117c178b0e82a84e66414f0987453d78da034b299c3a9"}
     #our wallet utxos, faked, for podle tests: utxos are doctored (leading 'f'),
     #and the lists are (amt, age)
     wallet_outs = {'f34b635ed8891f16c4ec5b8236ae86164783903e8e8bb47fa9ef2ca31f3c2d7a:0': [10000000, 2],
                    'f780d6e5e381bff01a3519997bb4fcba002493103a198fde334fd264f9835d75:1': [20000000, 6],
                    'fe574db96a4d43a99786b3ea653cda9e4388f377848f489332577e018380cff1:0': [50000000, 3],
                    'fd9711a2ef340750db21efb761f5f7d665d94b312332dc354e252c77e9c48349:0': [50000000, 6]}
     
     if includeconf and set(txouts).issubset(set(wallet_outs)):
         #includeconf used as a trigger for a podle check;
         #here we simulate a variety of amount/age returns
         results = []
         for to in txouts:
             results.append({'value': wallet_outs[to][0],
                             'confirms': wallet_outs[to][1]})
         return results
     if txouts[0] in known_outs:
         addr = btc.pubkey_to_p2sh_p2wpkh_address(
                     known_outs[txouts[0]], get_p2sh_vbyte())
         return [{'value': 200000000,
                  'address': addr,
                  'script': btc.address_to_script(addr),
                  'confirms': 20}]
     for t in txouts:
         result_dict = {'value': 10000000000,
                        'address': "mrcNu71ztWjAQA6ww9kHiW3zBWSQidHXTQ",
                        'script': '76a91479b000887626b294a914501a4cd226b58b23598388ac'}
         if includeconf:
             result_dict['confirms'] = 20
         result.append(result_dict)        
     return result
Exemplo n.º 6
0
 def final_checks(self):
     """Check that our keys have received the right funds
     in the wallet (all the single-owned outpoints to p2sh-p2wpkh
     outpoints should contain utxos that own the intended number
     of coins).
     """
     match = True
     total_coins = 0
     for i, tx in enumerate(self.template.txs):
         txid = self.realtxs[i].txid
         for j, tout in enumerate(tx.outs):
             if tout.counterparty == 0:
                 expected_amount = tout.amount
                 print("We expected this amount out: ", expected_amount)
                 actual_key = self.realtxs[i].keys["outs"][j][0]
                 actual_address = btc.pubkey_to_p2sh_p2wpkh_address(
                     actual_key, get_p2sh_vbyte())
                 #direct query on blockchain for the transaction,
                 #then check if it pays to our address and in what amount
                 res = cjxt_single().bc_interface.rpc(
                     'gettxout', [txid, j, True])
                 if not ("scriptPubKey" in res
                         and "addresses" in res["scriptPubKey"]):
                     print("Failed to query the tx: ", txid)
                 found_address = str(res["scriptPubKey"]["addresses"][0])
                 if not found_address == actual_address:
                     print("Error, transaction, vout: ", txid, j,
                           "has address: ", found_address,
                           ", but should have been address: ",
                           actual_address)
                 print("Amount received was: ", res["value"],
                       " at address: ", actual_address)
                 sat_value = btc_to_satoshis(res["value"])
                 total_coins += res["value"]
                 if not sat_value == expected_amount or not actual_address == found_address:
                     match = False
     if match:
         print("Success! Received back total coins: ", total_coins)
     else:
         print(
             "Failure! Not all expected coins received, see above summary.")
     reactor.stop()