Example #1
0
def Check1000k_address(start_private_key,Num):
    global guessNum
    private_key = deepcopy(start_private_key)
    # private_key=26563230048437957592232553826663696440606756685920117476832299673293013768870
    startkey = deepcopy(start_private_key)
    while private_key < 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141:
        random_private_key=Generate_random_private_key()
        random_addresss = from_private_key_to_address(random_private_key)
        private_key += 1
        guessNum += 1
        PrivateKey_WIF = bitcoin.encode_privkey(private_key,'wif')
        compressed_private_key = bitcoin.encode_privkey(private_key,'hex') + '01'
        PrivateKey_WIF_Compressed = bitcoin.encode_privkey(bitcoin.decode_privkey(compressed_private_key, 'hex'), 'wif')
        bitcoin_address = bitcoin.privkey_to_address(PrivateKey_WIF)
        compressed_bitcoin_address = bitcoin.privkey_to_address(PrivateKey_WIF_Compressed)
        addresss = [bitcoin_address,compressed_bitcoin_address,random_addresss[0],random_addresss[1]]
        for address in addresss:
            try:
                balance = querybalainceV3(address)
            except:
                print 'failed to query private_key %s ,address %s' % (private_key,address)
                add_unquery_address_to_log(private_key,address)
                continue
            time.sleep(0.5)
            #balance = querybalance('1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa')
            if int(balance) >0 :
                print 'private_key %s has %s BTC' % (private_key,balance)
                add_query_address_has_btc(private_key,address)
                linestring = 'private_key %s has %s BTC !' % (private_key,balance)
                smtp.send_BTCmail(linestring)
        print "Check %s private_key %s " % (str(guessNum),private_key)
        if private_key==startkey + Num:
            add_query_address_has_btc(private_key,Num)
            break
 def deploy(self):
     if self.contract.network.name in ['RSK_MAINNET', 'RSK_TESTNET'
                                       ] and self.btc_key is None:
         priv = os.urandom(32)
         if self.contract.network.name == 'RSK_MAINNET':
             address = bitcoin.privkey_to_address(priv, magicbyte=0)
         else:
             address = bitcoin.privkey_to_address(priv, magicbyte=0x6F)
         btc_key = BtcKey4RSK(private_key=binascii.hexlify(priv).decode(),
                              btc_address=address)
         btc_key.save()
         self.btc_key = btc_key
         self.save()
     super().deploy()
Example #3
0
def test_direct_send(setup_regtest, wallet_structures, mean_amt, mixdepth,
                     amount, valid):
    log = get_log()
    wallets = make_wallets(1,
                           wallet_structures=wallet_structures,
                           mean_amt=mean_amt)
    wallet = wallets[0]['wallet']
    sync_wallet(wallet)
    destaddr = btc.privkey_to_address(
        os.urandom(32),  #TODO deterministic-ise
        from_hex=False,
        magicbyte=get_p2pk_vbyte())
    addr_valid, errormsg = validate_address(destaddr)
    assert addr_valid, "Invalid destination address: " + destaddr + \
               ", error message: " + errormsg
    if not valid:
        with pytest.raises(Exception) as e_info:
            sendpayment.direct_send(wallet,
                                    amount,
                                    mixdepth,
                                    destaddr,
                                    answeryes=True)
    else:
        sendpayment.direct_send(wallet,
                                amount,
                                mixdepth,
                                destaddr,
                                answeryes=True)
Example #4
0
    def run_tumble(self, amt):
        yigen_procs = []
        for i in range(6):
            ygp = local_command([python_cmd, yg_cmd,\
                                 str(self.wallets[i]['seed'])], bg=True)
            time.sleep(2)  #give it a chance
            yigen_procs.append(ygp)


#A significant delay is needed to wait for the yield generators to sync
        time.sleep(20)

        #start a tumbler
        amt = amt * 1e8  #in satoshis
        #send to any old address
        dest_address = btc.privkey_to_address(os.urandom(32), get_p2pk_vbyte())
        try:
            print 'taker seed: ' + self.wallets[6]['seed']
            while True:
                print 'hello'
                time.sleep(80)
        except subprocess.CalledProcessError, e:
            for ygp in yigen_procs:
                ygp.kill()
            print e.returncode
            print e.message
            raise
Example #5
0
    def run_simple_send(self, n):
        #start yield generator with wallet1
        yigen_proc = local_command(
            ['python', 'yield-generator.py',
             str(self.wallets[1]['seed'])],
            redirect=self.wallets[1]['seed'],
            bg=True)

        #A significant delay is needed to wait for the yield generator to sync its wallet
        time.sleep(30)

        #run a single sendpayment call with wallet2
        amt = 100000000  #in satoshis
        dest_address = btc.privkey_to_address(os.urandom(32),
                                              common.get_addr_vbyte())
        try:
            for i in range(n):
                sp_proc = local_command(['python','sendpayment.py','--yes','-N','1', self.wallets[2]['seed'],\
                                                      str(amt), dest_address])
        except subprocess.CalledProcessError, e:
            if yigen_proc:
                yigen_proc.terminate()
            print e.returncode
            print e.message
            raise
Example #6
0
def __check_valid(k):
    #get raw priv key:
    decode_private_key = bitcoin.decode_privkey(k)
    if decode_private_key >= bitcoin.N:
        return None
    #get compressed priv key:
    compressed_private_key = bitcoin.encode_privkey(decode_private_key,
                                                    "hex_compressed")

    #get raw addr & compressed addr
    addr_raw = bitcoin.privkey_to_address(decode_private_key)
    addr_comp = bitcoin.privkey_to_address(compressed_private_key)

    if addr_raw == target_addr or addr_comp == target_addr:
        print(f"FOUND ONE!!!! PRIVATE KEY IS: {hex(decode_private_key)}")
        return hex(decode_private_key)
Example #7
0
    def run_send(self, bad=False):
        yigen_procs = []
        if bad:
            i = 2
        else:
            i = 0
        ygp = local_command([python_cmd,yg_cmd,\
                                 str(self.wallets[i]['seed'])], bg=True)
        time.sleep(2)  #give it a chance
        yigen_procs.append(ygp)

        #A significant delay is needed to wait for the yield generators to sync
        time.sleep(20)

        #run a single sendpayment call
        amt = 100000000  #in satoshis
        dest_address = btc.privkey_to_address(os.urandom(32), get_p2pk_vbyte())
        try:
            sp_proc = local_command([
                python_cmd, 'sendpayment.py', '--yes', '-N', '1',
                self.wallets[1]['seed'],
                str(amt), dest_address
            ])
        except subprocess.CalledProcessError, e:
            for ygp in yigen_procs:
                ygp.kill()
            print e.returncode
            print e.message
            raise
def validate_utxo_data(utxo_datas, retrieve=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())
        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:
            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: " + 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
    def run_tumble(self, amt):
        yigen_procs = []
        for i in range(6):
            ygp = local_command([python_cmd, yg_cmd,\
                                 str(self.wallets[i]['seed'])], bg=True)
            time.sleep(2)  #give it a chance
            yigen_procs.append(ygp)

#A significant delay is needed to wait for the yield generators to sync
        time.sleep(20)

        #start a tumbler
        amt = amt * 1e8  #in satoshis
        #send to any old address
        dest_address = btc.privkey_to_address(os.urandom(32), get_p2pk_vbyte())
        try:
            print 'taker seed: '+self.wallets[6]['seed']
            while True:
                print 'hello'
                time.sleep(80)
        except subprocess.CalledProcessError, e:
            for ygp in yigen_procs:
                ygp.kill()
            print e.returncode
            print e.message
            raise
Example #10
0
    def run_send(self, bad=False):
        yigen_procs = []
        if bad:
            i = 2
        else:
            i = 0
        ygp = local_command([python_cmd,yg_cmd,\
                                 str(self.wallets[i]['seed'])], bg=True)
        time.sleep(2)  #give it a chance
        yigen_procs.append(ygp)

        #A significant delay is needed to wait for the yield generators to sync
        time.sleep(20)

        #run a single sendpayment call
        amt = 100000000  #in satoshis
        dest_address = btc.privkey_to_address(os.urandom(32), get_p2pk_vbyte())
        try:
            sp_proc = local_command([python_cmd, 'sendpayment.py', '--yes',
                                     '-N', '1', self.wallets[1]['seed'], str(
                                         amt), dest_address])
        except subprocess.CalledProcessError, e:
            for ygp in yigen_procs:
                ygp.kill()
            print e.returncode
            print e.message
            raise
Example #11
0
def cmdImportPrivs(args):
    for l in stdin:
        ls = l.split()
        for x in ls:
            try:
                privkey = bitcoin.b58check_to_hex(x)
                addr = bitcoin.privkey_to_address(privkey)
                tokenval.db["PRIVKEY_" + addr] = privkey
            except:
                pass
Example #12
0
 def create_pair(b58_magic_byte, address_magic_byte, seed=None):
     """Function create private key and address"""
     if seed is None:
         seed = KeyGenerator.random_seed()
     hash = sha256(seed)
     private_key = int(hash, base=16)
     private_key_wif = bin_to_b58check(encode(private_key, 256, 32),
                                       b58_magic_byte)
     address = privkey_to_address(private_key, address_magic_byte)
     return private_key_wif, address
Example #13
0
def Check1000k_address(start_private_key, Num):
    global guessNum
    private_key = deepcopy(start_private_key)
    # private_key=26563230048437957592232553826663696440606756685920117476832299673293013768870
    startkey = deepcopy(start_private_key)
    while private_key < 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141:
        random_private_key = Generate_random_private_key()
        random_addresss = from_private_key_to_address(random_private_key)
        private_key += 1
        guessNum += 1
        PrivateKey_WIF = bitcoin.encode_privkey(private_key, 'wif')
        compressed_private_key = bitcoin.encode_privkey(private_key,
                                                        'hex') + '01'
        PrivateKey_WIF_Compressed = bitcoin.encode_privkey(
            bitcoin.decode_privkey(compressed_private_key, 'hex'), 'wif')
        bitcoin_address = bitcoin.privkey_to_address(PrivateKey_WIF)
        compressed_bitcoin_address = bitcoin.privkey_to_address(
            PrivateKey_WIF_Compressed)
        addresss = [
            bitcoin_address, compressed_bitcoin_address, random_addresss[0],
            random_addresss[1]
        ]
        for address in addresss:
            try:
                balance = querybalainceV3(address)
            except:
                print 'failed to query private_key %s ,address %s' % (
                    private_key, address)
                add_unquery_address_to_log(private_key, address)
                continue
            time.sleep(0.5)
            #balance = querybalance('1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa')
            if int(balance) > 0:
                print 'private_key %s has %s BTC' % (private_key, balance)
                add_query_address_has_btc(private_key, address)
                linestring = 'private_key %s has %s BTC !' % (private_key,
                                                              balance)
                smtp.send_BTCmail(linestring)
        print "Check %s private_key %s " % (str(guessNum), private_key)
        if private_key == startkey + Num:
            add_query_address_has_btc(private_key, Num)
            break
def makeTestMemberKeys():
    member_names = ["member_%s" % x for x in "abcdefghijklmnopqrstuvwxyz"]

    privkeys = [
        bitcoin.hex_to_b58check(bitcoin.sha256(member), 0x80)
        for member in member_names
    ]

    addresses = [bitcoin.privkey_to_address(priv) for priv in privkeys]

    return member_names, addresses, privkeys
Example #15
0
def wif_to_address(crypto, wif):
    if is_py2:
        wif_byte = int(hexlify(b58decode_check(wif)[0]), 16)
    else:
        wif_byte = b58decode_check(wif)[0]

    if not wif_byte == crypto_data[crypto.lower()]['private_key_prefix']:
        msg = 'WIF encoded with wrong prefix byte. Are you sure this is a %s address?' % crypto.upper()
        raise Exception(msg)

    address_byte = crypto_data[crypto.lower()]['address_version_byte']
    return privkey_to_address(wif, address_byte)
Example #16
0
def wif_to_address(crypto, wif):
    if is_py2:
        wif_byte = int(hexlify(b58decode_check(wif)[0]), 16)
    else:
        wif_byte = b58decode_check(wif)[0]

    if not wif_byte == crypto_data[crypto.lower()]['private_key_prefix']:
        msg = 'WIF encoded with wrong prefix byte. Are you sure this is a %s address?' % crypto.upper(
        )
        raise Exception(msg)

    address_byte = crypto_data[crypto.lower()]['address_version_byte']
    return privkey_to_address(wif, address_byte)
Example #17
0
def pattern_mine(pattern="dft", startWith=False):
    secret_key = ""
    address = ""
    while 1:
        # generate the secret private key
        secret_key = bitcoin.random_key()

        # generate the address derived from private key
        address = bitcoin.privkey_to_address(secret_key)

        if bool(startWith):
            if address.startswith("1" + pattern): break
        else:
            if pattern in address: break

    print("Vanity address found: ", address)
    print("HEX private key: ", secret_key)
def print_the_secrets(my_256_bit_secret):

    print ("\n\n========== 128-bit digests (12 BIP39 words): ==========")

    print ("\n\nThe two 128-bit digests are created by cutting the 256-bit digest.")

    print_128_bit_secret("FIRST",my_256_bit_secret[0:16])
    print_128_bit_secret("SECOND",my_256_bit_secret[16:32])

    print ("\n\nFor better security use only the 256-bit digest (24 BIP39 words).")
    print ("Don't forget that the two 128-bit digests were created by cutting the 256-bit digest in half.")

    print ("\n\n========== The same 256-bit digest in different formats: ==========")

    # we need it also for bitcoin.encode_privkey()
    my_256_bit_secret_HEX = binascii.b2a_hex(my_256_bit_secret).decode("utf-8")

    print ("\n\nThe 256-bit digest in hex format:", my_256_bit_secret_HEX)

    print ("\nThe 256-bit digest in base64 format:", binascii.b2a_base64(my_256_bit_secret).decode("utf-8"))

    print ("\nThe 256-bit digest in BIP39 mnemonic format:\n\n", mnemonic.Mnemonic('english').to_mnemonic(my_256_bit_secret))

    print ("\n\nThe 256-bit digest in RFC1751 mnemonic format:\n\n", key_to_english(my_256_bit_secret))

    CURVE_ORDER = 115792089237316195423570985008687907852837564279074904382605163141518161494337

    my_256_bit_secret_decimal = string_to_number(my_256_bit_secret)

    print ("\n\nThe 256-bit digest in decimal format:\n\n", my_256_bit_secret_decimal)

    if my_256_bit_secret_decimal < ( CURVE_ORDER - 1000000000 ):
        if my_256_bit_secret_decimal > 1000000000:
            print ("Looks ok for a SECP256k1 private key.")
        else:
            print ("Looks too small for a private key.")
    else:
        print ("Looks too big for a SECP256k1 private key.")

    my_256_bit_secret_WIF = bitcoin.encode_privkey(my_256_bit_secret_HEX,"wif_compressed")

    print ("\n\nThe 256-bit digest in compressed WIF format:\n\n", my_256_bit_secret_WIF)

    print ("\nThe address derived from the above WIF key:",bitcoin.privkey_to_address(my_256_bit_secret_WIF))
Example #19
0
    def run_simple_send(self, n):
        #start yield generator with wallet1
	yigen_proc = local_command(['python','yield-generator.py', 
	                            str(self.wallets[1]['seed'])],redirect=self.wallets[1]['seed'],bg=True)
	
	#A significant delay is needed to wait for the yield generator to sync its wallet
	time.sleep(30)
	
	#run a single sendpayment call with wallet2
	amt = 100000000 #in satoshis
	dest_address = btc.privkey_to_address(os.urandom(32), common.get_addr_vbyte())
	try:
	    for i in range(n):
		sp_proc = local_command(['python','sendpayment.py','--yes','-N','1', self.wallets[2]['seed'],\
	                                       str(amt), dest_address])
	except subprocess.CalledProcessError, e:
	    if yigen_proc:
		yigen_proc.terminate()
	    print e.returncode
	    print e.message
	    raise
Example #20
0
def test_direct_send(setup_regtest, wallet_structures, mean_amt, mixdepth,
                     amount, valid):
    log = get_log()
    wallets = make_wallets(1,
                           wallet_structures=wallet_structures,
                           mean_amt=mean_amt)
    wallet = wallets[0]['wallet']
    sync_wallet(wallet)
    destaddr = btc.privkey_to_address(
                os.urandom(32), #TODO deterministic-ise
                from_hex=False,
                magicbyte=get_p2pk_vbyte())
    addr_valid, errormsg = validate_address(destaddr)
    assert addr_valid, "Invalid destination address: " + destaddr + \
               ", error message: " + errormsg
    if not valid:
        with pytest.raises(Exception) as e_info:
            sendpayment.direct_send(wallet,
                                    amount, mixdepth, destaddr, answeryes=True)
    else:
        sendpayment.direct_send(wallet,
                                amount, mixdepth, destaddr, answeryes=True)
Example #21
0
    def __init__(self,
                 token_addr,
                 mints,
                 outputs,
                 privs=None,
                 linked_onchain_txn=None,
                 signatures=[]):
        self.token_addr = token_addr
        self.mints = mints
        self.outputs = outputs
        self.privs = privs
        self.linked_onchain_txn = linked_onchain_txn
        self.signatures = signatures

        msg = self.txn_part()
        log.info("Token transaction part hash: %s",
                 hexlify(bitcoin.electrum_sig_hash(msg)))

        if self.privs is None:
            assert (len(self.signatures))
            self.signed_addresses = []
            for sig in self.signatures:
                addr_reconstructed = bitcoin.pubtoaddr(
                    bitcoin.ecdsa_recover(msg, sig))
                self.signed_addresses.append(addr_reconstructed)
        else:
            self.signed_addresses = [
                bitcoin.privkey_to_address(priv) for priv in privs
            ]

        import io
        b = io.BytesIO()
        self.write(b)
        self.hsh = bitcoin.sha256(
            bytes(b.getbuffer())[:-1]
        )  # TOTAL hash, including signatures, but excluding final \n byte
        self.handle = "TOK_" + self.hsh
        log.info("Token transaction overall hash: %s", self.hsh)
Example #22
0
    def run_tumble(self, amt):
        yigen_procs = []
	for i in range(6):
	    ygp = local_command(['python','yield-generator.py',\
	                         str(self.wallets[i]['seed'])], bg=True)
	    time.sleep(2) #give it a chance
	    yigen_procs.append(ygp)
	
	#A significant delay is needed to wait for the yield generators to sync 
	time.sleep(60)
	
	#start a tumbler
	amt = amt*1e8 #in satoshis
	#send to any old address
	dest_address = btc.privkey_to_address(os.urandom(32), common.get_addr_vbyte())	
	try:
	    #default mixdepth source is zero, so will take coins from m 0.
	    #see tumbler.py --h for details
	    expected = ['tumble with these tx']
	    test_in = ['y']
	    p = pexpect.spawn('python',['tumbler.py', '-N', '1', '0',
	                             '-a', '0', '-M', '5', 
	                             self.wallets[6]['seed'], dest_address])
	    interact(p, test_in, expected)
	    p.expect(pexpect.EOF, timeout=100000)
	    p.close()
	    if p.exitstatus != 0:
		print 'failed due to exit status: '+str(p.exitstatus)
		return False
	    #print('use seed: '+self.wallets[6]['seed'])
	    #print('use dest addr: '+dest_address)
	    #ret = raw_input('quit?')
	except subprocess.CalledProcessError, e:
	    for ygp in yigen_procs:
		ygp.kill()
	    print e.returncode
	    print e.message
	    raise
Example #23
0
    def run_sweep(self):
        #currently broken due to flooding; to make it work
        #change the 60 loop for the bad wallet to 20
        yigen_procs = []
        ygp = local_command([python_cmd,yg_cmd,\
                                     str(self.wallets[3]['seed'])], bg=True)
        time.sleep(2)  #give it a chance
        yigen_procs.append(ygp)

        #A significant delay is needed to wait for the yield generators to sync
        time.sleep(20)

        dest_address = btc.privkey_to_address(os.urandom(32), get_p2pk_vbyte())
        try:
            sp_proc = local_command([python_cmd, 'sendpayment.py', '--yes',
                                     '-N', '1', self.wallets[2][
                                         'seed'], '0', dest_address])
        except subprocess.CalledProcessError, e:
            for ygp in yigen_procs:
                ygp.kill()
            print e.returncode
            print e.message
            raise
Example #24
0
def check_priv_key(priv_key):
    try:
        address = privkey_to_address(priv_key)
        print("try priv key {}".format(priv_key))
        print("generated public key {}".format(address))
        addr_overview = get_address_overview(address)  #getting address data
        for key, value in addr_overview.items(
        ):  #getting info from address overview
            #check past transactions
            if key == 'final_n_tx':  #check for any transactions in the past
                if value > 0:  #if exist, then address has been used
                    print("Address has been used {0} times in the past".format(
                        value))
                    print(priv_key)
                    print(address)
            #check balance
            if key == 'final_balance':  #check for funds in the address
                if value > 0:  #if any btc left on address, print details
                    print("Address has balance of {0}".format(
                        from_satoshis(value, 'btc')))
    except:
        #this happens if string doesn't generate valid key
        return None
Example #25
0
    def run_nparty_join(self):
	yigen_procs = []
	for i in range(self.n):
	    ygp = local_command(['python','yield-generator.py',\
	                         str(self.wallets[i]['seed'])], bg=True)
	    time.sleep(2) #give it a chance
	    yigen_procs.append(ygp)
	
	#A significant delay is needed to wait for the yield generators to sync 
	time.sleep(60)
	
	#run a single sendpayment call 
	amt = 100000000 #in satoshis
	dest_address = btc.privkey_to_address(os.urandom(32), common.get_addr_vbyte())	
	try:
	    sp_proc = local_command(['python','sendpayment.py','--yes','-N', str(self.n),\
	                             self.wallets[self.n]['seed'], str(amt), dest_address])
	except subprocess.CalledProcessError, e:
	    for ygp in yigen_procs:
		ygp.kill()
	    print e.returncode
	    print e.message
	    raise
Example #26
0
    def run_nparty_join(self):
        yigen_procs = []
        for i in range(self.n):
            ygp = local_command(['python','yield-generator.py',\
                                 str(self.wallets[i]['seed'])], bg=True)
            time.sleep(2)  #give it a chance
            yigen_procs.append(ygp)

        #A significant delay is needed to wait for the yield generators to sync
        time.sleep(60)

        #run a single sendpayment call
        amt = 100000000  #in satoshis
        dest_address = btc.privkey_to_address(os.urandom(32),
                                              common.get_addr_vbyte())
        try:
            sp_proc = local_command(['python','sendpayment.py','-N', str(self.n),\
                                     self.wallets[self.n]['seed'], str(amt), dest_address])
        except subprocess.CalledProcessError, e:
            for ygp in yigen_procs:
                ygp.kill()
            print e.returncode
            print e.message
            raise
Example #27
0
    def run_tumble(self, amt):
        yigen_procs = []
        for i in range(6):
            ygp = local_command([python_cmd, yg_cmd,\
                                 str(self.wallets[i]['seed'])], bg=True)
            time.sleep(2)  #give it a chance
            yigen_procs.append(ygp)

#A significant delay is needed to wait for the yield generators to sync
        time.sleep(60)

        #start a tumbler
        amt = amt * 1e8  #in satoshis
        #send to any old address
        dest_address = btc.privkey_to_address(os.urandom(32), get_p2pk_vbyte())
        try:
            #default mixdepth source is zero, so will take coins from m 0.
            #see tumbler.py --h for details
            expected = ['tumble with these tx']
            test_in = ['y']
            p = pexpect.spawn(python_cmd,
                              ['tumbler.py', '-N', '2', '0', '-a', '0', '-M',
                               '5', '-w', '10', '-l', '0.2', '-s', '1000000',
                               '-q', '5', self.wallets[6]['seed'], dest_address])
            interact(p, test_in, expected)
            p.expect(pexpect.EOF, timeout=100000)
            p.close()
            if p.exitstatus != 0:
                print 'failed due to exit status: ' + str(p.exitstatus)
                return False
        except subprocess.CalledProcessError, e:
            for ygp in yigen_procs:
                ygp.kill()
            print e.returncode
            print e.message
            raise
Example #28
0
    def run_sweep(self):
        #currently broken due to flooding; to make it work
        #change the 60 loop for the bad wallet to 20
        yigen_procs = []
        ygp = local_command([python_cmd,yg_cmd,\
                                     str(self.wallets[3]['seed'])], bg=True)
        time.sleep(2)  #give it a chance
        yigen_procs.append(ygp)

        #A significant delay is needed to wait for the yield generators to sync
        time.sleep(20)

        dest_address = btc.privkey_to_address(os.urandom(32), get_p2pk_vbyte())
        try:
            sp_proc = local_command([
                python_cmd, 'sendpayment.py', '--yes', '-N', '1',
                self.wallets[2]['seed'], '0', dest_address
            ])
        except subprocess.CalledProcessError, e:
            for ygp in yigen_procs:
                ygp.kill()
            print e.returncode
            print e.message
            raise
Example #29
0
def from_private_key_to_address(private_key):
    compressed_private_key = private_key + '01'
    bitcoin_address = bitcoin.privkey_to_address(private_key)
    compressed_bitcoin_address = bitcoin.privkey_to_address(
        compressed_private_key)
    return bitcoin_address, compressed_bitcoin_address
Example #30
0
def from_private_key_to_address(private_key):
    compressed_private_key = private_key + '01'
    bitcoin_address = bitcoin.privkey_to_address(private_key)
    compressed_bitcoin_address = bitcoin.privkey_to_address(compressed_private_key)
    return bitcoin_address,compressed_bitcoin_address
Example #31
0
def test_sendpayment(setup_regtest, num_ygs, wallet_structures, mean_amt,
                     mixdepth, sending_amt, ygcfs, fails, donate, rpcwallet):
    """Test of sendpayment code, with yield generators in background.
    """
    log = get_log()
    makercount = num_ygs
    answeryes = True
    txfee = 5000
    waittime = 5
    amount = sending_amt
    wallets = make_wallets(makercount + 1,
                           wallet_structures=wallet_structures,
                           mean_amt=mean_amt)
    #the sendpayment bot uses the last wallet in the list
    if not rpcwallet:
        wallet = wallets[makercount]['wallet']
    else:
        wallet = BitcoinCoreWallet(fromaccount="")

    yigen_procs = []
    if ygcfs:
        assert makercount == len(ygcfs)
    for i in range(makercount):
        if ygcfs:
            #back up default config, overwrite before start
            os.rename("joinmarket.cfg", "joinmarket.cfg.bak")
            shutil.copy2(ygcfs[i], "joinmarket.cfg")
        ygp = local_command([python_cmd, yg_cmd,\
                             str(wallets[i]['seed'])], bg=True)
        time.sleep(2)  #give it a chance
        yigen_procs.append(ygp)
        if ygcfs:
            #Note: in case of using multiple configs,
            #the starting config is what is used by sendpayment
            os.rename("joinmarket.cfg.bak", "joinmarket.cfg")

    #A significant delay is needed to wait for the yield generators to sync
    time.sleep(20)
    if donate:
        destaddr = None
    else:
        destaddr = btc.privkey_to_address(
            os.urandom(32),
            from_hex=False,
            magicbyte=get_p2pk_vbyte())
        addr_valid, errormsg = validate_address(destaddr)
        assert addr_valid, "Invalid destination address: " + destaddr + \
           ", error message: " + errormsg

    #TODO paramatetrize this as a test variable
    chooseOrdersFunc = weighted_order_choose

    log.debug('starting sendpayment')

    sync_wallet(wallet)
    
    #Trigger PING LAG sending artificially
    joinmarket.irc.PING_INTERVAL = 3
    
    mcs = [IRCMessageChannel(c) for c in get_irc_mchannels()]
    mcc = MessageChannelCollection(mcs)
    #hack fix for #356 if multiple orders per counterparty
    #removed for now.
    #if amount==0: makercount=2
    taker = sendpayment.SendPayment(mcc, wallet, destaddr, amount, makercount-2,
                                    txfee, waittime, mixdepth, answeryes,
                                    chooseOrdersFunc)
    try:
        log.debug('starting message channels')
        mcc.run(failures=fails)
    finally:
        if any(yigen_procs):
            for ygp in yigen_procs:
                #NB *GENTLE* shutdown is essential for
                #test coverage reporting!
                ygp.send_signal(signal.SIGINT)
                ygp.wait()
    #wait for block generation
    time.sleep(5)
    if not donate:
        received = jm_single().bc_interface.get_received_by_addr(
            [destaddr], None)['data'][0]['balance']
        if amount != 0:
            assert received == amount, "sendpayment failed - coins not arrived, " +\
               "received: " + str(received)
        #TODO: how to check success for sweep case?
        else:
            assert received != 0
Example #32
0
                sig = ls[1]

                sigs.append(sig)
                l = infile.readline().decode("ascii")
                ls = l.split()

            tt = TokenTransaction(token_addr, mints, outputs, signatures=sigs)
            log.info("Read transaction %s.", tt.handle)
            for addr in tt.signed_addresses:
                log.info("Signed with key for address: %s", addr)
            yield tt

        elif ls[0] == "BCH":  # on chain transaction hex string
            yield OnchainTransaction(ls[1])


# FIXME: replace this garbage with unit tests
if __name__ == "__main__":
    priv = bitcoin.sha256("0")
    priv2 = bitcoin.sha256("1")
    addr = bitcoin.privkey_to_address(priv)
    mints = [("txid1", 0, 50), ("txid1", 1, 100)]
    ctxn = TokenTransaction("TOK", addr, mints, [], [priv])
    ctxn.write(sys.stdout.buffer)

    #inputs = [("txid2", 0), ("txid3", 1)]
    outputs = [30, 50]
    mtxn = TokenTransaction("TOK", addr, [], outputs,
                            [priv2, bitcoin.sha256("2")])
    mtxn.write(sys.stdout.buffer)
Example #33
0
def test_external_commitment_used(setup_podle):
    tries = jm_single().config.getint("POLICY", "taker_utxo_retries")
    #Don't want to wait too long, but must account for possible
    #throttling with !auth
    jm_single().maker_timeout_sec = 12
    amount = 50000000
    wallets = make_wallets(3,
                           wallet_structures=[[1, 0, 0, 0, 0], [1, 0, 0, 0, 0],
                                              [1, 1, 0, 0, 0]],
                           mean_amt=1)
    #the sendpayment bot uses the last wallet in the list
    wallet = wallets[2]['wallet']
    yigen_procs = []
    for i in range(2):
        ygp = local_command([python_cmd, yg_cmd,\
                             str(wallets[i]['seed'])], bg=True)
        time.sleep(2)  #give it a chance
        yigen_procs.append(ygp)

    #A significant delay is needed to wait for the yield generators to sync
    time.sleep(10)
    destaddr = btc.privkey_to_address(binascii.hexlify(os.urandom(32)),
                                      magicbyte=get_p2pk_vbyte())
    addr_valid, errormsg = validate_address(destaddr)
    assert addr_valid, "Invalid destination address: " + destaddr + \
           ", error message: " + errormsg

    log.debug('starting sendpayment')

    jm_single().bc_interface.sync_wallet(wallet)

    #Trigger PING LAG sending artificially
    joinmarket.irc.PING_INTERVAL = 3

    mcs = [IRCMessageChannel(c) for c in get_irc_mchannels()]
    mcc = MessageChannelCollection(mcs)
    #add all utxo in mixdepth 0 to 'used' list of commitments,
    utxos = wallet.get_utxos_by_mixdepth()[0]
    for u, addrval in utxos.iteritems():
        priv = wallet.get_key_from_addr(addrval['address'])
        podle = btc.PoDLE(u, priv)
        for i in range(tries):
            #loop because we want to use up all retries of this utxo
            commitment = podle.generate_podle(i)['commit']
            btc.update_commitments(commitment=commitment)

    #create a new utxo, notionally from an external source; to make life a little
    #easier we'll pay to another mixdepth, but this is OK because
    #taker does not source from here currently, only from the utxos chosen
    #for the transaction, not the whole wallet. So we can treat it as if
    #external (don't access its privkey).
    utxos = wallet.get_utxos_by_mixdepth()[1]
    ecs = {}
    for u, addrval in utxos.iteritems():
        priv = wallet.get_key_from_addr(addrval['address'])
        ecs[u] = {}
        ecs[u]['reveal'] = {}
        for j in range(tries):
            P, P2, s, e, commit = generate_single_podle_sig(
                binascii.unhexlify(priv), j)
            if 'P' not in ecs[u]:
                ecs[u]['P'] = P
            ecs[u]['reveal'][j] = {'P2': P2, 's': s, 'e': e}
    btc.update_commitments(external_to_add=ecs)
    #Now the conditions described above hold. We do a normal single
    #sendpayment.
    taker = sendpayment.SendPayment(mcc, wallet, destaddr, amount, 2, 5000, 3,
                                    0, True, weighted_order_choose)
    try:
        log.debug('starting message channels')
        mcc.run()
    finally:
        if any(yigen_procs):
            for ygp in yigen_procs:
                #NB *GENTLE* shutdown is essential for
                #test coverage reporting!
                ygp.send_signal(signal.SIGINT)
                ygp.wait()
    #wait for block generation
    time.sleep(5)
    received = jm_single().bc_interface.get_received_by_addr(
        [destaddr], None)['data'][0]['balance']
    assert received == amount, "sendpayment failed - coins not arrived, " +\
           "received: " + str(received)
    #Cleanup - remove the external commitments added
    btc.update_commitments(external_to_remove=ecs)
Example #34
0
def test_tumbler(setup_tumbler, num_ygs, wallet_structures, mean_amt, sdev_amt,
                 yg_excess):
    """Test of tumbler code, with yield generators in background.
    """
    log = get_log()
    options = Options()
    options.mixdepthsrc = 0
    options.mixdepthcount = 4
    options.minmakercount = 2
    options.makercountrange = (num_ygs, 0)
    options.maxcjfee = (0.01, 10000)
    options.txfee = 5000
    options.addrcount = 3
    options.donateamount = 0.5
    options.txcountparams = (4, 1)
    options.mintxcount = 1
    options.amountpower = 100
    options.timelambda = 0.2
    options.waittime = 10
    options.mincjamount = 1000000
    options.liquiditywait = 5
    options.maxbroadcasts = 4
    options.maxcreatetx = 9
    options = vars(options)

    wallets = make_wallets(num_ygs + 1,
                           wallet_structures=wallet_structures,
                           mean_amt=mean_amt,
                           sdev_amt=sdev_amt)
    #need to make sure that at least some ygs have substantially
    #more coins for last stages of sweep/spend in tumble:
    for i in range(num_ygs):
        jm_single().bc_interface.grab_coins(
            wallets[i]['wallet'].get_external_addr(0), yg_excess)
    #the tumbler bot uses the last wallet in the list
    wallet = wallets[num_ygs]['wallet']

    yigen_procs = []
    for i in range(num_ygs):
        ygp = local_command([python_cmd, yg_cmd,\
                             str(wallets[i]['seed'])], bg=True)
        time.sleep(2)  #give it a chance
        yigen_procs.append(ygp)

    #A significant delay is needed to wait for the yield generators to sync
    time.sleep(20)
    destaddrs = []
    for i in range(3):
        destaddr = btc.privkey_to_address(os.urandom(32),
                                          from_hex=False,
                                          magicbyte=get_p2pk_vbyte())
        addr_valid, errormsg = validate_address(destaddr)
        assert addr_valid, "Invalid destination address: " + destaddr + \
                   ", error message: " + errormsg
        destaddrs.append(destaddr)
    tx_list = tumbler.generate_tumbler_tx(destaddrs, options)
    pprint(tx_list)
    if options['addrcount'] + 1 > options['mixdepthcount']:
        print(
            'not enough mixing depths to pay to all destination addresses, '
            'increasing mixdepthcount')
        options['mixdepthcount'] = options['addrcount'] + 1

    tx_list2 = copy.deepcopy(tx_list)
    tx_dict = {}
    for tx in tx_list2:
        srcmixdepth = tx['srcmixdepth']
        tx.pop('srcmixdepth')
        if srcmixdepth not in tx_dict:
            tx_dict[srcmixdepth] = []
        tx_dict[srcmixdepth].append(tx)
    dbg_tx_list = []
    for srcmixdepth, txlist in tx_dict.iteritems():
        dbg_tx_list.append({'srcmixdepth': srcmixdepth, 'tx': txlist})
    log.debug('tumbler transaction list')
    pprint(dbg_tx_list)

    total_wait = sum([tx['wait'] for tx in tx_list])
    print('creates ' + str(len(tx_list)) + ' transactions in total')
    print('waits in total for ' + str(len(tx_list)) + ' blocks and ' +
          str(total_wait) + ' minutes')
    total_block_and_wait = len(tx_list) * 10 + total_wait
    print('estimated time taken ' + str(total_block_and_wait) +
          ' minutes or ' + str(round(total_block_and_wait / 60.0, 2)) +
          ' hours')

    jm_single().nickname = random_nick()

    log.debug('starting tumbler')

    jm_single().bc_interface.sync_wallet(wallet)
    jm_single().bc_interface.pushtx_failure_prob = 0.4
    mcs = [
        IRCMessageChannel(c,
                          jm_single().nickname) for c in get_irc_mchannels()
    ]
    mcc = MessageChannelCollection(mcs)
    tumbler_bot = tumbler.Tumbler(mcc, wallet, tx_list, options)
    try:
        log.debug('starting message channels')
        mcc.run()
    except:
        log.debug('CRASHING, DUMPING EVERYTHING')
        debug_dump_object(wallet,
                          ['addr_cache', 'keys', 'wallet_name', 'seed'])
        debug_dump_object(tumbler_bot)
        import traceback
        log.debug(traceback.format_exc())
    finally:
        if any(yigen_procs):
            for ygp in yigen_procs:
                #NB *GENTLE* shutdown is essential for
                #test coverage reporting!
                ygp.send_signal(signal.SIGINT)
                ygp.wait()
    #wait for block generation
    time.sleep(5)
    received = jm_single().bc_interface.get_received_by_addr(
        [destaddr], None)['data'][0]['balance']
    assert received != 0
    """TODO: figure out a sensible assertion check for the destination
Example #35
0
def test_tx_commitments_used(setup_podle, consume_tx, age_required, cmt_age):
    tries = jm_single().config.getint("POLICY","taker_utxo_retries")
    #remember and reset at the end
    taker_utxo_age = jm_single().config.getint("POLICY", "taker_utxo_age")
    jm_single().config.set("POLICY", "taker_utxo_age", str(age_required))
    #Don't want to wait too long, but must account for possible
    #throttling with !auth
    jm_single().maker_timeout_sec = 12
    amount = 0
    wallets = make_wallets(3,
                        wallet_structures=[[1,2,1,0,0],[1,2,0,0,0],[2,2,1,0,0]],
                        mean_amt=1)
    #the sendpayment bot uses the last wallet in the list
    wallet = wallets[2]['wallet']

    #make_wallets calls grab_coins which mines 1 block per individual payout,
    #so the age of the coins depends on where they are in that list. The sendpayment
    #is the last wallet in the list, and we choose the non-tx utxos which are in
    #mixdepth 1 and 2 (2 and 1 utxos in each respectively). We filter for those
    #that have sufficient age, so to get 1 which is old enough, it will be the oldest,
    #which will have an age of 2 + 1 (the first utxo spent to that wallet).
    #So if we need an age of 6, we need to mine 3 more blocks.
    blocks_reqd = cmt_age - 3
    jm_single().bc_interface.tick_forward_chain(blocks_reqd)
    yigen_procs = []
    for i in range(2):
        ygp = local_command([python_cmd, yg_cmd,\
                             str(wallets[i]['seed'])], bg=True)
        time.sleep(2)  #give it a chance
        yigen_procs.append(ygp)

    time.sleep(5)
    destaddr = btc.privkey_to_address(
            binascii.hexlify(os.urandom(32)),
            magicbyte=get_p2pk_vbyte())
    addr_valid, errormsg = validate_address(destaddr)
    assert addr_valid, "Invalid destination address: " + destaddr + \
           ", error message: " + errormsg

    log.debug('starting sendpayment')

    jm_single().bc_interface.sync_wallet(wallet)
    log.debug("Here is the whole wallet: \n" + str(wallet.unspent))
    #Trigger PING LAG sending artificially
    joinmarket.irc.PING_INTERVAL = 3

    mcs = [IRCMessageChannel(c) for c in get_irc_mchannels()]
    mcc = MessageChannelCollection(mcs)
    if consume_tx:
        #add all utxo in mixdepth 0 to 'used' list of commitments,
        utxos = wallet.get_utxos_by_mixdepth()[0]
        for u, addrval in utxos.iteritems():
            priv = wallet.get_key_from_addr(addrval['address'])
            podle = btc.PoDLE(u, priv)
            for i in range(tries):
                #loop because we want to use up all retries of this utxo
                commitment = podle.generate_podle(i)['commit']
                btc.update_commitments(commitment=commitment)

    #Now test a sendpayment from mixdepth 0 with all the depth 0 utxos
    #used up, so that the other utxos in the wallet get used.
    taker = sendpayment.SendPayment(mcc, wallet, destaddr, amount, 2,
                                    5000, 3, 0, True,
                                    weighted_order_choose)
    try:
        log.debug('starting message channels')
        mcc.run()
    finally:
        if any(yigen_procs):
            for ygp in yigen_procs:
                #NB *GENTLE* shutdown is essential for
                #test coverage reporting!
                ygp.send_signal(signal.SIGINT)
                ygp.wait()
    #wait for block generation
    time.sleep(5)
    received = jm_single().bc_interface.get_received_by_addr(
        [destaddr], None)['data'][0]['balance']
    jm_single().config.set("POLICY", "taker_utxo_age", str(taker_utxo_age))
    if cmt_age < age_required:
        assert received == 0, "Coins arrived but shouldn't"
    else:
        assert received != 0, "sendpayment failed - coins not arrived, " +\
           "received: " + str(received)
Example #36
0
def test_sendpayment(setup_regtest, num_ygs, wallet_structures, mean_amt,
                     mixdepth, sending_amt):
    """Test of sendpayment code, with yield generators in background.
    """
    log = get_log()
    makercount = num_ygs
    answeryes = True
    txfee = 5000
    waittime = 5
    amount = sending_amt
    wallets = make_wallets(makercount + 1,
                           wallet_structures=wallet_structures,
                           mean_amt=mean_amt)
    #the sendpayment bot uses the last wallet in the list
    wallet = wallets[makercount]['wallet']

    yigen_procs = []
    for i in range(makercount):
        ygp = local_command([python_cmd, yg_cmd,\
                             str(wallets[i]['seed'])], bg=True)
        time.sleep(2)  #give it a chance
        yigen_procs.append(ygp)

    #A significant delay is needed to wait for the yield generators to sync
    time.sleep(20)
    if btc.secp_present:
        destaddr = btc.privkey_to_address(
            os.urandom(32),
            from_hex=False,
            magicbyte=get_p2pk_vbyte())
    else:
        destaddr = btc.privkey_to_address(
            os.urandom(32),
            magicbyte=get_p2pk_vbyte())

    addr_valid, errormsg = validate_address(destaddr)
    assert addr_valid, "Invalid destination address: " + destaddr + \
           ", error message: " + errormsg

    #TODO paramatetrize this as a test variable
    chooseOrdersFunc = weighted_order_choose

    jm_single().nickname = random_nick()

    log.debug('starting sendpayment')

    jm_single().bc_interface.sync_wallet(wallet)
    
    #Trigger PING LAG sending artificially
    joinmarket.irc.PING_INTERVAL = 3
    
    irc = IRCMessageChannel(jm_single().nickname)
    taker = sendpayment.SendPayment(irc, wallet, destaddr, amount, makercount,
                                    txfee, waittime, mixdepth, answeryes,
                                    chooseOrdersFunc)
    try:
        log.debug('starting irc')
        irc.run()
    finally:
        if any(yigen_procs):
            for ygp in yigen_procs:
                #NB *GENTLE* shutdown is essential for
                #test coverage reporting!
                ygp.send_signal(signal.SIGINT)
                ygp.wait()
    #wait for block generation
    time.sleep(5)
    received = jm_single().bc_interface.get_received_by_addr(
        [destaddr], None)['data'][0]['balance']
    if amount != 0:
        assert received == amount, "sendpayment failed - coins not arrived, " +\
           "received: " + str(received)
    #TODO: how to check success for sweep case?
    else:
        assert received != 0
Example #37
0
def test_failed_sendpayment(setup_podle, num_ygs, wallet_structures, mean_amt,
                     mixdepth, sending_amt):
    """Test of initiating joins, but failing to complete,
    to see commitment usage. YGs in background as per test_regtest.
    Use sweeps to avoid recover_from_nonrespondants without intruding
    into sendpayment code.
    """
    makercount = num_ygs
    answeryes = True
    txfee = 5000
    waittime = 3
    #Don't want to wait too long, but must account for possible
    #throttling with !auth
    jm_single().maker_timeout_sec = 12
    amount = 0
    wallets = make_wallets(makercount + 1,
                           wallet_structures=wallet_structures,
                           mean_amt=mean_amt)
    #the sendpayment bot uses the last wallet in the list
    wallet = wallets[makercount]['wallet']

    yigen_procs = []
    for i in range(makercount):
        ygp = local_command([python_cmd, yg_cmd,\
                             str(wallets[i]['seed'])], bg=True)
        time.sleep(2)  #give it a chance
        yigen_procs.append(ygp)

    #A significant delay is needed to wait for the yield generators to sync
    time.sleep(20)
    destaddr = btc.privkey_to_address(
            os.urandom(32),
            from_hex=False,
            magicbyte=get_p2pk_vbyte())

    addr_valid, errormsg = validate_address(destaddr)
    assert addr_valid, "Invalid destination address: " + destaddr + \
           ", error message: " + errormsg

    #TODO paramatetrize this as a test variable
    chooseOrdersFunc = weighted_order_choose

    log.debug('starting sendpayment')

    jm_single().bc_interface.sync_wallet(wallet)
    
    #Trigger PING LAG sending artificially
    joinmarket.irc.PING_INTERVAL = 3
    
    mcs = [IRCMessageChannel(c) for c in get_irc_mchannels()]
    mcc = MessageChannelCollection(mcs)

    #Allow taker more retries than makers allow, so as to trigger
    #blacklist failure case
    jm_single().config.set("POLICY", "taker_utxo_retries", "4")
    #override ioauth receipt with a dummy do-nothing callback:
    def on_ioauth(*args):
        log.debug("Taker received: " + ','.join([str(x) for x in args]))

    class DummySendPayment(sendpayment.SendPayment):
        def __init__(self, msgchan, wallet, destaddr, amount, makercount, txfee,
                 waittime, mixdepth, answeryes, chooseOrdersFunc, on_ioauth):
            self.on_ioauth = on_ioauth
            self.podle_fails = 0
            self.podle_allowed_fails = 3 #arbitrary; but do it more than once
            self.retries = 0
            super(DummySendPayment, self).__init__(msgchan, wallet,
                    destaddr, amount, makercount, txfee, waittime,
                    mixdepth, answeryes, chooseOrdersFunc)
        def on_welcome(self):
            Taker.on_welcome(self)
            DummyPaymentThread(self).start()        

    class DummyPaymentThread(sendpayment.PaymentThread):
        def finishcallback(self, coinjointx):
            #Don't ignore makers and just re-start
            self.taker.retries += 1
            if self.taker.podle_fails == self.taker.podle_allowed_fails:
                self.taker.msgchan.shutdown()
                return
            self.create_tx()
        def create_tx(self):
            try:
                super(DummyPaymentThread, self).create_tx()
            except btc.PoDLEError:
                log.debug("Got one commit failure, continuing")
                self.taker.podle_fails += 1

    taker = DummySendPayment(mcc, wallet, destaddr, amount, makercount,
                                    txfee, waittime, mixdepth, answeryes,
                                    chooseOrdersFunc, on_ioauth)
    try:
        log.debug('starting message channels')
        mcc.run()
    finally:
        if any(yigen_procs):
            for ygp in yigen_procs:
                #NB *GENTLE* shutdown is essential for
                #test coverage reporting!
                ygp.send_signal(signal.SIGINT)
                ygp.wait()
    #We should have been able to try (tur -1) + podle_allowed_fails times
    assert taker.retries == jm_single().config.getint(
        "POLICY", "taker_utxo_retries") + taker.podle_allowed_fails
    #wait for block generation
    time.sleep(2)
    received = jm_single().bc_interface.get_received_by_addr(
        [destaddr], None)['data'][0]['balance']
    #Sanity check no transaction succeeded
    assert received == 0
Example #38
0
def test_external_commitment_used(setup_podle):
    tries = jm_single().config.getint("POLICY","taker_utxo_retries")
    #Don't want to wait too long, but must account for possible
    #throttling with !auth
    jm_single().maker_timeout_sec = 12
    amount = 50000000
    wallets = make_wallets(3,
                        wallet_structures=[[1,0,0,0,0],[1,0,0,0,0],[1,1,0,0,0]],
                        mean_amt=1)
    #the sendpayment bot uses the last wallet in the list
    wallet = wallets[2]['wallet']
    yigen_procs = []
    for i in range(2):
        ygp = local_command([python_cmd, yg_cmd,\
                             str(wallets[i]['seed'])], bg=True)
        time.sleep(2)  #give it a chance
        yigen_procs.append(ygp)

    #A significant delay is needed to wait for the yield generators to sync
    time.sleep(10)
    destaddr = btc.privkey_to_address(
            binascii.hexlify(os.urandom(32)),
            magicbyte=get_p2pk_vbyte())
    addr_valid, errormsg = validate_address(destaddr)
    assert addr_valid, "Invalid destination address: " + destaddr + \
           ", error message: " + errormsg

    log.debug('starting sendpayment')

    jm_single().bc_interface.sync_wallet(wallet)
    
    #Trigger PING LAG sending artificially
    joinmarket.irc.PING_INTERVAL = 3
    
    mcs = [IRCMessageChannel(c) for c in get_irc_mchannels()]
    mcc = MessageChannelCollection(mcs)
    #add all utxo in mixdepth 0 to 'used' list of commitments,
    utxos = wallet.get_utxos_by_mixdepth()[0]
    for u, addrval in utxos.iteritems():
        priv = wallet.get_key_from_addr(addrval['address'])
        podle = btc.PoDLE(u, priv)
        for i in range(tries):
            #loop because we want to use up all retries of this utxo
            commitment = podle.generate_podle(i)['commit']
            btc.update_commitments(commitment=commitment)

    #create a new utxo, notionally from an external source; to make life a little
    #easier we'll pay to another mixdepth, but this is OK because
    #taker does not source from here currently, only from the utxos chosen
    #for the transaction, not the whole wallet. So we can treat it as if
    #external (don't access its privkey).
    utxos = wallet.get_utxos_by_mixdepth()[1]
    ecs = {}
    for u, addrval in utxos.iteritems():
        priv = wallet.get_key_from_addr(addrval['address'])
        ecs[u] = {}
        ecs[u]['reveal']={}
        for j in range(tries):
            P, P2, s, e, commit = generate_single_podle_sig(
                binascii.unhexlify(priv), j)
            if 'P' not in ecs[u]:
                ecs[u]['P'] = P
            ecs[u]['reveal'][j] = {'P2':P2, 's':s, 'e':e}
    btc.update_commitments(external_to_add=ecs)
    #Now the conditions described above hold. We do a normal single
    #sendpayment.
    taker = sendpayment.SendPayment(mcc, wallet, destaddr, amount, 2,
                                    5000, 3, 0, True,
                                    weighted_order_choose)
    try:
        log.debug('starting message channels')
        mcc.run()
    finally:
        if any(yigen_procs):
            for ygp in yigen_procs:
                #NB *GENTLE* shutdown is essential for
                #test coverage reporting!
                ygp.send_signal(signal.SIGINT)
                ygp.wait()
    #wait for block generation
    time.sleep(5)
    received = jm_single().bc_interface.get_received_by_addr(
        [destaddr], None)['data'][0]['balance']
    assert received == amount, "sendpayment failed - coins not arrived, " +\
           "received: " + str(received)
    #Cleanup - remove the external commitments added
    btc.update_commitments(external_to_remove=ecs)
Example #39
0
def test_failed_sendpayment(setup_podle, num_ygs, wallet_structures, mean_amt,
                            mixdepth, sending_amt):
    """Test of initiating joins, but failing to complete,
    to see commitment usage. YGs in background as per test_regtest.
    Use sweeps to avoid recover_from_nonrespondants without intruding
    into sendpayment code.
    """
    makercount = num_ygs
    answeryes = True
    txfee = 5000
    waittime = 3
    #Don't want to wait too long, but must account for possible
    #throttling with !auth
    jm_single().maker_timeout_sec = 12
    amount = 0
    wallets = make_wallets(makercount + 1,
                           wallet_structures=wallet_structures,
                           mean_amt=mean_amt)
    #the sendpayment bot uses the last wallet in the list
    wallet = wallets[makercount]['wallet']

    yigen_procs = []
    for i in range(makercount):
        ygp = local_command([python_cmd, yg_cmd,\
                             str(wallets[i]['seed'])], bg=True)
        time.sleep(2)  #give it a chance
        yigen_procs.append(ygp)

    #A significant delay is needed to wait for the yield generators to sync
    time.sleep(20)
    destaddr = btc.privkey_to_address(os.urandom(32),
                                      from_hex=False,
                                      magicbyte=get_p2pk_vbyte())

    addr_valid, errormsg = validate_address(destaddr)
    assert addr_valid, "Invalid destination address: " + destaddr + \
           ", error message: " + errormsg

    #TODO paramatetrize this as a test variable
    chooseOrdersFunc = weighted_order_choose

    log.debug('starting sendpayment')

    jm_single().bc_interface.sync_wallet(wallet)

    #Trigger PING LAG sending artificially
    joinmarket.irc.PING_INTERVAL = 3

    mcs = [IRCMessageChannel(c) for c in get_irc_mchannels()]
    mcc = MessageChannelCollection(mcs)

    #Allow taker more retries than makers allow, so as to trigger
    #blacklist failure case
    jm_single().config.set("POLICY", "taker_utxo_retries", "4")

    #override ioauth receipt with a dummy do-nothing callback:
    def on_ioauth(*args):
        log.debug("Taker received: " + ','.join([str(x) for x in args]))

    class DummySendPayment(sendpayment.SendPayment):
        def __init__(self, msgchan, wallet, destaddr, amount, makercount,
                     txfee, waittime, mixdepth, answeryes, chooseOrdersFunc,
                     on_ioauth):
            self.on_ioauth = on_ioauth
            self.podle_fails = 0
            self.podle_allowed_fails = 3  #arbitrary; but do it more than once
            self.retries = 0
            super(DummySendPayment,
                  self).__init__(msgchan, wallet, destaddr, amount, makercount,
                                 txfee, waittime, mixdepth, answeryes,
                                 chooseOrdersFunc)

        def on_welcome(self):
            Taker.on_welcome(self)
            DummyPaymentThread(self).start()

    class DummyPaymentThread(sendpayment.PaymentThread):
        def finishcallback(self, coinjointx):
            #Don't ignore makers and just re-start
            self.taker.retries += 1
            if self.taker.podle_fails == self.taker.podle_allowed_fails:
                self.taker.msgchan.shutdown()
                return
            self.create_tx()

        def create_tx(self):
            try:
                super(DummyPaymentThread, self).create_tx()
            except btc.PoDLEError:
                log.debug("Got one commit failure, continuing")
                self.taker.podle_fails += 1

    taker = DummySendPayment(mcc, wallet, destaddr, amount, makercount, txfee,
                             waittime, mixdepth, answeryes, chooseOrdersFunc,
                             on_ioauth)
    try:
        log.debug('starting message channels')
        mcc.run()
    finally:
        if any(yigen_procs):
            for ygp in yigen_procs:
                #NB *GENTLE* shutdown is essential for
                #test coverage reporting!
                ygp.send_signal(signal.SIGINT)
                ygp.wait()
    #We should have been able to try (tur -1) + podle_allowed_fails times
    assert taker.retries == jm_single().config.getint(
        "POLICY", "taker_utxo_retries") + taker.podle_allowed_fails
    #wait for block generation
    time.sleep(2)
    received = jm_single().bc_interface.get_received_by_addr(
        [destaddr], None)['data'][0]['balance']
    #Sanity check no transaction succeeded
    assert received == 0
Example #40
0
def wif_to_address(crypto, wif):
    try:
        return privkey_to_address(wif,
                                  crypto_data[crypto]['address_version_byte'])
    except KeyError:
        raise CurrencyNotSupported("Currency not yet supported")
#Vanity miner (searching for an address containing a certain string)
import bitcoin
import os
import codecs

search = '1kid'

while True:
    secret = os.urandom(32)
    address = bitcoin.privkey_to_address(secret)
    if search in address:
        break

print('Found vanity address! ', address)
print('Secret: ', codecs.encode(secret, 'hex').decode())
Example #42
0
def main():
    args = parse_args()

    # Set DEBUG variable for testing purposes (changing styling)
    # If true, prints the SCAD to the terminal and then breaks after first generation
    DEBUG = False

    # Generate the addresses
    if args.copies < 1:
        print("Please enter a valid number of copies (-co flag), and try again.")
        sys.exit()
    else: # Use an else statement here just in case we add the option to import a CSV file with the keys (generated somewhere else)
        walletDataList = []
        for i in range(args.copies):
            thisData = {}

            # Generate the addresses with keys
            thisData["privateKey"] = bitcoin.main.random_key() # Secure: uses random library, time library and proprietary function
            thisData["wif"] = bitcoin.encode_privkey(thisData["privateKey"], "wif", args.versionByte)
            thisData["address"] = bitcoin.privkey_to_address(thisData["privateKey"], args.versionByte)

            # Generate the QR codes
            if args.errorCorrection.upper() not in ["L","M","Q","H"]:
                print("Please select a valid QR Error Correction value (L, M, Q, or H).")
                sys.exit()
            thisData["wifQR"] = qrTools.getQRArray(thisData["wif"], args.errorCorrection.upper())
            thisData["addressQR"] = qrTools.getQRArray(thisData["address"], args.errorCorrection.upper())

            # Reverse them or else they appear backwards (unknown reason)
            thisData["wifQR"] = list(reversed(thisData["wifQR"]))
            thisData["addressQR"] = list(reversed(thisData["addressQR"]))

            # Append ALL the wallet information, just in case we want to do something with it later
            walletDataList.append(thisData) 

    # Validate other args and set some constants
    walletWidth = args.walletWidth
    walletHeight = args.walletHeight
    if args.layoutStyle == 1 or args.layoutStyle == 2 or args.layoutStyle == 3:
        walletLength = walletWidth*1.6 # Approximately the same ratio as a credit card
    else:
        print("Please choose a valid layout style option.")
        sys.exit()
    if args.blackOffset < -90.0:
        print("Please ensure that --black-offset (-bo flag) is set correctly, and is greater than -90.")
        sys.exit()
    textDepth = (args.blackOffset/100) * walletHeight

    # Check the openscad command
    scadExe = args.scadExe
    if args.scadExe == "openscad" and not distutils.spawn.find_executable("openscad"):
        if os.path.isfile("/Applications/OpenSCAD.app/Contents/MacOS/OpenSCAD"):
            print("Info: OpenSCAD found in Applications folder on Mac")
            scadExe = "/Applications/OpenSCAD.app/Contents/MacOS/OpenSCAD"
        elif os.path.isfile("%PROGRAMFILES%\OpenSCAD\openscad.exe"):
            print("Info: OpenSCAD found in Program Files on Windows")
            scadExe = "%PROGRAMFILES%\OpenSCAD\openscad.exe"
        elif os.path.isfile("%PROGRAMFILES(x86)%\OpenSCAD\openscad.exe"):
            print("Info: OpenSCAD found in Program Files (x86) on Windows")
            scadExe = "%PROGRAMFILES(x86)%\OpenSCAD\openscad.exe"
    if not distutils.spawn.find_executable(scadExe):
        print("Please install OpenSCAD or specify the location of it with --openscad-exe.")
        sys.exit()

    # Set the master SCAD variable
    masterSCAD = "// SCAD Code Generated By 3DGen.py - 3D Wallet Generator\n\n" # The beginning of the wallet are identical
    scadOutputs = [] # Generated from loop for each wallet (different addresses)

    # Include some modules at the beginning
    masterSCAD += "// Import some modules\n"
    masterSCAD += """
    $fn=100;
    module createMeniscus(h,radius)difference(){translate([radius/2+0.1,radius/2+0.1,0]){cube([radius+0.2,radius+0.1,h+0.2],center=true);}cylinder(h=h+0.2,r=radius,center=true);}
    module roundCornersCube(x,y,z)translate([x/2,y/2,z/2]){difference(){r=((x+y)/2)*0.052;cube([x,y,z],center=true);translate([x/2-r,y/2-r]){rotate(0){createMeniscus(z,r);}}translate([-x/2+r,y/2-r]){rotate(90){createMeniscus(z,r);}}translate([-x/2+r,-y/2+r]){rotate(180){createMeniscus(z,r);}}translate([x/2-r,-y/2+r]){rotate(270){createMeniscus(z,r);}}}}
    """ # The rounding corners modules for creating a rounded rectangle

    masterSCAD += "\n"

    # Draw the main prism
    if args.roundCorners:
        mainCube = "roundCornersCube(" + str(walletLength) + "," + str(walletWidth) + "," + str(walletHeight) + ");"
    else:
        mainCube = "cube([" + str(walletLength) + "," + str(walletWidth) + "," + str(walletHeight) + "]);"
    mainCube += "\n\n"

    # Init a variable to keep all the additive/subtractive parts
    finalParts = []

    # Init variables to keep the CSV output data in
    addressOut = []
    privkeyOut = []
    APOut = []
    PAOut = []

    # Set a counter for naming the files
    filenameCounter = 1

    # Break into the loop for each wallet
    for data in walletDataList:
        # 'data' = wif, address, wifQR, addressQR

        # Generate the texts
        addressLine1 = data["address"][:math.ceil(len(data["address"])/2.0)]
        addressLine2 = data["address"][math.ceil(len(data["address"])/2.0):]
        wifLine1 = data["wif"][:17]
        wifLine2 = data["wif"][17:34]
        wifLine3 = data["wif"][34:]

        addressLine1Dots = textGen.getArray(addressLine1)
        addressLine2Dots = textGen.getArray(addressLine2)
        privkeyLine1Dots = textGen.getArray(wifLine1)
        privkeyLine2Dots = textGen.getArray(wifLine2)
        privkeyLine3Dots = textGen.getArray(wifLine3)

        bigTitle = textGen.getArray("3D " + args.coinTitle + " Wallet")
        addressTitle = textGen.getArray("Address")
        privkeyTitle = textGen.getArray("Private Key")

        # Create the big title union so that it can be sized and moved
        bigTitleUnion = ""
        for rowIndex in range(len(bigTitle)):
            row = bigTitle[rowIndex]
            for colIndex in range(len(row)):
                if row[colIndex] == '1':
                    translateHeight = walletHeight if textDepth>0 else walletHeight+textDepth
                    bigTitleUnion += "translate([colIndex,rowIndex,translateHeight]){cube([1,1,textDepth]);}".replace('colIndex',str(colIndex)).replace('rowIndex',str(rowIndex)).replace('textDepth',str(abs(textDepth))).replace('translateHeight',str(translateHeight))

        # Translate the title to where it goes
        bigTitleFinal = "translate([(1/17)*length,(14/17)*width,0]){resize([(15/17)*length,0,0],auto=[true,true,false]){bigTitleUnion}}".replace('length',str(walletLength)).replace('width',str(walletWidth)).replace('bigTitleUnion',bigTitleUnion)
        finalParts.append(bigTitleFinal+"\n\n")
        if args.layoutStyle == 1:
            # Need to copy it on to the backside as well - rotate then move it, and then create a union of the two titles (front and back)
            bigTitle2 = "translate([length,0,height]){rotate(180,v=[0,1,0]){bigTitleFinal}}".replace('length',str(walletLength)).replace('height',str(walletHeight)).replace('bigTitleFinal',bigTitleFinal).replace('translateHeight',str(translateHeight))
            finalParts.append(bigTitle2+"\n\n")
        
        # Draw the word "Address" on the front, and draw on the actual address
        if args.layoutStyle == 1 or args.layoutStyle == 3:
            # Draw the address on the front
            addressParts = []

            # Create the address title union and size/move it
            addressTitleUnion = "union(){"
            for rowIndex in range(len(addressTitle)):
                row = addressTitle[rowIndex]
                for colIndex in range(len(row)):
                    if row[colIndex] == '1':
                        translateHeight = walletHeight if textDepth>0 else walletHeight+textDepth
                        addressTitleUnion += "translate([colIndex,rowIndex,translateHeight]){cube([1,1,textDepth]);}".replace('colIndex',str(colIndex)).replace('rowIndex',str(rowIndex)).replace('textDepth',str(abs(textDepth))).replace('translateHeight',str(translateHeight))
            addressTitleUnion += "}"
            addressTitleFinal = "translate([(10/17)*length,(6/11)*width,0]){resize([0,(4/55)*width,0],auto=[true,true,false]){addressTitleUnion}}\n\n".replace('length',str(walletLength)).replace('width',str(walletWidth)).replace('addressTitleUnion',addressTitleUnion)
            addressParts.append(addressTitleFinal)

            # Create the first line of the address
            addressLine1Union = "union(){"
            for rowIndex in range(len(addressLine1Dots)):
                row = addressLine1Dots[rowIndex]
                for colIndex in range(len(row)):
                    if row[colIndex] == '1':
                        translateHeight = walletHeight if textDepth>0 else walletHeight+textDepth
                        addressLine1Union += "translate([colIndex,rowIndex,translateHeight]){cube([1,1,textDepth]);}".replace('colIndex',str(colIndex)).replace('rowIndex',str(rowIndex)).replace('textDepth',str(abs(textDepth))).replace('translateHeight',str(translateHeight))
            addressLine1Union += "}"
            addressLine1Final = "translate([(8.2/17)*length,(5/11)*width,0]){resize([0,(3/55)*width,0],auto=[true,true,false]){addressLine1Union}}\n\n".replace('length',str(walletLength)).replace('width',str(walletWidth)).replace('addressLine1Union',addressLine1Union)
            addressParts.append(addressLine1Final)

            # Create the second line of the address
            addressLine2Union = "union(){"
            for rowIndex in range(len(addressLine2Dots)):
                row = addressLine2Dots[rowIndex]
                for colIndex in range(len(row)):
                    if row[colIndex] == '1':
                        translateHeight = walletHeight if textDepth>0 else walletHeight+textDepth
                        addressLine2Union += "translate([colIndex,rowIndex,translateHeight]){cube([1,1,textDepth]);}".replace('colIndex',str(colIndex)).replace('rowIndex',str(rowIndex)).replace('textDepth',str(abs(textDepth))).replace('translateHeight',str(translateHeight))
            addressLine2Union += "}"
            addressLine2Final = "translate([(8.2/17)*length,(4.1/11)*width,0]){resize([0,(3/55)*width,0],auto=[true,true,false]){addressLine2Union}}\n\n".replace('length',str(walletLength)).replace('width',str(walletWidth)).replace('addressLine2Union',addressLine2Union)
            addressParts.append(addressLine2Final)

            # Create the QR code
            addressQRUnion = "union(){"
            for rowIndex in range(len(data["addressQR"])):
                row = data["addressQR"][rowIndex]
                for colIndex in range(len(row)):
                    if row[colIndex] == 0:
                        translateHeight = walletHeight if textDepth>0 else walletHeight+textDepth
                        addressQRUnion += "translate([colIndex,rowIndex,translateHeight]){cube([1,1,textDepth]);}".replace('colIndex',str(colIndex)).replace('rowIndex',str(rowIndex)).replace('textDepth',str(abs(textDepth))).replace('translateHeight',str(translateHeight))
            addressQRUnion += "}"
            addressQRFinal = "translate([(0.6/17)*length,(0.6/11)*width,0]){resize([0,(8/12)*width,0],auto=[true,true,false]){addressQRUnion}}\n\n".replace('length',str(walletLength)).replace('width',str(walletWidth)).replace('addressQRUnion',addressQRUnion)
            addressParts.append(addressQRFinal)
            
            finalParts.extend(addressParts)

        # Draw all the things having to do with the private key
        if args.layoutStyle == 1 or args.layoutStyle == 2:
            privkeyParts = []

            # Create the privkey title union and size/move it
            privkeyTitleUnion = "union(){"
            for rowIndex in range(len(privkeyTitle)):
                row = privkeyTitle[rowIndex]
                for colIndex in range(len(row)):
                    if row[colIndex] == '1':
                        translateHeight = walletHeight if textDepth>0 else walletHeight+textDepth
                        privkeyTitleUnion += "translate([colIndex,rowIndex,translateHeight]){cube([1,1,textDepth]);}".replace('colIndex',str(colIndex)).replace('rowIndex',str(rowIndex)).replace('textDepth',str(abs(textDepth))).replace('translateHeight',str(translateHeight))
            privkeyTitleUnion += "}"
            privkeyTitleFinal = "translate([(8.7/17)*length,(7/11)*width,0]){resize([0,(4/55)*width,0],auto=[true,true,false]){privkeyTitleUnion}}\n\n".replace('length',str(walletLength)).replace('width',str(walletWidth)).replace('privkeyTitleUnion',privkeyTitleUnion)
            privkeyParts.append(privkeyTitleFinal)

            # Create the first line of the privkey
            privkeyLine1Union = "union(){"
            for rowIndex in range(len(privkeyLine1Dots)):
                row = privkeyLine1Dots[rowIndex]
                for colIndex in range(len(row)):
                    if row[colIndex] == '1':
                        translateHeight = walletHeight if textDepth>0 else walletHeight+textDepth
                        privkeyLine1Union += "translate([colIndex,rowIndex,translateHeight]){cube([1,1,textDepth]);}".replace('colIndex',str(colIndex)).replace('rowIndex',str(rowIndex)).replace('textDepth',str(abs(textDepth))).replace('translateHeight',str(translateHeight))
            privkeyLine1Union += "}"
            privkeyLine1Final = "translate([(8.2/17)*length,(6/11)*width,0]){resize([0,(3/55)*width,0],auto=[true,true,false]){privkeyLine1Union}}\n\n".replace('length',str(walletLength)).replace('width',str(walletWidth)).replace('privkeyLine1Union',privkeyLine1Union)
            privkeyParts.append(privkeyLine1Final)

            # Create the second line of the privkey
            privkeyLine2Union = "union(){"
            for rowIndex in range(len(privkeyLine2Dots)):
                row = privkeyLine2Dots[rowIndex]
                for colIndex in range(len(row)):
                    if row[colIndex] == '1':
                        translateHeight = walletHeight if textDepth>0 else walletHeight+textDepth
                        privkeyLine2Union += "translate([colIndex,rowIndex,translateHeight]){cube([1,1,textDepth]);}".replace('colIndex',str(colIndex)).replace('rowIndex',str(rowIndex)).replace('textDepth',str(abs(textDepth))).replace('translateHeight',str(translateHeight))
            privkeyLine2Union += "}"
            privkeyLine2Final = "translate([(8.2/17)*length,(5.1/11)*width,0]){resize([0,(3/55)*width,0],auto=[true,true,false]){privkeyLine2Union}}\n\n".replace('length',str(walletLength)).replace('width',str(walletWidth)).replace('privkeyLine2Union',privkeyLine2Union)
            privkeyParts.append(privkeyLine2Final)

            # Create the third line of the privkey
            privkeyLine3Union = "union(){"
            for rowIndex in range(len(privkeyLine3Dots)):
                row = privkeyLine3Dots[rowIndex]
                for colIndex in range(len(row)):
                    if row[colIndex] == '1':
                        translateHeight = walletHeight if textDepth>0 else walletHeight+textDepth
                        privkeyLine3Union += "translate([colIndex,rowIndex,translateHeight]){cube([1,1,textDepth]);}".replace('colIndex',str(colIndex)).replace('rowIndex',str(rowIndex)).replace('textDepth',str(abs(textDepth))).replace('translateHeight',str(translateHeight))
            privkeyLine3Union += "}"
            privkeyLine3Final = "translate([(8.2/17)*length,(4.2/11)*width,0]){resize([0,(3/55)*width,0],auto=[true,true,false]){privkeyLine3Union}}\n\n".replace('length',str(walletLength)).replace('width',str(walletWidth)).replace('privkeyLine3Union',privkeyLine3Union)
            privkeyParts.append(privkeyLine3Final)

            # Create the QR code
            privkeyQRUnion = "union(){"
            for rowIndex in range(len(data["wifQR"])):
                row = data["wifQR"][rowIndex]
                for colIndex in range(len(row)):
                    if row[colIndex] == 0:
                        translateHeight = walletHeight if textDepth>0 else walletHeight+textDepth
                        privkeyQRUnion += "translate([colIndex,rowIndex,translateHeight]){cube([1,1,textDepth]);}".replace('colIndex',str(colIndex)).replace('rowIndex',str(rowIndex)).replace('textDepth',str(abs(textDepth))).replace('translateHeight',str(translateHeight))
            privkeyQRUnion += "}"
            privkeyQRFinal = "translate([(0.6/17)*length,(0.6/11)*width,0]){resize([0,(8/12)*width,0],auto=[true,true,false]){privkeyQRUnion}}\n\n".replace('length',str(walletLength)).replace('width',str(walletWidth)).replace('privkeyQRUnion',privkeyQRUnion)
            privkeyParts.append(privkeyQRFinal)

            if args.layoutStyle == 2:
                # Just add it all to the finalParts
                finalParts.extend(privkeyParts)
            elif args.layoutStyle == 1:
                # Rotate it all and then add it to the finalParts
                privkeyPartsNew = []
                for part in privkeyParts:
                    privkeyPartsNew.append("translate([length,0,height]){rotate(180,v=[0,1,0]){part}}".replace('length',str(walletLength)).replace('height',str(walletHeight)).replace('part',part).replace('translateHeight',str(translateHeight)))
                finalParts.extend(privkeyPartsNew)

        # Put it all together
        finalSCAD = masterSCAD
        if textDepth < 0:
            finalSCAD += "difference() {\n\n"
        else:
            finalSCAD += "union() {\n\n"
        finalSCAD += mainCube
        finalSCAD += "".join(finalParts)
        finalSCAD += "}"

        if DEBUG:
            print(finalSCAD)
            break

        if args.outputSCADFolder:
            try:
                os.makedirs(args.outputSCADFolder)
            except FileExistsError:
                pass
            scadOutFile = open(args.outputSCADFolder + '/wallet' + str(filenameCounter) + '.scad','w')
            scadOutFile.write(finalSCAD)
            scadOutFile.close()

        # Log some info
        print("Status: Done generating data for wallet #" + str(filenameCounter) + "...Starting generating STL file")

        if args.outputSTLFolder:
            try:
                os.makedirs(args.outputSTLFolder)
            except FileExistsError:
                pass
            scadOutFile = open('temp.scad','w')
            scadOutFile.write(finalSCAD)
            scadOutFile.close()
            os.system(scadExe + " -o " + args.outputSTLFolder + "/wallet" + str(filenameCounter) + ".stl temp.scad")
            try:
                os.remove('temp.scad')
            except:
                pass
        else:
            print("Please provide a folder to output the STL files.")

        # Update the CSV file variables
        addressOut.append(data["address"])
        privkeyOut.append(data["wif"])
        APOut.append(data["address"] + "," + data["wif"])
        PAOut.append(data["wif"] + "," + data["address"])

        # Print some more stats
        print("Status: Done generating STL file (" + str(round(filenameCounter/args.copies*100)) + "% done)")

        filenameCounter += 1

    # Export the CSV files
    if args.exportAddressCSV:
        csvFile = open(args.exportAddressCSV,'a')
        csvFile.write(','.join(addressOut))
        csvFile.close()

    if args.exportPrivkeyCSV:
        csvFile = open(args.exportPrivkeyCSV,'a')
        csvFile.write(','.join(privkeyOut))
        csvFile.close()

    if args.exportAPCSV:
        csvFile = open(args.exportAPCSV,'a')
        csvFile.write('\n'.join(exportAPCSV))
        csvFile.close()

    if args.exportPACSV:
        csvFile = open(args.exportPACSV,'a')
        csvFile.write('\n'.join(exportPACSV))
        csvFile.close()
Example #43
0
def test_tumbler(setup_tumbler, num_ygs, wallet_structures, mean_amt, sdev_amt,
                 yg_excess):
    """Test of tumbler code, with yield generators in background.
    """
    log = get_log()
    options = Options()
    options.mixdepthsrc = 0
    options.mixdepthcount = 4
    options.minmakercount = 2
    options.makercountrange = (num_ygs, 0)
    options.maxcjfee = (0.01, 10000)
    options.txfee = 5000
    options.addrcount = 3
    options.donateamount = 0.5
    options.txcountparams = (4, 1)
    options.mintxcount = 1
    options.amountpower = 100
    options.timelambda = 0.2
    options.waittime = 10
    options.mincjamount = 1000000
    options.liquiditywait = 5
    options.maxbroadcasts = 4
    options.maxcreatetx = 9
    options = vars(options)

    wallets = make_wallets(num_ygs + 1,
                           wallet_structures=wallet_structures,
                           mean_amt=mean_amt, sdev_amt=sdev_amt)
    #need to make sure that at least some ygs have substantially
    #more coins for last stages of sweep/spend in tumble:
    for i in range(num_ygs):
        jm_single().bc_interface.grab_coins(
                            wallets[i]['wallet'].get_external_addr(0), yg_excess)    
    #the tumbler bot uses the last wallet in the list
    wallet = wallets[num_ygs]['wallet']

    yigen_procs = []
    for i in range(num_ygs):
        ygp = local_command([python_cmd, yg_cmd,\
                             str(wallets[i]['seed'])], bg=True)
        time.sleep(2)  #give it a chance
        yigen_procs.append(ygp)

    #A significant delay is needed to wait for the yield generators to sync
    time.sleep(20)
    destaddrs = []
    for i in range(3):
        if btc.secp_present:
            destaddr = btc.privkey_to_address(
                os.urandom(32),
                from_hex=False,
                magicbyte=get_p2pk_vbyte())
        else:
            destaddr = btc.privkey_to_address(
                os.urandom(32),
                magicbyte=get_p2pk_vbyte())
        addr_valid, errormsg = validate_address(destaddr)
        assert addr_valid, "Invalid destination address: " + destaddr + \
                   ", error message: " + errormsg
        destaddrs.append(destaddr)
    tx_list = tumbler.generate_tumbler_tx(destaddrs, options)
    pprint(tx_list)
    if options['addrcount'] + 1 > options['mixdepthcount']:
        print('not enough mixing depths to pay to all destination addresses, '
              'increasing mixdepthcount')
        options['mixdepthcount'] = options['addrcount'] + 1

    tx_list2 = copy.deepcopy(tx_list)
    tx_dict = {}
    for tx in tx_list2:
        srcmixdepth = tx['srcmixdepth']
        tx.pop('srcmixdepth')
        if srcmixdepth not in tx_dict:
            tx_dict[srcmixdepth] = []
        tx_dict[srcmixdepth].append(tx)
    dbg_tx_list = []
    for srcmixdepth, txlist in tx_dict.iteritems():
        dbg_tx_list.append({'srcmixdepth': srcmixdepth, 'tx': txlist})
    log.debug('tumbler transaction list')
    pprint(dbg_tx_list)

    total_wait = sum([tx['wait'] for tx in tx_list])
    print('creates ' + str(len(tx_list)) + ' transactions in total')
    print('waits in total for ' + str(len(tx_list)) + ' blocks and ' + str(
            total_wait) + ' minutes')
    total_block_and_wait = len(tx_list) * 10 + total_wait
    print('estimated time taken ' + str(total_block_and_wait) + ' minutes or ' +
          str(round(total_block_and_wait / 60.0, 2)) + ' hours')

    jm_single().nickname = random_nick()

    log.debug('starting tumbler')

    jm_single().bc_interface.sync_wallet(wallet)
    jm_single().bc_interface.pushtx_failure_prob = 0.4
    irc = IRCMessageChannel(jm_single().nickname)
    tumbler_bot = tumbler.Tumbler(irc, wallet, tx_list, options)
    try:
        log.debug('starting irc')
        irc.run()
    except:
        log.debug('CRASHING, DUMPING EVERYTHING')
        debug_dump_object(wallet, ['addr_cache', 'keys', 'wallet_name', 'seed'])
        debug_dump_object(tumbler_bot)
        import traceback
        log.debug(traceback.format_exc())
    finally:
        if any(yigen_procs):
            for ygp in yigen_procs:
                #NB *GENTLE* shutdown is essential for
                #test coverage reporting!
                ygp.send_signal(signal.SIGINT)
                ygp.wait()
    #wait for block generation
    time.sleep(5)
    received = jm_single().bc_interface.get_received_by_addr(
        [destaddr], None)['data'][0]['balance']
    assert received != 0
    """TODO: figure out a sensible assertion check for the destination
Example #44
0
# If true, prints the SCAD to the terminal and then breaks after first generation
DEBUG = False

# Generate the addresses
if args.copies < 1:
	print("Please enter a valid number of copies (-co flag), and try again.")
	sys.exit()
else: # Use an else statement here just in case we add the option to import a CSV file with the keys (generated somewhere else)
	walletDataList = []
	for i in range(args.copies):
		thisData = {}

		# Generate the addresses with keys
		thisData["privateKey"] = bitcoin.main.random_key() # Secure: uses random library, time library and proprietary function
		thisData["wif"] = bitcoin.encode_privkey(thisData["privateKey"], "wif", args.versionByte)
		thisData["address"] = bitcoin.privkey_to_address(thisData["privateKey"], args.versionByte)

		# Generate the QR codes
		if args.errorCorrection.upper() not in ["L","M","Q","H"]:
			print("Please select a valid QR Error Correction value (L, M, Q, or H).")
			sys.exit()
		thisData["wifQR"] = qrTools.getQRArray(thisData["wif"], args.errorCorrection.upper())
		thisData["addressQR"] = qrTools.getQRArray(thisData["address"], args.errorCorrection.upper())

		# Reverse them or else they appear backwards (unknown reason)
		thisData["wifQR"] = list(reversed(thisData["wifQR"]))
		thisData["addressQR"] = list(reversed(thisData["addressQR"]))

		# Append ALL the wallet information, just in case we want to do something with it later
		walletDataList.append(thisData) 
Example #45
0
def test_sendpayment(setup_regtest, num_ygs, wallet_structures, mean_amt,
                     mixdepth, sending_amt):
    """Test of sendpayment code, with yield generators in background.
    """
    log = get_log()
    makercount = num_ygs
    answeryes = True
    txfee = 5000
    waittime = 5
    amount = sending_amt
    wallets = make_wallets(makercount + 1,
                           wallet_structures=wallet_structures,
                           mean_amt=mean_amt)
    #the sendpayment bot uses the last wallet in the list
    wallet = wallets[makercount]['wallet']

    yigen_procs = []
    for i in range(makercount):
        ygp = local_command([python_cmd, yg_cmd,\
                             str(wallets[i]['seed'])], bg=True)
        time.sleep(2)  #give it a chance
        yigen_procs.append(ygp)

    #A significant delay is needed to wait for the yield generators to sync
    time.sleep(20)
    if btc.secp_present:
        destaddr = btc.privkey_to_address(os.urandom(32),
                                          from_hex=False,
                                          magicbyte=get_p2pk_vbyte())
    else:
        destaddr = btc.privkey_to_address(os.urandom(32),
                                          magicbyte=get_p2pk_vbyte())

    addr_valid, errormsg = validate_address(destaddr)
    assert addr_valid, "Invalid destination address: " + destaddr + \
           ", error message: " + errormsg

    #TODO paramatetrize this as a test variable
    chooseOrdersFunc = weighted_order_choose

    jm_single().nickname = random_nick()

    log.debug('starting sendpayment')

    jm_single().bc_interface.sync_wallet(wallet)

    #Trigger PING LAG sending artificially
    joinmarket.irc.PING_INTERVAL = 3

    irc = IRCMessageChannel(jm_single().nickname)
    taker = sendpayment.SendPayment(irc, wallet, destaddr, amount, makercount,
                                    txfee, waittime, mixdepth, answeryes,
                                    chooseOrdersFunc)
    try:
        log.debug('starting irc')
        irc.run()
    finally:
        if any(yigen_procs):
            for ygp in yigen_procs:
                #NB *GENTLE* shutdown is essential for
                #test coverage reporting!
                ygp.send_signal(signal.SIGINT)
                ygp.wait()
    #wait for block generation
    time.sleep(5)
    received = jm_single().bc_interface.get_received_by_addr(
        [destaddr], None)['data'][0]['balance']
    if amount != 0:
        assert received == amount, "sendpayment failed - coins not arrived, " +\
           "received: " + str(received)
    #TODO: how to check success for sweep case?
    else:
        assert received != 0
Example #46
0
def wif_to_address(crypto, wif):
    try:
        return privkey_to_address(wif, crypto_data[crypto]['address_version_byte'])
    except KeyError:
        raise CurrencyNotSupported("Currency not yet supported")
Example #47
0
def test_tx_commitments_used(setup_podle, consume_tx, age_required, cmt_age):
    tries = jm_single().config.getint("POLICY", "taker_utxo_retries")
    #remember and reset at the end
    taker_utxo_age = jm_single().config.getint("POLICY", "taker_utxo_age")
    jm_single().config.set("POLICY", "taker_utxo_age", str(age_required))
    #Don't want to wait too long, but must account for possible
    #throttling with !auth
    jm_single().maker_timeout_sec = 12
    amount = 0
    wallets = make_wallets(3,
                           wallet_structures=[[1, 2, 1, 0, 0], [1, 2, 0, 0, 0],
                                              [2, 2, 1, 0, 0]],
                           mean_amt=1)
    #the sendpayment bot uses the last wallet in the list
    wallet = wallets[2]['wallet']

    #make_wallets calls grab_coins which mines 1 block per individual payout,
    #so the age of the coins depends on where they are in that list. The sendpayment
    #is the last wallet in the list, and we choose the non-tx utxos which are in
    #mixdepth 1 and 2 (2 and 1 utxos in each respectively). We filter for those
    #that have sufficient age, so to get 1 which is old enough, it will be the oldest,
    #which will have an age of 2 + 1 (the first utxo spent to that wallet).
    #So if we need an age of 6, we need to mine 3 more blocks.
    blocks_reqd = cmt_age - 3
    jm_single().bc_interface.tick_forward_chain(blocks_reqd)
    yigen_procs = []
    for i in range(2):
        ygp = local_command([python_cmd, yg_cmd,\
                             str(wallets[i]['seed'])], bg=True)
        time.sleep(2)  #give it a chance
        yigen_procs.append(ygp)

    time.sleep(5)
    destaddr = btc.privkey_to_address(binascii.hexlify(os.urandom(32)),
                                      magicbyte=get_p2pk_vbyte())
    addr_valid, errormsg = validate_address(destaddr)
    assert addr_valid, "Invalid destination address: " + destaddr + \
           ", error message: " + errormsg

    log.debug('starting sendpayment')

    jm_single().bc_interface.sync_wallet(wallet)
    log.debug("Here is the whole wallet: \n" + str(wallet.unspent))
    #Trigger PING LAG sending artificially
    joinmarket.irc.PING_INTERVAL = 3

    mcs = [IRCMessageChannel(c) for c in get_irc_mchannels()]
    mcc = MessageChannelCollection(mcs)
    if consume_tx:
        #add all utxo in mixdepth 0 to 'used' list of commitments,
        utxos = wallet.get_utxos_by_mixdepth()[0]
        for u, addrval in utxos.iteritems():
            priv = wallet.get_key_from_addr(addrval['address'])
            podle = btc.PoDLE(u, priv)
            for i in range(tries):
                #loop because we want to use up all retries of this utxo
                commitment = podle.generate_podle(i)['commit']
                btc.update_commitments(commitment=commitment)

    #Now test a sendpayment from mixdepth 0 with all the depth 0 utxos
    #used up, so that the other utxos in the wallet get used.
    taker = sendpayment.SendPayment(mcc, wallet, destaddr, amount, 2, 5000, 3,
                                    0, True, weighted_order_choose)
    try:
        log.debug('starting message channels')
        mcc.run()
    finally:
        if any(yigen_procs):
            for ygp in yigen_procs:
                #NB *GENTLE* shutdown is essential for
                #test coverage reporting!
                ygp.send_signal(signal.SIGINT)
                ygp.wait()
    #wait for block generation
    time.sleep(5)
    received = jm_single().bc_interface.get_received_by_addr(
        [destaddr], None)['data'][0]['balance']
    jm_single().config.set("POLICY", "taker_utxo_age", str(taker_utxo_age))
    if cmt_age < age_required:
        assert received == 0, "Coins arrived but shouldn't"
    else:
        assert received != 0, "sendpayment failed - coins not arrived, " +\
           "received: " + str(received)
Example #48
0
    elif key_type == 'P-256':
        sec = the_key.export_key(format='PEM')
        pub = the_key._export_public_pem(compress=0)  #PEM
        decoded_keys_temp_list.append({'secret': sec, 'public': pub})

    elif key_type == 'RSA':
        sec = the_key.export_key().decode()
        pub = the_key.publickey().export_key().decode()
        decoded_keys_temp_list.append({'secret': sec, 'public': pub})

    elif key_type == 'bitcoin':
        from bitcoin import encode_privkey, privkey_to_address
        print('the_key', the_key)
        sec = encode_privkey(the_key[:64], 'wif_compressed')
        print('sec', sec)
        addr = privkey_to_address(the_key[:64])
        print('addr', addr)
        decoded_keys_temp_list.append({'secret': sec, 'address': addr})

if file_type == 'json':
    jsoned(decoded_keys_temp_list, key_type)
elif file_type == 'separated':
    separated(decoded_keys_temp_list, key_type)
else:
    printed('Wrong file type. You can only use "json" and "separated" types')

clear_screen()
print(logo)
printed('\nDone.\n')
printed(
    '\nMAKE SURE YOU INSTANTLY PUT YOUR PRIVATE KEY IN A SAFE PLACE AS IT\'S NOT ENCRYPTED!\n'
Example #49
0
def main():
    args = parse_args()

    if  args.layoutStyle == 4 and args.blackOffset>0:
        print("Unable to generate a breakaway protected wallet with inverted depth")
        sys.exit()

    # Set DEBUG variable for testing purposes (changing styling)
    # If true, prints the SCAD to the terminal and then breaks after first generation
    DEBUG = False

    # Generate the addresses
    if args.copies < 1:
        print("Please enter a valid number of copies (-co flag), and try again.")
        sys.exit()
    else: # Use an else statement here just in case we add the option to import a CSV file with the keys (generated somewhere else)
        walletDataList = []
        for i in range(args.copies):
            thisData = {}

            # Generate the addresses with keys
            thisData["privateKey"] = bitcoin.main.random_key() # Secure: uses random library, time library and proprietary function
            thisData["wif"] = bitcoin.encode_privkey(thisData["privateKey"], "wif", args.versionByte)
            thisData["address"] = bitcoin.privkey_to_address(thisData["privateKey"], args.versionByte)

            # Generate the QR codes
            if args.errorCorrection.upper() not in ["L","M","Q","H"]:
                print("Please select a valid QR Error Correction value (L, M, Q, or H).")
                sys.exit()
            thisData["wifQR"] = qrTools.getQRArray(thisData["wif"], args.errorCorrection.upper())
            thisData["addressQR"] = qrTools.getQRArray(thisData["address"], args.errorCorrection.upper())

            # Reverse them or else they appear backwards (unknown reason)
            thisData["wifQR"] = list(reversed(thisData["wifQR"]))
            thisData["addressQR"] = list(reversed(thisData["addressQR"]))

            # Append ALL the wallet information, just in case we want to do something with it later
            walletDataList.append(thisData) 

    # Validate other args and set some constants
    walletWidth = args.walletWidth
    walletHeight = args.walletHeight
    if args.layoutStyle == 1 or args.layoutStyle == 2 or args.layoutStyle == 3 or args.layoutStyle == 4:
        walletLength = walletWidth*1.6 # Approximately the same ratio as a credit card
    else:
        print("Please choose a valid layout style option.")
        sys.exit()
    if args.blackOffset < -90.0:
        print("Please ensure that --black-offset (-bo flag) is set correctly, and is greater than -90.")
        sys.exit()
    textDepth = (args.blackOffset/100) * walletHeight

    # Check the openscad command
    scadExe = args.scadExe
    if args.scadExe == "openscad" and not distutils.spawn.find_executable("openscad"):
        if os.path.isfile("/Applications/OpenSCAD.app/Contents/MacOS/OpenSCAD"):
            print("Info: OpenSCAD found in Applications folder on Mac")
            scadExe = "/Applications/OpenSCAD.app/Contents/MacOS/OpenSCAD"
        elif os.path.isfile("%PROGRAMFILES%\OpenSCAD\openscad.exe"):
            print("Info: OpenSCAD found in Program Files on Windows")
            scadExe = "%PROGRAMFILES%\OpenSCAD\openscad.exe"
        elif os.path.isfile("%PROGRAMFILES(x86)%\OpenSCAD\openscad.exe"):
            print("Info: OpenSCAD found in Program Files (x86) on Windows")
            scadExe = "%PROGRAMFILES(x86)%\OpenSCAD\openscad.exe"
    if not distutils.spawn.find_executable(scadExe):
        print("Please install OpenSCAD or specify the location of it with --openscad-exe.")
        sys.exit()

    # Set the master SCAD variable
    masterSCAD = "// SCAD Code Generated By 3DGen.py - 3D Wallet Generator\n\n" # The beginning of the wallet are identical
    scadOutputs = [] # Generated from loop for each wallet (different addresses)

    # Include some modules at the beginning
    masterSCAD += "// Import some modules\n"
    masterSCAD += """
    $fn=100;
    module createMeniscus(h,radius)difference(){translate([radius/2+0.1,radius/2+0.1,0]){cube([radius+0.2,radius+0.1,h+0.2],center=true);}cylinder(h=h+0.2,r=radius,center=true);}
    module roundCornersCube(x,y,z)translate([x/2,y/2,z/2]){difference(){r=((x+y)/2)*0.052;cube([x,y,z],center=true);translate([x/2-r,y/2-r]){rotate(0){createMeniscus(z,r);}}translate([-x/2+r,y/2-r]){rotate(90){createMeniscus(z,r);}}translate([-x/2+r,-y/2+r]){rotate(180){createMeniscus(z,r);}}translate([x/2-r,-y/2+r]){rotate(270){createMeniscus(z,r);}}}}
    """ # The rounding corners modules for creating a rounded rectangle

    masterSCAD += "\n"

    # Draw the main prism


    mainCube = ""
    adjHeight = walletHeight
    if args.layoutStyle == 4:
        adjHeight += 2
        mainCube ="translate([0,0,-2]) "

    if args.roundCorners:
        mainCube += "roundCornersCube(" + str(walletLength) + "," + str(walletWidth) + "," + str(adjHeight) + ");"
    else:
        mainCube += "cube([" + str(walletLength) + "," + str(walletWidth) + "," + str(adjHeight) + "]);"
    mainCube += "\n\n"

    if args.layoutStyle == 4:
        # Create a slice in the wallet with breakaway stubs
        mainCube += """
        difference ()
          {
            cube([86.4,54.0,0.2]);
            for (x=[0:20])
            {
                translate([((x+2)/24)*86.4,(1/20)*54.0,-1]) cube([86.4/200,54.0/100,2]);
                translate([((x+2)/24)*86.4,(19/20)*54.0,-1]) cube([86.4/200,54.0/100,2]);
                translate([(1/30)*86.4,((x+2)/24)*54.0,-1]) cube([86.4/200,54.0/100,2]);
                translate([(29/30)*86.4,((x+2)/24)*54.0,-1]) cube([86.4/200,54.0/100,2]);
            }
          }   
        """

    # Init a variable to keep all the additive/subtractive parts
    finalParts = []

    # Init variables to keep the CSV output data in
    addressOut = []
    privkeyOut = []
    APOut = []
    PAOut = []

    # Set a counter for naming the files
    filenameCounter = 1

    # Break into the loop for each wallet
    for data in walletDataList:
        # 'data' = wif, address, wifQR, addressQR

        # Generate the texts
        addressLine1 = data["address"][:math.ceil(len(data["address"])/2.0)]
        addressLine2 = data["address"][math.ceil(len(data["address"])/2.0):]
        wifLine1 = data["wif"][:17]
        wifLine2 = data["wif"][17:34]
        wifLine3 = data["wif"][34:]

        addressLine1Dots = textGen.getArray(addressLine1)
        addressLine2Dots = textGen.getArray(addressLine2)
        privkeyLine1Dots = textGen.getArray(wifLine1)
        privkeyLine2Dots = textGen.getArray(wifLine2)
        privkeyLine3Dots = textGen.getArray(wifLine3)

        bigTitle = textGen.getArray("3D " + args.coinTitle + " Wallet")
        addressTitle = textGen.getArray("Address")
        privkeyTitle = textGen.getArray("Private Key")

        # Create the big title union so that it can be sized and moved
        bigTitleUnion = ""
        for rowIndex in range(len(bigTitle)):
            row = bigTitle[rowIndex]
            for colIndex in range(len(row)):
                if row[colIndex] == '1':
                    translateHeight = walletHeight if textDepth>0 else walletHeight+textDepth
                    bigTitleUnion += "translate([colIndex,rowIndex,translateHeight]){cube([1,1,textDepth]);}".replace('colIndex',str(colIndex)).replace('rowIndex',str(rowIndex)).replace('textDepth',str(abs(textDepth))).replace('translateHeight',str(translateHeight))

        # Translate the title to where it goes
        bigTitleFinal = "translate([(1/17)*length,(14/17)*width,0]){resize([(15/17)*length,0,0],auto=[true,true,false]){bigTitleUnion}}".replace('length',str(walletLength)).replace('width',str(walletWidth)).replace('bigTitleUnion',bigTitleUnion)
        finalParts.append(bigTitleFinal+"\n\n")
        if args.layoutStyle == 1 or args.layoutStyle == 4:
            # Need to copy it on to the backside as well - rotate then move it, and then create a union of the two titles (front and back)
            bigTitle2 = "translate([length,0,height]){rotate(180,v=[0,1,0]){bigTitleFinal}}".replace('length',str(walletLength)).replace('height',str(walletHeight)).replace('bigTitleFinal',bigTitleFinal).replace('translateHeight',str(translateHeight))
            finalParts.append(bigTitle2+"\n\n")
        
        # Draw the word "Address" on the front, and draw on the actual address
        if args.layoutStyle == 1 or args.layoutStyle == 3 or args.layoutStyle == 4:
            # Draw the address on the front
            addressParts = []

            # Create the address title union and size/move it
            addressTitleUnion = "union(){"
            for rowIndex in range(len(addressTitle)):
                row = addressTitle[rowIndex]
                for colIndex in range(len(row)):
                    if row[colIndex] == '1':
                        translateHeight = walletHeight if textDepth>0 else walletHeight+textDepth
                        addressTitleUnion += "translate([colIndex,rowIndex,translateHeight]){cube([1,1,textDepth]);}".replace('colIndex',str(colIndex)).replace('rowIndex',str(rowIndex)).replace('textDepth',str(abs(textDepth))).replace('translateHeight',str(translateHeight))
            addressTitleUnion += "}"
            addressTitleFinal = "translate([(10/17)*length,(6/11)*width,0]){resize([0,(4/55)*width,0],auto=[true,true,false]){addressTitleUnion}}\n\n".replace('length',str(walletLength)).replace('width',str(walletWidth)).replace('addressTitleUnion',addressTitleUnion)
            addressParts.append(addressTitleFinal)

            # Create the first line of the address
            addressLine1Union = "union(){"
            for rowIndex in range(len(addressLine1Dots)):
                row = addressLine1Dots[rowIndex]
                for colIndex in range(len(row)):
                    if row[colIndex] == '1':
                        translateHeight = walletHeight if textDepth>0 else walletHeight+textDepth
                        addressLine1Union += "translate([colIndex,rowIndex,translateHeight]){cube([1,1,textDepth]);}".replace('colIndex',str(colIndex)).replace('rowIndex',str(rowIndex)).replace('textDepth',str(abs(textDepth))).replace('translateHeight',str(translateHeight))
            addressLine1Union += "}"
            addressLine1Final = "translate([(8.2/17)*length,(5/11)*width,0]){resize([0,(3/55)*width,0],auto=[true,true,false]){addressLine1Union}}\n\n".replace('length',str(walletLength)).replace('width',str(walletWidth)).replace('addressLine1Union',addressLine1Union)
            addressParts.append(addressLine1Final)

            # Create the second line of the address
            addressLine2Union = "union(){"
            for rowIndex in range(len(addressLine2Dots)):
                row = addressLine2Dots[rowIndex]
                for colIndex in range(len(row)):
                    if row[colIndex] == '1':
                        translateHeight = walletHeight if textDepth>0 else walletHeight+textDepth
                        addressLine2Union += "translate([colIndex,rowIndex,translateHeight]){cube([1,1,textDepth]);}".replace('colIndex',str(colIndex)).replace('rowIndex',str(rowIndex)).replace('textDepth',str(abs(textDepth))).replace('translateHeight',str(translateHeight))
            addressLine2Union += "}"
            addressLine2Final = "translate([(8.2/17)*length,(4.1/11)*width,0]){resize([0,(3/55)*width,0],auto=[true,true,false]){addressLine2Union}}\n\n".replace('length',str(walletLength)).replace('width',str(walletWidth)).replace('addressLine2Union',addressLine2Union)
            addressParts.append(addressLine2Final)

            # Create the QR code
            addressQRUnion = "union(){"
            for rowIndex in range(len(data["addressQR"])):
                row = data["addressQR"][rowIndex]
                for colIndex in range(len(row)):
                    if row[colIndex] == 0:
                        translateHeight = walletHeight if textDepth>0 else walletHeight+textDepth
                        addressQRUnion += "translate([colIndex,rowIndex,translateHeight]){cube([1,1,textDepth]);}".replace('colIndex',str(colIndex)).replace('rowIndex',str(rowIndex)).replace('textDepth',str(abs(textDepth))).replace('translateHeight',str(translateHeight))
            addressQRUnion += "}"
            addressQRFinal = "translate([(0.6/17)*length,(0.6/11)*width,0]){resize([0,(8/12)*width,0],auto=[true,true,false]){addressQRUnion}}\n\n".replace('length',str(walletLength)).replace('width',str(walletWidth)).replace('addressQRUnion',addressQRUnion)
            addressParts.append(addressQRFinal)
            
            finalParts.extend(addressParts)

        # Draw all the things having to do with the private key
        if args.layoutStyle == 1 or args.layoutStyle == 2 or args.layoutStyle == 4:
            privkeyParts = []

            # Create the privkey title union and size/move it
            privkeyTitleUnion = "union(){"
            for rowIndex in range(len(privkeyTitle)):
                row = privkeyTitle[rowIndex]
                for colIndex in range(len(row)):
                    if row[colIndex] == '1':
                        translateHeight = walletHeight if textDepth>0 else walletHeight+textDepth
                        privkeyTitleUnion += "translate([colIndex,rowIndex,translateHeight]){cube([1,1,textDepth]);}".replace('colIndex',str(colIndex)).replace('rowIndex',str(rowIndex)).replace('textDepth',str(abs(textDepth))).replace('translateHeight',str(translateHeight))
            privkeyTitleUnion += "}"
            privkeyTitleFinal = "translate([(8.7/17)*length,(7/11)*width,0]){resize([0,(4/55)*width,0],auto=[true,true,false]){privkeyTitleUnion}}\n\n".replace('length',str(walletLength)).replace('width',str(walletWidth)).replace('privkeyTitleUnion',privkeyTitleUnion)
            privkeyParts.append(privkeyTitleFinal)

            # Create the first line of the privkey
            privkeyLine1Union = "union(){"
            for rowIndex in range(len(privkeyLine1Dots)):
                row = privkeyLine1Dots[rowIndex]
                for colIndex in range(len(row)):
                    if row[colIndex] == '1':
                        translateHeight = walletHeight if textDepth>0 else walletHeight+textDepth
                        privkeyLine1Union += "translate([colIndex,rowIndex,translateHeight]){cube([1,1,textDepth]);}".replace('colIndex',str(colIndex)).replace('rowIndex',str(rowIndex)).replace('textDepth',str(abs(textDepth))).replace('translateHeight',str(translateHeight))
            privkeyLine1Union += "}"
            privkeyLine1Final = "translate([(8.2/17)*length,(6/11)*width,0]){resize([0,(3/55)*width,0],auto=[true,true,false]){privkeyLine1Union}}\n\n".replace('length',str(walletLength)).replace('width',str(walletWidth)).replace('privkeyLine1Union',privkeyLine1Union)
            privkeyParts.append(privkeyLine1Final)

            # Create the second line of the privkey
            privkeyLine2Union = "union(){"
            for rowIndex in range(len(privkeyLine2Dots)):
                row = privkeyLine2Dots[rowIndex]
                for colIndex in range(len(row)):
                    if row[colIndex] == '1':
                        translateHeight = walletHeight if textDepth>0 else walletHeight+textDepth
                        privkeyLine2Union += "translate([colIndex,rowIndex,translateHeight]){cube([1,1,textDepth]);}".replace('colIndex',str(colIndex)).replace('rowIndex',str(rowIndex)).replace('textDepth',str(abs(textDepth))).replace('translateHeight',str(translateHeight))
            privkeyLine2Union += "}"
            privkeyLine2Final = "translate([(8.2/17)*length,(5.1/11)*width,0]){resize([0,(3/55)*width,0],auto=[true,true,false]){privkeyLine2Union}}\n\n".replace('length',str(walletLength)).replace('width',str(walletWidth)).replace('privkeyLine2Union',privkeyLine2Union)
            privkeyParts.append(privkeyLine2Final)

            # Create the third line of the privkey
            privkeyLine3Union = "union(){"
            for rowIndex in range(len(privkeyLine3Dots)):
                row = privkeyLine3Dots[rowIndex]
                for colIndex in range(len(row)):
                    if row[colIndex] == '1':
                        translateHeight = walletHeight if textDepth>0 else walletHeight+textDepth
                        privkeyLine3Union += "translate([colIndex,rowIndex,translateHeight]){cube([1,1,textDepth]);}".replace('colIndex',str(colIndex)).replace('rowIndex',str(rowIndex)).replace('textDepth',str(abs(textDepth))).replace('translateHeight',str(translateHeight))
            privkeyLine3Union += "}"
            privkeyLine3Final = "translate([(8.2/17)*length,(4.2/11)*width,0]){resize([0,(3/55)*width,0],auto=[true,true,false]){privkeyLine3Union}}\n\n".replace('length',str(walletLength)).replace('width',str(walletWidth)).replace('privkeyLine3Union',privkeyLine3Union)
            privkeyParts.append(privkeyLine3Final)

            # Create the QR code
            privkeyQRUnion = "union(){"
            for rowIndex in range(len(data["wifQR"])):
                row = data["wifQR"][rowIndex]
                for colIndex in range(len(row)):
                    if row[colIndex] == 0:
                        translateHeight = walletHeight if textDepth>0 else walletHeight+textDepth
                        privkeyQRUnion += "translate([colIndex,rowIndex,translateHeight]){cube([1,1,textDepth]);}".replace('colIndex',str(colIndex)).replace('rowIndex',str(rowIndex)).replace('textDepth',str(abs(textDepth))).replace('translateHeight',str(translateHeight))
            privkeyQRUnion += "}"
            privkeyQRFinal = "translate([(0.6/17)*length,(0.6/11)*width,0]){resize([0,(8/12)*width,0],auto=[true,true,false]){privkeyQRUnion}}\n\n".replace('length',str(walletLength)).replace('width',str(walletWidth)).replace('privkeyQRUnion',privkeyQRUnion)
            privkeyParts.append(privkeyQRFinal)

            if args.layoutStyle == 2:
                # Just add it all to the finalParts
                finalParts.extend(privkeyParts)
            elif args.layoutStyle == 1 or args.layoutStyle == 4:
                # Rotate it all and then add it to the finalParts
                privkeyPartsNew = []
                for part in privkeyParts:
                    privkeyPartsNew.append("translate([length,0,height]){rotate(180,v=[0,1,0]){part}}".replace('length',str(walletLength)).replace('height',str(walletHeight)).replace('part',part).replace('translateHeight',str(translateHeight)))
                finalParts.extend(privkeyPartsNew)

        # Put it all together
        finalSCAD = masterSCAD
        if textDepth < 0:
            finalSCAD += "difference() {\n\n"
        else:
            finalSCAD += "union() {\n\n"
        finalSCAD += mainCube
        finalSCAD += "".join(finalParts)
        finalSCAD += "}"

        if DEBUG:
            print(finalSCAD)
            break

        if args.outputSCADFolder:
            try:
                os.makedirs(args.outputSCADFolder)
            except FileExistsError:
                pass
            scadOutFile = open(args.outputSCADFolder + '/wallet' + str(filenameCounter) + '.scad','w')
            scadOutFile.write(finalSCAD)
            scadOutFile.close()

        # Log some info
        print("Status: Done generating data for wallet #" + str(filenameCounter) + "...Starting generating STL file")

        if args.outputSTLFolder:
            try:
                os.makedirs(args.outputSTLFolder)
            except FileExistsError:
                pass
            scadOutFile = open('temp.scad','w')
            scadOutFile.write(finalSCAD)
            scadOutFile.close()
            os.system(scadExe + " -o " + args.outputSTLFolder + "/wallet" + str(filenameCounter) + ".stl temp.scad")
            try:
                os.remove('temp.scad')
            except:
                pass
        else:
            print("Please provide a folder to output the STL files.")

        # Update the CSV file variables
        addressOut.append(data["address"])
        privkeyOut.append(data["wif"])
        APOut.append(data["address"] + "," + data["wif"])
        PAOut.append(data["wif"] + "," + data["address"])

        # Print some more stats
        print("Status: Done generating STL file (" + str(round(filenameCounter/args.copies*100)) + "% done)")

        filenameCounter += 1

    # Export the CSV files
    if args.exportAddressCSV:
        csvFile = open(args.exportAddressCSV,'a')
        csvFile.write(','.join(addressOut))
        csvFile.close()

    if args.exportPrivkeyCSV:
        csvFile = open(args.exportPrivkeyCSV,'a')
        csvFile.write(','.join(privkeyOut))
        csvFile.close()

    if args.exportAPCSV:
        csvFile = open(args.exportAPCSV,'a')
        csvFile.write('\n'.join(exportAPCSV))
        csvFile.close()

    if args.exportPACSV:
        csvFile = open(args.exportPACSV,'a')
        csvFile.write('\n'.join(exportPACSV))
        csvFile.close()