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
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))
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_key_from_addr(self, addr): """usable addresses: privkey all 1s, 2s, 3s, ... :""" privs = [x * 32 + "\x01" for x in [chr(y) for y in range(1, 6)]] addrs = {} """ mrcNu71ztWjAQA6ww9kHiW3zBWSQidHXTQ n31WD8pkfAjg2APV78GnbDTdZb1QonBi5D mmVEKH61BZbLbnVEmk9VmojreB4G4PmBPd msxyyydNXTiBmt3SushXbH5Qh2ukBAThk3 musGZczug3BAbqobmYherywCwL9REgNaNm """ for p in privs: addrs[p] = bitcoin.privkey_to_address(p, False, magicbyte=0x6f) for p, a in addrs.iteritems(): if a == addr: return binascii.hexlify(p) raise ValueError("No such keypair")
def test_on_sig(createcmtdata, dummyaddr, signmethod, schedule): #plan: create a new transaction with known inputs and dummy outputs; #then, create a signature with various inputs, pass in in b64 to on_sig. #in order for it to verify, the DummyBlockchainInterface will have to #return the right values in query_utxo_set #create 2 privkey + utxos that are to be ours privs = [x * 32 + "\x01" for x in [chr(y) for y in range(1, 6)]] utxos = [str(x) * 64 + ":1" for x in range(5)] fake_query_results = [{ 'value': 200000000, 'utxo': utxos[x], 'address': bitcoin.privkey_to_address(privs[x], False, magicbyte=0x6f), 'script': bitcoin.mk_pubkey_script( bitcoin.privkey_to_address(privs[x], False, magicbyte=0x6f)), 'confirms': 20 } for x in range(5)] dbci = DummyBlockchainInterface() dbci.insert_fake_query_results(fake_query_results) jm_single().bc_interface = dbci #make a transaction with all the fake results above, and some outputs outs = [{ 'value': 100000000, 'address': dummyaddr }, { 'value': 899990000, 'address': dummyaddr }] tx = bitcoin.mktx(utxos, outs) de_tx = bitcoin.deserialize(tx) #prepare the Taker with the right intermediate data taker = get_taker(schedule=schedule, sign_method=signmethod) taker.nonrespondants = ["cp1", "cp2", "cp3"] taker.latest_tx = de_tx #my inputs are the first 2 utxos taker.input_utxos = { utxos[0]: { 'address': bitcoin.privkey_to_address(privs[0], False, magicbyte=0x6f), 'value': 200000000 }, utxos[1]: { 'address': bitcoin.privkey_to_address(privs[1], False, magicbyte=0x6f), 'value': 200000000 } } taker.utxos = { None: utxos[:2], "cp1": [utxos[2]], "cp2": [utxos[3]], "cp3": [utxos[4]] } for i in range(2): # placeholders required for my inputs taker.latest_tx['ins'][i]['script'] = 'deadbeef' #to prepare for my signing, need to mark cjaddr: taker.my_cj_addr = dummyaddr #make signatures for the last 3 fake utxos, considered as "not ours": tx3 = bitcoin.sign(tx, 2, privs[2]) sig3 = b64encode( bitcoin.deserialize(tx3)['ins'][2]['script'].decode('hex')) taker.on_sig("cp1", sig3) tx4 = bitcoin.sign(tx, 3, privs[3]) sig4 = b64encode( bitcoin.deserialize(tx4)['ins'][3]['script'].decode('hex')) taker.on_sig("cp2", sig4) tx5 = bitcoin.sign(tx, 4, privs[4]) #Before completing with the final signature, which will trigger our own #signing, try with an injected failure of query utxo set, which should #prevent this signature being accepted. dbci.setQUSFail(True) sig5 = b64encode( bitcoin.deserialize(tx5)['ins'][4]['script'].decode('hex')) taker.on_sig("cp3", sig5) #allow it to succeed, and try again dbci.setQUSFail(False) #this should succeed and trigger the we-sign code taker.on_sig("cp3", sig5)