def test_funding_mainnet(self): addresses = srv.main( ["--basedir={0}".format(self.basedir), "--funding"], serve=False) self.assertIsNotNone(addresses) self.assertTrue(len(addresses) == 3) for address in addresses: validate.is_address_valid(address, allowable_netcodes=[etc.netcode])
def __call__(self, value): value = str(value) if getattr(settings, 'TESTNET', False): if is_address_valid(value) != 'XTN': raise ValidationError( _(u'%s is not a valid bitcoin testnet address!') % value) else: if is_address_valid(value) != 'BTC': raise ValidationError( _(u'%s is not a valid bitcoin address!') % value)
def get_unused_address(social_id, deriv): ''' Need to be careful about when to move up the latest_derivation listing. Figure only incrementing the database entry when blockchain activity is found is the least likely to create large gaps of empty addresses in someone's BTC Wallet. ''' pp = pprint.PrettyPrinter(indent=2) userdata = User.query.filter_by(social_id=social_id).first() # Pull BTC Address from given user data key = Key.from_text(userdata.xpub).subkey(0). \ subkey(deriv) address = key.address(use_uncompressed=False) if is_address_valid(userdata.xpub) == "BTC": return "STREAMER SUBMITTED BTCADDR INSTEAD OF XPUB, PLEASE INFORM "\ + "STREAMER OR DEVELOPER" if is_address_valid(key.address(use_uncompressed=False)) != "BTC": return "NO VALID ADDRESS, PLEASE INFORM STREAMER OR DEVELOPER" # Check for existing payment request, delete if older than 5m. payment_request = PayReq.query.filter_by(addr=address).first() if payment_request: req_timestamp = payment_request.timestamp now_timestamp = datetime.utcnow() delta_timestamp = now_timestamp - req_timestamp if delta_timestamp > timedelta(seconds=60 * 5): db.session.delete(payment_request) db.session.commit() payment_request = None pp.pprint(check_payment_on_address(address)) if not check_address_history(address): if not payment_request: return address else: print("Address has payment request...") print("Address Derivation: ", deriv) return get_unused_address(social_id, deriv + 1) else: print("Address has blockchain history, searching new address...") print("Address Derivation: ", userdata.latest_derivation) userdata.latest_derivation = userdata.latest_derivation + 1 db.session.commit() return get_unused_address(social_id, deriv + 1)
def address(value): if value is None: return None value = str(value) valid = validate.is_address_valid(value, allowable_netcodes=["XTN", "BTC"]) assert valid, "{} is not a bitcoin address!".format(value) return value
def test_get_funding_addresses(): assets = ["XCP"] result = lib.get_funding_addresses(assets) assert (assets == list(result.keys())) assert (all([ is_address_valid(a, allowable_netcodes=["XTN"]) for a in result.values() ]))
def get_address(which): while 1: print("enter the %s address=> " % which, end='') address = input() is_valid = is_address_valid(address) if is_valid: return address print("invalid address, please try again")
def get_address(which): while 1: print("enter the " + str(which) + " address=> ", end="") address = input() is_valid = is_address_valid(address) if is_valid: return address print("invalid address, please try again")
def get_address(which): while 1: print "enter the %s address=>"%which, address=input(); is_valid=is_address_valid(address) if is_valid: return address print 'invalid address, please try again'
def test_get_funding_addresses(): assets = ["XCP"] result = lib.get_funding_addresses(assets) assert(assets == list(result.keys())) assert(all([ is_address_valid(a, allowable_netcodes=["XTN"]) for a in result.values() ]))
def as_payable(payable): address, amount = payable, None if "/" in payable: address, amount = payable.split("/", 1) if not is_address_valid(address): raise argparse.ArgumentTypeError("%s is not a valid address" % address) if amount is not None: return (address, int(amount)) return address
def coinbase(): account = Account.Account(TEST_EMAIL1) wallet = Wallet.Wallet.from_wallet_key(account.get_wallet_keys()[0]) address = wallet.address() assert is_address_valid(address) tx_in = TxIn.coinbase_tx_in(script=b'') tx_out = TxOut(50 * 1e8, standard_tx_out_script(address)) tx = Tx(1, [tx_in], [tx_out]) return tx.as_hex()
def parse_context(args, parser): # we create the tx_db lazily tx_db = None if args.db: the_ram_tx_db = dict((tx.hash(), tx) for tx in args.db) if tx_db is None: tx_db = create_tx_db(args.network) tx_db.lookup_methods.append(the_ram_tx_db.get) # defaults txs = [] spendables = [] payables = [] key_iters = [] # there are a few warnings we might optionally print out, but only if # they are relevant. We don't want to print them out multiple times, so we # collect them here and print them at the end if they ever kick in. warning_spendables = None for arg in args.argument: if is_address_valid( arg, allowable_netcodes=[args.network], allowable_types=["address", "pay_to_script", "segwit"]): payables.append((arg, 0)) continue if key_found(arg, payables, key_iters): continue tx, tx_db = parse_tx(arg, parser, tx_db, args.network) if tx: txs.append(tx) continue if parse_parts(arg, spendables, payables, args.network): continue parser.error("can't parse %s" % arg) parse_private_key_file(args, key_iters) if args.fetch_spendables: warning_spendables = message_about_spendables_for_address_env( args.network) for address in args.fetch_spendables: spendables.extend(spendables_for_address(address, args.network)) return (txs, spendables, payables, key_iters, tx_db, warning_spendables)
def parse_context(args, parser): # we create the tx_db lazily tx_db = None if args.db: the_ram_tx_db = dict((tx.hash(), tx) for tx in args.db) if tx_db is None: tx_db = create_tx_db(args.network) tx_db.lookup_methods.append(the_ram_tx_db.get) # defaults txs = [] spendables = [] payables = [] key_iters = [] # there are a few warnings we might optionally print out, but only if # they are relevant. We don't want to print them out multiple times, so we # collect them here and print them at the end if they ever kick in. warning_spendables = None for arg in args.argument: if is_address_valid(arg, allowable_netcodes=[args.network], allowable_types=[ "address", "pay_to_script", "segwit"]): payables.append((arg, 0)) continue if key_found(arg, payables, key_iters): continue tx, tx_db = parse_tx(arg, parser, tx_db, args.network) if tx: txs.append(tx) continue if parse_parts(arg, spendables, payables, args.network): continue parser.error("can't parse %s" % arg) parse_private_key_file(args, key_iters) if args.fetch_spendables: warning_spendables = message_about_spendables_for_address_env(args.network) for address in args.fetch_spendables: spendables.extend(spendables_for_address(address, args.network)) return (txs, spendables, payables, key_iters, tx_db, warning_spendables)
def home(request): #region GET if request.method == "GET": form_capcha = CaptchaTestForm() form_account = AccountForm() html_dtc = dict(form_capcha=form_capcha, form_account=form_account, count=len(AccountModel.objects.all())) error_message = request.session.get('error_message', False) if error_message: html_dtc.update(dict(error_message=error_message)) del request.session['error_message'] html_dtc.update(csrf(request)) return render_to_response('chikun/home.html', html_dtc) #endregion #region POST if request.method == "POST": # human test form = CaptchaTestForm(request.POST) if not form.is_valid(): request.session.update(dict(error_message='Invalid Captcha')) return redirect('home') # validate return address return_address = request.POST.get('return_address', False) if not is_address_valid(return_address): request.session.update( dict(error_message='Invalid Bitcoin Address')) return redirect('home') # log details account_record = AccountModel.objects.create( return_address=return_address) account_record.save() # deposit address deposit_address = master_public_key.subkey(account_record.id).address() # html tags html_dtc = dict(deposit_address=deposit_address) html_dtc.update(csrf(request)) return render_to_response('chikun/address.html', html_dtc) ''''''
def main(): if len(sys.argv) != 2: print("usage: %s address" % sys.argv[0]) sys.exit(-1) # validate the address address = sys.argv[1] assert is_address_valid(address) print("creating coinbase transaction to %s" % address) tx_in = TxIn.coinbase_tx_in(script=b'') tx_out = TxOut(50*1e8, standard_tx_out_script(address)) tx = Tx(1, [tx_in], [tx_out]) print("Here is the tx as hex:\n%s" % tx.as_hex())
def subscribe(self): try: try: parsed_request = cherrypy.request.json addresses = parsed_request['addresses'] if type(addresses) not in [list, dict]: raise ValueError except (ValueError, KeyError), err: return self.response(400, {'error': 'Invalid request json data. Expected: {"addresses": {"address": "account_id", ..}} or {"addresses": ["address", ..]}'}) for address in addresses: if not is_address_valid(address): return self.response(400, {'error': '%s is invalid address. Ignoring all.' % address}) self.__subscribe(addresses) return self.response(200, {'subscribed': True})
def validate_address(address, network=None): """ Validate an address of the given network. :param str address: The address to validate :param str network: The network the address belongs to (i.e. DASH) :rtype: bool """ try: netcode = is_address_valid(address, allowable_netcodes=NETCODES) except Exception: return False if netcode is None or (network is not None and netcode != network): return False return True
def parse_parts(arg, spendables, payables, network): parts = arg.split("/") if 4 <= len(parts) <= 7: # spendable try: spendables.append(Spendable.from_text(arg)) return True except Exception: pass if len(parts) == 2 and is_address_valid(parts[0], allowable_netcodes=[network]): try: payables.append(parts) return True except ValueError: pass
def home(request): #region GET if request.method == "GET": form_capcha = CaptchaTestForm() form_account = AccountForm() html_dtc = dict(form_capcha=form_capcha, form_account=form_account, count=len(AccountModel.objects.all())) error_message = request.session.get('error_message', False) if error_message: html_dtc.update(dict(error_message=error_message)) del request.session['error_message'] html_dtc.update(csrf(request)) return render_to_response('chikun/home.html', html_dtc) #endregion #region POST if request.method == "POST": # human test form = CaptchaTestForm(request.POST) if not form.is_valid(): request.session.update(dict(error_message='Invalid Captcha')) return redirect('home') # validate return address return_address = request.POST.get('return_address', False) if not is_address_valid(return_address): request.session.update(dict(error_message='Invalid Bitcoin Address')) return redirect('home') # log details account_record = AccountModel.objects.create(return_address=return_address) account_record.save() # deposit address deposit_address = master_public_key.subkey(account_record.id).address() # html tags html_dtc = dict(deposit_address=deposit_address) html_dtc.update(csrf(request)) return render_to_response('chikun/address.html', html_dtc) ''''''
def test_address_valid_btc(self): for address in PAY_TO_HASH_ADDRESSES: self.assertEqual(is_address_valid(address), "BTC") a = address[:-1] + chr(ord(address[-1])+1) self.assertEqual(is_address_valid(a), None) for address in PAY_TO_HASH_ADDRESSES: self.assertEqual(is_address_valid(address, allowable_types=["pay_to_script"]), None) self.assertEqual(is_address_valid(address, allowable_types=["address"]), "BTC") for address in PAY_TO_SCRIPT_ADDRESSES: self.assertEqual(address[0], "3") self.assertEqual(is_address_valid(address, allowable_types=["pay_to_script"]), "BTC") self.assertEqual(is_address_valid(address, allowable_types=["address"]), None)
def main(): if len(sys.argv) != 4: print("usage: %s incoming_tx_hex_filename tx_out_index new_address" % sys.argv[0]) sys.exit(-1) with open(sys.argv[1], "r") as f: tx_hex = f.readline().strip() # get the spendable from the prior transaction tx = Tx.from_hex(tx_hex) tx_out_index = int(sys.argv[2]) spendable = tx.tx_outs_as_spendable()[tx_out_index] # make sure the address is valid payable = sys.argv[3] assert is_address_valid(payable) # create the unsigned transaction tx = create_tx([spendable], [payable]) print("here is the transaction: %s" % tx.as_hex(include_unspents=True))
[docs]def main(): if len(sys.argv) != 4: print("usage: %s incoming_tx_hex_filename tx_out_index new_address" % sys.argv[0]) sys.exit(-1) with open(sys.argv[1], "r") as f: tx_hex = f.readline().strip() # get the spendable from the prior transaction tx = Tx.from_hex(tx_hex) tx_out_index = int(sys.argv[2]) spendable = tx.tx_outs_as_spendable()[tx_out_index] # make sure the address is valid payable = sys.argv[3] assert is_address_valid(payable) # create the unsigned transaction tx = create_tx([spendable], [payable]) print("here is the transaction: %s" % tx.as_hex(include_unspents=True))
def test_address_valid_btc(self): for address in PAY_TO_HASH_ADDRESSES: self.assertEqual(is_address_valid(address), "BTC") a = address[:-1] + chr(ord(address[-1]) + 1) self.assertEqual(is_address_valid(a), None) for address in PAY_TO_HASH_ADDRESSES: self.assertEqual( is_address_valid(address, allowable_types=["pay_to_script"]), None) self.assertEqual( is_address_valid(address, allowable_types=["address"]), "BTC") for address in PAY_TO_SCRIPT_ADDRESSES: self.assertEqual(address[0], "3") self.assertEqual( is_address_valid(address, allowable_types=["pay_to_script"]), "BTC") self.assertEqual( is_address_valid(address, allowable_types=["address"]), None)
def verifyAddress(self, address): if self.use_production: return is_address_valid(address) == "BTC" else: return is_address_valid(address) == "XTN"
def test_standard(self): wif = self.api.create_key() address = self.api.get_address(wif) self.assertTrue(validate.is_address_valid(address, allowable_netcodes=['XTN']))
def send_to_address(self, ticker, address, amount, multisig={}): if self.testnet: network = "XTN" else: network = "BTC" if is_address_valid(address) != network: raise INVALID_ADDRESS contract = accounting.get_contract(self.session, ticker) if not multisig: withdrawal_amount = float(conversions.quantity_from_wire(contract, amount)) try: result = yield self.bitcoinrpc[ticker].getbalance() except Exception as e: log.err("Unable to get wallet balance: %s" % str(e)) raise e balance = result['result'] if balance >= withdrawal_amount: try: result = yield self.bitcoinrpc[ticker].sendtoaddress(address, withdrawal_amount) txid = result['result'] tx = yield self.bitcoinrpc[ticker].gettransaction(txid) # The fee shows up from gettransaction as a negative number, # but we want a positive number fee = abs(long(round(tx['result']['fee'] * contract.denominator))) except Exception as e: log.err("Unable to send to address: %s" % str(e)) raise e else: raise INSUFFICIENT_FUNDS else: self.bitgo.token = multisig['token'].encode('utf-8') try: yield self.bitgo.unlock(multisig['otp']) except Exception as e: log.err("Unable to unlock multisig") raise OTP_INVALID wallet_id = contract.multisig_wallet_address try: wallet = yield self.bitgo.wallets.get(wallet_id) except Exception as e: log.err("Unable to get wallet details") log.err(e) raise e balance = wallet.balance if balance < amount: raise INSUFFICIENT_FUNDS if not os.path.exists(self.bitgo_private_key_file): raise NO_KEY_FILE else: with open(self.bitgo_private_key_file, "rb") as f: key_data = json.load(f) passphrase = key_data['passphrase'] try: result = yield wallet.sendCoins(address=address, amount=amount, passphrase=passphrase) txid = result['tx'] fee = result['fee'] except Exception as e: log.err("Unable to sendCoins") log.err(e) raise e returnValue({'txid': txid, 'fee': fee})
def __call__(self, value): value = str(value) if is_address_valid(value) != 'BTC': raise ValidationError(_(u'%s is not a valid bitcoin address!') % value)
def send_to_address(self, ticker, address, amount, multisig={}): if self.testnet: network = "XTN" else: network = "BTC" if is_address_valid(address) != network: raise INVALID_ADDRESS contract = accounting.get_contract(self.session, ticker) if not multisig: withdrawal_amount = float( conversions.quantity_from_wire(contract, amount)) try: result = yield self.bitcoinrpc[ticker].getbalance() except Exception as e: log.err("Unable to get wallet balance: %s" % str(e)) raise e balance = result['result'] if balance >= withdrawal_amount: try: result = yield self.bitcoinrpc[ticker].sendtoaddress( address, withdrawal_amount) txid = result['result'] tx = yield self.bitcoinrpc[ticker].gettransaction(txid) # The fee shows up from gettransaction as a negative number, # but we want a positive number fee = abs( long(round(tx['result']['fee'] * contract.denominator))) except Exception as e: log.err("Unable to send to address: %s" % str(e)) raise e else: raise INSUFFICIENT_FUNDS else: self.bitgo.token = multisig['token'].encode('utf-8') try: yield self.bitgo.unlock(multisig['otp']) except Exception as e: log.err("Unable to unlock multisig") raise OTP_INVALID wallet_id = contract.multisig_wallet_address try: wallet = yield self.bitgo.wallets.get(wallet_id) except Exception as e: log.err("Unable to get wallet details") log.err(e) raise e balance = wallet.balance if balance < amount: raise INSUFFICIENT_FUNDS if not os.path.exists(self.bitgo_private_key_file): raise NO_KEY_FILE else: with open(self.bitgo_private_key_file, "rb") as f: key_data = json.load(f) passphrase = key_data['passphrase'] try: result = yield wallet.sendCoins(address=address, amount=amount, passphrase=passphrase) txid = result['tx'] fee = result['fee'] except Exception as e: log.err("Unable to sendCoins") log.err(e) raise e returnValue({'txid': txid, 'fee': fee})
def test_get_funding_addresses(): address = lib.get_funding_address() assert (is_address_valid(address, allowable_netcodes=["XTN"]))
def test_get_funding_addresses(): address = lib.get_funding_address() assert(is_address_valid(address, allowable_netcodes=["XTN"]))
def address(testnet, address): address = unicode_str(address) netcode = 'XTN' if testnet else 'BTC' if not validate.is_address_valid(address, allowable_netcodes=[netcode]): raise exceptions.InvalidAddress(address) return address
def address(testnet, address): netcode = 'XTN' if testnet else 'BTC' if not validate.is_address_valid(address, allowable_netcodes=[netcode]): raise exceptions.InvalidAddress(address) return address
def parse_context(args, parser): # defaults txs = [] spendables = [] payables = [] key_iters = [] TX_ID_RE = re.compile(r"^[0-9a-fA-F]{64}$") # there are a few warnings we might optionally print out, but only if # they are relevant. We don't want to print them out multiple times, so we # collect them here and print them at the end if they ever kick in. warning_tx_cache = None warning_tx_for_tx_hash = None warning_spendables = None if args.private_key_file: wif_re = re.compile(r"[1-9a-km-zA-LMNP-Z]{51,111}") # address_re = re.compile(r"[1-9a-kmnp-zA-KMNP-Z]{27-31}") for f in args.private_key_file: if f.name.endswith(".gpg"): gpg_args = ["gpg", "-d"] if args.gpg_argument: gpg_args.extend(args.gpg_argument.split()) gpg_args.append(f.name) popen = subprocess.Popen(gpg_args, stdout=subprocess.PIPE) f = popen.stdout for line in f.readlines(): # decode if isinstance(line, bytes): line = line.decode("utf8") # look for WIFs possible_keys = wif_re.findall(line) def make_key(x): try: return Key.from_text(x) except Exception: return None keys = [make_key(x) for x in possible_keys] for key in keys: if key: key_iters.append((k.wif() for k in key.subkeys(""))) # if len(keys) == 1 and key.hierarchical_wallet() is None: # # we have exactly 1 WIF. Let's look for an address # potential_addresses = address_re.findall(line) # update p2sh_lookup p2sh_lookup = {} if args.pay_to_script: for p2s in args.pay_to_script: try: script = h2b(p2s) p2sh_lookup[hash160(script)] = script except Exception: print("warning: error parsing pay-to-script value %s" % p2s) if args.pay_to_script_file: hex_re = re.compile(r"[0-9a-fA-F]+") for f in args.pay_to_script_file: count = 0 for l in f: try: m = hex_re.search(l) if m: p2s = m.group(0) script = h2b(p2s) p2sh_lookup[hash160(script)] = script count += 1 except Exception: print("warning: error parsing pay-to-script file %s" % f.name) if count == 0: print("warning: no scripts found in %s" % f.name) # we create the tx_db lazily tx_db = None for arg in args.argument: # hex transaction id if TX_ID_RE.match(arg): if tx_db is None: warning_tx_cache = message_about_tx_cache_env() warning_tx_for_tx_hash = message_about_tx_for_tx_hash_env( args.network) tx_db = get_tx_db(args.network) tx = tx_db.get(h2b_rev(arg)) if not tx: for m in [ warning_tx_cache, warning_tx_for_tx_hash, warning_spendables ]: if m: print("warning: %s" % m, file=sys.stderr) parser.error("can't find Tx with id %s" % arg) txs.append(tx) continue # hex transaction data try: tx = Tx.from_hex(arg) txs.append(tx) continue except Exception: pass is_valid = is_address_valid(arg, allowable_netcodes=[args.network]) if is_valid: payables.append((arg, 0)) continue try: key = Key.from_text(arg) # TODO: check network if key.wif() is None: payables.append((key.address(), 0)) continue # TODO: support paths to subkeys key_iters.append((k.wif() for k in key.subkeys(""))) continue except Exception: pass if os.path.exists(arg): try: with open(arg, "rb") as f: if f.name.endswith("hex"): f = io.BytesIO(codecs.getreader("hex_codec")(f).read()) tx = Tx.parse(f) txs.append(tx) try: tx.parse_unspents(f) except Exception as ex: pass continue except Exception: pass parts = arg.split("/") if len(parts) == 4: # spendable try: spendables.append(Spendable.from_text(arg)) continue except Exception: pass if len(parts) == 2 and is_address_valid( parts[0], allowable_netcodes=[args.network]): try: payables.append(parts) continue except ValueError: pass parser.error("can't parse %s" % arg) if args.fetch_spendables: warning_spendables = message_about_spendables_for_address_env( args.network) for address in args.fetch_spendables: spendables.extend(spendables_for_address(address)) for tx in txs: if tx.missing_unspents() and args.augment: if tx_db is None: warning_tx_cache = message_about_tx_cache_env() warning_tx_for_tx_hash = message_about_tx_for_tx_hash_env( args.network) tx_db = get_tx_db(args.network) tx.unspents_from_db(tx_db, ignore_missing=True) return (txs, spendables, payables, key_iters, p2sh_lookup, tx_db, warning_tx_cache, warning_tx_for_tx_hash, warning_spendables)
def set_address_error(self, addr): netcode = self.chain.netcode is_valid = addr.strip() and validate.is_address_valid( addr.strip(), ["address", "pay_to_script"], [netcode]) == netcode self.root.ids.address_input.error = not is_valid
def main(): global wallet, history print "PYCOIN_WALLET---" pswd = getpass("Enter Passphrase: ") master_secret = create_master_secret(pswd, "") wallet = BIP32Node.from_master_secret(master_secret, netcode=NETCODE) my_pcode_node = get_new_nodes(None, None, pcode=True) my_pcode_nosuffix = node_to_pcode_nosuffix(my_pcode_node) my_pcode_b58 = pcode_to_b58( pcode_add_suffix(my_pcode_nosuffix) ) print "My Payment Code:", my_pcode_b58 payees = load_dat("payees") my_notif_node = my_pcode_node.subkey_for_path("0/0") my_notif_addr = my_notif_node.address() response = json.load( urlopen("http://%s.blockr.io/api/v1/address/txs/" % BLOCKR + my_notif_addr) ) time.sleep(1) # Don't overload blockr.io API history[my_notif_addr] = response['data']['txs'] payers = populate_pcodes_from_notif(my_notif_node) wallet_nodes = init_nodes() change_nodes = init_nodes() populate_all_nodes(wallet_nodes, GAP_LIMIT) populate_all_nodes(change_nodes, GAP_LIMIT, change=True) populate_unspents(wallet_nodes) populate_unspents(change_nodes) print "Balance: %f %s" % ( balance, SYMBOL ) print "\nUnused wallet addresses:" nodelist = sorted( wallet_nodes['unused'].values(), key=itemgetter('index') ) for node in nodelist[:10]: print "%d %s" % ( node['index'], node['key'].address() ) if balance == 0: sys.exit(0) print "\nUsed address history:" nodelist = sorted( wallet_nodes['used'].values(), key=itemgetter('index') ) for node in nodelist: addr = node['key'].address() print "%d %s" % ( node['index'], addr ) for txs in history[addr]: print " TXID: %s" % txs['tx'] print " Amount: %f %s" % ( txs['amount'], SYMBOL ) print " Confs: %d" % txs['confirmations'] print print "Would you like to send %s?" % SYMBOL if not yorn(): sys.exit(0) amount = decput("Enter an amount: ") print "\nWho would you like to send %s to?:" % SYMBOL print "1.) A normal %s address" % SYMBOL print "2.) Create a new payee" payee_names = sorted( payees.keys() ) index = 3 for payee in payee_names: print "%d.) Send to '%s'" % ( index, payee ) index += 1 choice = intput("$ ") if choice == 1: spend_addr = raw_input("Enter an address: ") assert validate.is_address_valid(spend_addr) print "Sending %f %s to %s." % ( amount, SYMBOL, spend_addr ) tx = mktx(amount, spend_addr, wallet_nodes, change_nodes, DEFAULT_FEE) txid = sendtx(tx) print "TXID: ", txid elif choice == 2: payee_name = raw_input("Enter the payee's name: ") assert payee_name not in payees.keys() payee_pcode = raw_input("Enter a payment code: ") payees[payee_name] = payee_pcode payee_pcode_node = pcode_to_public_node(payee_pcode) notif_tx = mk_notif_tx(my_pcode_node, payee_pcode_node, \ wallet_nodes, change_nodes, DEFAULT_FEE) print "Sending Notification TX..." print notif_tx.as_hex() # txid = sendtx(tx) # print "TXID: ", txid dump_dat(payees, "payees") else: payee_name = payee_names[choice-4] payee_pcode = payees[payee_name] print payee_pcode sys.exit(0)
def parse_context(args, parser): # defaults txs = [] spendables = [] payables = [] key_iters = [] TX_ID_RE = re.compile(r"^[0-9a-fA-F]{64}$") # there are a few warnings we might optionally print out, but only if # they are relevant. We don't want to print them out multiple times, so we # collect them here and print them at the end if they ever kick in. warning_tx_cache = None warning_tx_for_tx_hash = None warning_spendables = None if args.private_key_file: wif_re = re.compile(r"[1-9a-km-zA-LMNP-Z]{51,111}") # address_re = re.compile(r"[1-9a-kmnp-zA-KMNP-Z]{27-31}") for f in args.private_key_file: if f.name.endswith(".gpg"): gpg_args = ["gpg", "-d"] if args.gpg_argument: gpg_args.extend(args.gpg_argument.split()) gpg_args.append(f.name) popen = subprocess.Popen(gpg_args, stdout=subprocess.PIPE) f = popen.stdout for line in f.readlines(): # decode if isinstance(line, bytes): line = line.decode("utf8") # look for WIFs possible_keys = wif_re.findall(line) def make_key(x): try: return Key.from_text(x) except Exception: return None keys = [make_key(x) for x in possible_keys] for key in keys: if key: key_iters.append((k.wif() for k in key.subkeys(""))) # if len(keys) == 1 and key.hierarchical_wallet() is None: # # we have exactly 1 WIF. Let's look for an address # potential_addresses = address_re.findall(line) # update p2sh_lookup p2sh_lookup = {} if args.pay_to_script: for p2s in args.pay_to_script: try: script = h2b(p2s) p2sh_lookup[hash160(script)] = script except Exception: print("warning: error parsing pay-to-script value %s" % p2s) if args.pay_to_script_file: hex_re = re.compile(r"[0-9a-fA-F]+") for f in args.pay_to_script_file: count = 0 for l in f: try: m = hex_re.search(l) if m: p2s = m.group(0) script = h2b(p2s) p2sh_lookup[hash160(script)] = script count += 1 except Exception: print("warning: error parsing pay-to-script file %s" % f.name) if count == 0: print("warning: no scripts found in %s" % f.name) # we create the tx_db lazily tx_db = None for arg in args.argument: # hex transaction id if TX_ID_RE.match(arg): if tx_db is None: warning_tx_cache = message_about_tx_cache_env() warning_tx_for_tx_hash = message_about_tx_for_tx_hash_env(args.network) tx_db = get_tx_db(args.network) tx = tx_db.get(h2b_rev(arg)) if not tx: for m in [warning_tx_cache, warning_tx_for_tx_hash, warning_spendables]: if m: print("warning: %s" % m, file=sys.stderr) parser.error("can't find Tx with id %s" % arg) txs.append(tx) continue # hex transaction data try: tx = Tx.from_hex(arg) txs.append(tx) continue except Exception: pass is_valid = is_address_valid(arg, allowable_netcodes=[args.network]) if is_valid: payables.append((arg, 0)) continue try: key = Key.from_text(arg) # TODO: check network if key.wif() is None: payables.append((key.address(), 0)) continue # TODO: support paths to subkeys key_iters.append((k.wif() for k in key.subkeys(""))) continue except Exception: pass if os.path.exists(arg): try: with open(arg, "rb") as f: if f.name.endswith("hex"): f = io.BytesIO(codecs.getreader("hex_codec")(f).read()) tx = Tx.parse(f) txs.append(tx) try: tx.parse_unspents(f) except Exception as ex: pass continue except Exception: pass parts = arg.split("/") if len(parts) == 4: # spendable try: spendables.append(Spendable.from_text(arg)) continue except Exception: pass if len(parts) == 2 and is_address_valid(parts[0], allowable_netcodes=[args.network]): try: payables.append(parts) continue except ValueError: pass parser.error("can't parse %s" % arg) if args.fetch_spendables: warning_spendables = message_about_spendables_for_address_env(args.network) for address in args.fetch_spendables: spendables.extend(spendables_for_address(address)) for tx in txs: if tx.missing_unspents() and args.augment: if tx_db is None: warning_tx_cache = message_about_tx_cache_env() warning_tx_for_tx_hash = message_about_tx_for_tx_hash_env(args.network) tx_db = get_tx_db(args.network) tx.unspents_from_db(tx_db, ignore_missing=True) return (txs, spendables, payables, key_iters, p2sh_lookup, tx_db, warning_tx_cache, warning_tx_for_tx_hash, warning_spendables)
def validate_ltc(self, addr): if self.network == 'testnet': return is_address_valid(addr) == 'XTN' return is_address_valid(addr) == 'LTC'
def main(): parser = argparse.ArgumentParser( description="Manipulate bitcoin (or alt coin) transactions.", epilog=EPILOG) parser.add_argument('-t', "--transaction-version", type=int, help='Transaction version, either 1 (default) or 3 (not yet supported).') parser.add_argument('-l', "--lock-time", type=parse_locktime, help='Lock time; either a block' 'index, or a date/time (example: "2014-01-01T15:00:00"') parser.add_argument('-n', "--network", default="BTC", help='Define network code (M=Bitcoin mainnet, T=Bitcoin testnet).') parser.add_argument('-a', "--augment", action='store_true', help='augment tx by adding any missing spendable metadata by fetching' ' inputs from cache and/or web services') parser.add_argument('-s', "--verbose-signature", action='store_true', help='Display technical signature details.') parser.add_argument("-i", "--fetch-spendables", metavar="address", action="append", help='Add all unspent spendables for the given bitcoin address. This information' ' is fetched from web services.') parser.add_argument('-f', "--private-key-file", metavar="path-to-private-keys", action="append", help='file containing WIF or BIP0032 private keys. If file name ends with .gpg, ' '"gpg -d" will be invoked automatically. File is read one line at a time, and if ' 'the file contains only one WIF per line, it will also be scanned for a bitcoin ' 'address, and any addresses found will be assumed to be public keys for the given' ' private key.', type=argparse.FileType('r')) parser.add_argument('-g', "--gpg-argument", help='argument to pass to gpg (besides -d).', default='') parser.add_argument("--remove-tx-in", metavar="tx_in_index_to_delete", action="append", type=int, help='remove a tx_in') parser.add_argument("--remove-tx-out", metavar="tx_out_index_to_delete", action="append", type=int, help='remove a tx_out') parser.add_argument('-F', "--fee", help='fee, in satoshis, to pay on transaction, or ' '"standard" to auto-calculate. This is only useful if the "split pool" ' 'is used; otherwise, the fee is automatically set to the unclaimed funds.', default="standard", metavar="transaction-fee", type=parse_fee) parser.add_argument('-C', "--cache", help='force the resultant transaction into the transaction cache.' ' Mostly for testing.', action='store_true'), parser.add_argument('-u', "--show-unspents", action='store_true', help='show TxOut items for this transaction in Spendable form.') parser.add_argument('-b', "--bitcoind-url", help='URL to bitcoind instance to validate against (http://user:pass@host:port).') parser.add_argument('-o', "--output-file", metavar="path-to-output-file", type=argparse.FileType('wb'), help='file to write transaction to. This supresses most other output.') parser.add_argument('-d', "--disassemble", action='store_true', help='Disassemble scripts.') parser.add_argument("--trace", action='store_true', help='Trace scripts.') parser.add_argument('-p', "--pay-to-script", metavar="pay-to-script", action="append", help='a hex version of a script required for a pay-to-script input (a bitcoin address that starts with 3)') parser.add_argument('-P', "--pay-to-script-file", metavar="pay-to-script-file", nargs=1, type=argparse.FileType('r'), help='a file containing hex scripts (one per line) corresponding to pay-to-script inputs') parser.add_argument("argument", nargs="+", help='generic argument: can be a hex transaction id ' '(exactly 64 characters) to be fetched from cache or a web service;' ' a transaction as a hex string; a path name to a transaction to be loaded;' ' a spendable 4-tuple of the form tx_id/tx_out_idx/script_hex/satoshi_count ' 'to be added to TxIn list; an address/satoshi_count to be added to the TxOut ' 'list; an address to be added to the TxOut list and placed in the "split' ' pool".') args = parser.parse_args() # defaults txs = [] spendables = [] payables = [] key_iters = [] TX_ID_RE = re.compile(r"^[0-9a-fA-F]{64}$") # there are a few warnings we might optionally print out, but only if # they are relevant. We don't want to print them out multiple times, so we # collect them here and print them at the end if they ever kick in. warning_tx_cache = None warning_tx_for_tx_hash = None warning_spendables = None if args.private_key_file: wif_re = re.compile(r"[1-9a-km-zA-LMNP-Z]{51,111}") # address_re = re.compile(r"[1-9a-kmnp-zA-KMNP-Z]{27-31}") for f in args.private_key_file: if f.name.endswith(".gpg"): gpg_args = ["gpg", "-d"] if args.gpg_argument: gpg_args.extend(args.gpg_argument.split()) gpg_args.append(f.name) popen = subprocess.Popen(gpg_args, stdout=subprocess.PIPE) f = popen.stdout for line in f.readlines(): # decode if isinstance(line, bytes): line = line.decode("utf8") # look for WIFs possible_keys = wif_re.findall(line) def make_key(x): try: return Key.from_text(x) except Exception: return None keys = [make_key(x) for x in possible_keys] for key in keys: if key: key_iters.append((k.wif() for k in key.subkeys(""))) # if len(keys) == 1 and key.hierarchical_wallet() is None: # # we have exactly 1 WIF. Let's look for an address # potential_addresses = address_re.findall(line) # update p2sh_lookup p2sh_lookup = {} if args.pay_to_script: for p2s in args.pay_to_script: try: script = h2b(p2s) p2sh_lookup[hash160(script)] = script except Exception: print("warning: error parsing pay-to-script value %s" % p2s) if args.pay_to_script_file: hex_re = re.compile(r"[0-9a-fA-F]+") for f in args.pay_to_script_file: count = 0 for l in f: try: m = hex_re.search(l) if m: p2s = m.group(0) script = h2b(p2s) p2sh_lookup[hash160(script)] = script count += 1 except Exception: print("warning: error parsing pay-to-script file %s" % f.name) if count == 0: print("warning: no scripts found in %s" % f.name) # we create the tx_db lazily tx_db = None for arg in args.argument: # hex transaction id if TX_ID_RE.match(arg): if tx_db is None: warning_tx_cache = message_about_tx_cache_env() warning_tx_for_tx_hash = message_about_tx_for_tx_hash_env(args.network) tx_db = get_tx_db(args.network) tx = tx_db.get(h2b_rev(arg)) if not tx: for m in [warning_tx_cache, warning_tx_for_tx_hash, warning_spendables]: if m: print("warning: %s" % m, file=sys.stderr) parser.error("can't find Tx with id %s" % arg) txs.append(tx) continue # hex transaction data try: tx = Tx.from_hex(arg) txs.append(tx) continue except Exception: pass is_valid = is_address_valid(arg, allowable_netcodes=[args.network]) if is_valid: payables.append((arg, 0)) continue try: key = Key.from_text(arg) # TODO: check network if key.wif() is None: payables.append((key.address(), 0)) continue # TODO: support paths to subkeys key_iters.append((k.wif() for k in key.subkeys(""))) continue except Exception: pass if os.path.exists(arg): try: with open(arg, "rb") as f: if f.name.endswith("hex"): f = io.BytesIO(codecs.getreader("hex_codec")(f).read()) tx = Tx.parse(f) txs.append(tx) try: tx.parse_unspents(f) except Exception as ex: pass continue except Exception: pass parts = arg.split("/") if len(parts) == 4: # spendable try: spendables.append(Spendable.from_text(arg)) continue except Exception: pass if len(parts) == 2 and is_address_valid(parts[0], allowable_netcodes=[args.network]): try: payables.append(parts) continue except ValueError: pass parser.error("can't parse %s" % arg) if args.fetch_spendables: warning_spendables = message_about_spendables_for_address_env(args.network) for address in args.fetch_spendables: spendables.extend(spendables_for_address(address)) for tx in txs: if tx.missing_unspents() and args.augment: if tx_db is None: warning_tx_cache = message_about_tx_cache_env() warning_tx_for_tx_hash = message_about_tx_for_tx_hash_env(args.network) tx_db = get_tx_db(args.network) tx.unspents_from_db(tx_db, ignore_missing=True) txs_in = [] txs_out = [] unspents = [] # we use a clever trick here to keep each tx_in corresponding with its tx_out for tx in txs: smaller = min(len(tx.txs_in), len(tx.txs_out)) txs_in.extend(tx.txs_in[:smaller]) txs_out.extend(tx.txs_out[:smaller]) unspents.extend(tx.unspents[:smaller]) for tx in txs: smaller = min(len(tx.txs_in), len(tx.txs_out)) txs_in.extend(tx.txs_in[smaller:]) txs_out.extend(tx.txs_out[smaller:]) unspents.extend(tx.unspents[smaller:]) for spendable in spendables: txs_in.append(spendable.tx_in()) unspents.append(spendable) for address, coin_value in payables: script = standard_tx_out_script(address) txs_out.append(TxOut(coin_value, script)) lock_time = args.lock_time version = args.transaction_version # if no lock_time is explicitly set, inherit from the first tx or use default if lock_time is None: if txs: lock_time = txs[0].lock_time else: lock_time = DEFAULT_LOCK_TIME # if no version is explicitly set, inherit from the first tx or use default if version is None: if txs: version = txs[0].version else: version = DEFAULT_VERSION if args.remove_tx_in: s = set(args.remove_tx_in) txs_in = [tx_in for idx, tx_in in enumerate(txs_in) if idx not in s] if args.remove_tx_out: s = set(args.remove_tx_out) txs_out = [tx_out for idx, tx_out in enumerate(txs_out) if idx not in s] tx = Tx(txs_in=txs_in, txs_out=txs_out, lock_time=lock_time, version=version, unspents=unspents) fee = args.fee try: distribute_from_split_pool(tx, fee) except ValueError as ex: print("warning: %s" % ex.args[0], file=sys.stderr) unsigned_before = tx.bad_signature_count() unsigned_after = unsigned_before if unsigned_before > 0 and key_iters: def wif_iter(iters): while len(iters) > 0: for idx, iter in enumerate(iters): try: wif = next(iter) yield wif except StopIteration: iters = iters[:idx] + iters[idx+1:] break print("signing...", file=sys.stderr) sign_tx(tx, wif_iter(key_iters), p2sh_lookup=p2sh_lookup) unsigned_after = tx.bad_signature_count() if unsigned_after > 0: print("warning: %d TxIn items still unsigned" % unsigned_after, file=sys.stderr) if len(tx.txs_in) == 0: print("warning: transaction has no inputs", file=sys.stderr) if len(tx.txs_out) == 0: print("warning: transaction has no outputs", file=sys.stderr) include_unspents = (unsigned_after > 0) tx_as_hex = tx.as_hex(include_unspents=include_unspents) if args.output_file: f = args.output_file if f.name.endswith(".hex"): f.write(tx_as_hex.encode("utf8")) else: tx.stream(f) if include_unspents: tx.stream_unspents(f) f.close() elif args.show_unspents: for spendable in tx.tx_outs_as_spendable(): print(spendable.as_text()) else: if not tx.missing_unspents(): check_fees(tx) dump_tx(tx, args.network, args.verbose_signature, args.disassemble, args.trace) if include_unspents: print("including unspents in hex dump since transaction not fully signed") print(tx_as_hex) if args.cache: if tx_db is None: warning_tx_cache = message_about_tx_cache_env() warning_tx_for_tx_hash = message_about_tx_for_tx_hash_env(args.network) tx_db = get_tx_db(args.network) tx_db.put(tx) if args.bitcoind_url: if tx_db is None: warning_tx_cache = message_about_tx_cache_env() warning_tx_for_tx_hash = message_about_tx_for_tx_hash_env(args.network) tx_db = get_tx_db(args.network) validate_bitcoind(tx, tx_db, args.bitcoind_url) if tx.missing_unspents(): print("\n** can't validate transaction as source transactions missing", file=sys.stderr) else: try: if tx_db is None: warning_tx_cache = message_about_tx_cache_env() warning_tx_for_tx_hash = message_about_tx_for_tx_hash_env(args.network) tx_db = get_tx_db(args.network) tx.validate_unspents(tx_db) print('all incoming transaction values validated') except BadSpendableError as ex: print("\n**** ERROR: FEES INCORRECTLY STATED: %s" % ex.args[0], file=sys.stderr) except Exception as ex: print("\n*** can't validate source transactions as untampered: %s" % ex.args[0], file=sys.stderr) # print warnings for m in [warning_tx_cache, warning_tx_for_tx_hash, warning_spendables]: if m: print("warning: %s" % m, file=sys.stderr)
def validate_address(self, address): netcodes = ['XTN'] if self.testnet else ['BTC'] return bool(is_address_valid(address, allowable_netcodes=netcodes))
def test_cycle(insight_url): BATCH_FILE = '_test-batch.txs' BATCH_FILE_SIGNED = '_test-batch-signed.txs' try: os.remove(BATCH_FILE) except: pass try: os.remove(BATCH_FILE_SIGNED) except: pass insight_service = InsightBatchService(insight_url) seeds_hex = get_test_hex_seeds() xpubs = get_test_master_xpub_strings() # getting first addresss, making sure funds are on it process = subprocess.Popen([ 'python', './recovery', 'address', '--origin', '%s,%s,%s' % (seeds_hex[1], xpubs[2], xpubs[3]), '--path', '0/0/0', ], stdout=subprocess.PIPE) process.wait() deposit_address = process.communicate()[0].strip()[-34:] print "[test] Working with testing address", deposit_address assert is_address_valid(deposit_address) if not insight_service.spendables_for_address(deposit_address): print "[test] No coins on target address to recover. Please deposit a small amount." exit(0) print "\n\n[test] Creating batch" # creating a batch process = subprocess.Popen([ 'python', './recovery', 'create', '--origin', '%s,%s,%s' % (seeds_hex[1], xpubs[2], xpubs[3]), '--destination', '%s,%s,%s' % (seeds_hex[1], xpubs[2], xpubs[3]), '--insight', insight_url, '--save', BATCH_FILE, ]) process.wait() print "\n\n[test] Adding second signature", BATCH_FILE process = subprocess.Popen([ 'python', './recovery', 'cosign', '--load', BATCH_FILE, '--private', seeds_hex[2], '--save', BATCH_FILE_SIGNED, ]) process.wait() # broadcasting print "\n\n[test] Broadcasting", BATCH_FILE process = subprocess.Popen([ 'python', './recovery', 'broadcast', '--load', BATCH_FILE_SIGNED, '--insight', insight_url, ], stdout=subprocess.PIPE) process.wait() stdout, stderr = process.communicate() print stdout if stderr: print stderr else: last_line = stdout.strip().split('\n')[-1] try: _, txhash, bytes = last_line.split(' ') except: print "\n[test] no tx propagated" exit(1) print "\n\n[test] waiting for new tx to show in bitcoin mempool:", while True: try: found_tx = insight_service.get_tx(h2b_rev(txhash)) break except HTTPError: print '.', print 'found.', found_tx, '\n\n', '[test] Coins successfuly moved'
def create_transaction(event, context): """ :param event: :param context: :return: """ log.debug("Received event in Create: %s", event) request_body = event['body'] if isinstance(request_body, basestring): try: request_body = json.loads(request_body) except TypeError: return { 'statusCode': BAD_REQUEST, 'headers': headers, 'body': json.dumps({'message': 'Cannot decode JSON'}) } except ValueError: return { 'statusCode': BAD_REQUEST, 'headers': headers, 'body': json.dumps({'message': 'Bad request (no body)'}) } elif isinstance(request_body, dict): log.debug("Body type was dict; assuming test request") pass else: return { 'statusCode': BAD_REQUEST, 'headers': headers, 'body': json.dumps( {'message': "Bad type for body: %s" % type(request_body)}) } if "address" not in request_body: return { 'statusCode': BAD_REQUEST, 'headers': headers, 'body': json.dumps({'message': 'No Address'}) } is_good_address = pycoin_validator.is_address_valid( address=request_body['address']) if not is_good_address: return { 'statusCode': BAD_REQUEST, 'headers': headers, 'body': json.dumps({ 'message': 'Not a valid address: %s' % request_body['address'] }) } try: tx = QPagosPurchase(initial="price_quoted", request_context=event['requestContext'], **request_body) except TxInstantiationException, tie: return { 'statusCode': BAD_REQUEST, 'headers': headers, 'body': tie.to_json() }
def main(): parser = argparse.ArgumentParser( description="Manipulate bitcoin (or alt coin) transactions.", epilog=EPILOG) parser.add_argument( '-t', "--transaction-version", type=int, help='Transaction version, either 1 (default) or 3 (not yet supported).' ) parser.add_argument( '-l', "--lock-time", type=parse_locktime, help='Lock time; either a block' 'index, or a date/time (example: "2014-01-01T15:00:00"') parser.add_argument( '-n', "--network", default="BTC", help='Define network code (M=Bitcoin mainnet, T=Bitcoin testnet).') parser.add_argument( '-a', "--augment", action='store_true', help='augment tx by adding any missing spendable metadata by fetching' ' inputs from cache and/or web services') parser.add_argument( "-i", "--fetch-spendables", metavar="address", action="append", help= 'Add all unspent spendables for the given bitcoin address. This information' ' is fetched from web services.') parser.add_argument( '-f', "--private-key-file", metavar="path-to-private-keys", action="append", help= 'file containing WIF or BIP0032 private keys. If file name ends with .gpg, ' '"gpg -d" will be invoked automatically. File is read one line at a time, and if ' 'the file contains only one WIF per line, it will also be scanned for a bitcoin ' 'address, and any addresses found will be assumed to be public keys for the given' ' private key.', type=argparse.FileType('r')) parser.add_argument('-g', "--gpg-argument", help='argument to pass to gpg (besides -d).', default='') parser.add_argument("--remove-tx-in", metavar="tx_in_index_to_delete", action="append", type=int, help='remove a tx_in') parser.add_argument("--remove-tx-out", metavar="tx_out_index_to_delete", action="append", type=int, help='remove a tx_out') parser.add_argument( '-F', "--fee", help='fee, in satoshis, to pay on transaction, or ' '"standard" to auto-calculate. This is only useful if the "split pool" ' 'is used; otherwise, the fee is automatically set to the unclaimed funds.', default="standard", metavar="transaction-fee", type=parse_fee) parser.add_argument( '-C', "--cache", help='force the resultant transaction into the transaction cache.' ' Mostly for testing.', action='store_true'), parser.add_argument( '-u', "--show-unspents", action='store_true', help='show TxOut items for this transaction in Spendable form.') parser.add_argument( '-b', "--bitcoind-url", help= 'URL to bitcoind instance to validate against (http://user:pass@host:port).' ) parser.add_argument( '-o', "--output-file", metavar="path-to-output-file", type=argparse.FileType('wb'), help='file to write transaction to. This supresses most other output.') parser.add_argument( '-p', "--pay-to-script", metavar="pay-to-script", action="append", help= 'a hex version of a script required for a pay-to-script input (a bitcoin address that starts with 3)' ) parser.add_argument( '-P', "--pay-to-script-file", metavar="pay-to-script-file", nargs=1, type=argparse.FileType('r'), help= 'a file containing hex scripts (one per line) corresponding to pay-to-script inputs' ) parser.add_argument( "argument", nargs="+", help='generic argument: can be a hex transaction id ' '(exactly 64 characters) to be fetched from cache or a web service;' ' a transaction as a hex string; a path name to a transaction to be loaded;' ' a spendable 4-tuple of the form tx_id/tx_out_idx/script_hex/satoshi_count ' 'to be added to TxIn list; an address/satoshi_count to be added to the TxOut ' 'list; an address to be added to the TxOut list and placed in the "split' ' pool".') args = parser.parse_args() # defaults txs = [] spendables = [] payables = [] key_iters = [] TX_ID_RE = re.compile(r"^[0-9a-fA-F]{64}$") # there are a few warnings we might optionally print out, but only if # they are relevant. We don't want to print them out multiple times, so we # collect them here and print them at the end if they ever kick in. warning_tx_cache = None warning_get_tx = None warning_spendables = None if args.private_key_file: wif_re = re.compile(r"[1-9a-km-zA-LMNP-Z]{51,111}") # address_re = re.compile(r"[1-9a-kmnp-zA-KMNP-Z]{27-31}") for f in args.private_key_file: if f.name.endswith(".gpg"): gpg_args = ["gpg", "-d"] if args.gpg_argument: gpg_args.extend(args.gpg_argument.split()) gpg_args.append(f.name) popen = subprocess.Popen(gpg_args, stdout=subprocess.PIPE) f = popen.stdout for line in f.readlines(): # decode if isinstance(line, bytes): line = line.decode("utf8") # look for WIFs possible_keys = wif_re.findall(line) def make_key(x): try: return Key.from_text(x) except Exception: return None keys = [make_key(x) for x in possible_keys] for key in keys: if key: key_iters.append((k.wif() for k in key.subkeys(""))) # if len(keys) == 1 and key.hierarchical_wallet() is None: # # we have exactly 1 WIF. Let's look for an address # potential_addresses = address_re.findall(line) # update p2sh_lookup p2sh_lookup = {} if args.pay_to_script: for p2s in args.pay_to_script: try: script = h2b(p2s) p2sh_lookup[hash160(script)] = script except Exception: print("warning: error parsing pay-to-script value %s" % p2s) if args.pay_to_script_file: hex_re = re.compile(r"[0-9a-fA-F]+") for f in args.pay_to_script_file: count = 0 for l in f: try: m = hex_re.search(l) if m: p2s = m.group(0) script = h2b(p2s) p2sh_lookup[hash160(script)] = script count += 1 except Exception: print("warning: error parsing pay-to-script file %s" % f.name) if count == 0: print("warning: no scripts found in %s" % f.name) # we create the tx_db lazily tx_db = None for arg in args.argument: # hex transaction id if TX_ID_RE.match(arg): if tx_db is None: warning_tx_cache = message_about_tx_cache_env() warning_get_tx = message_about_get_tx_env() tx_db = get_tx_db() tx = tx_db.get(h2b_rev(arg)) if not tx: for m in [ warning_tx_cache, warning_get_tx, warning_spendables ]: if m: print("warning: %s" % m, file=sys.stderr) parser.error("can't find Tx with id %s" % arg) txs.append(tx) continue # hex transaction data try: tx = Tx.tx_from_hex(arg) txs.append(tx) continue except Exception: pass is_valid = is_address_valid(arg, allowable_netcodes=[args.network]) if is_valid: payables.append((arg, 0)) continue try: key = Key.from_text(arg) # TODO: check network if key.wif() is None: payables.append((key.address(), 0)) continue # TODO: support paths to subkeys key_iters.append((k.wif() for k in key.subkeys(""))) continue except Exception: pass if os.path.exists(arg): try: with open(arg, "rb") as f: if f.name.endswith("hex"): f = io.BytesIO(codecs.getreader("hex_codec")(f).read()) tx = Tx.parse(f) txs.append(tx) try: tx.parse_unspents(f) except Exception as ex: pass continue except Exception: pass parts = arg.split("/") if len(parts) == 4: # spendable try: spendables.append(Spendable.from_text(arg)) continue except Exception: pass if len(parts) == 2 and is_address_valid( parts[0], allowable_netcodes=[args.network]): try: payables.append(parts) continue except ValueError: pass parser.error("can't parse %s" % arg) if args.fetch_spendables: warning_spendables = message_about_spendables_for_address_env() for address in args.fetch_spendables: spendables.extend(spendables_for_address(address)) for tx in txs: if tx.missing_unspents() and args.augment: if tx_db is None: warning_tx_cache = message_about_tx_cache_env() warning_get_tx = message_about_get_tx_env() tx_db = get_tx_db() tx.unspents_from_db(tx_db, ignore_missing=True) txs_in = [] txs_out = [] unspents = [] # we use a clever trick here to keep each tx_in corresponding with its tx_out for tx in txs: smaller = min(len(tx.txs_in), len(tx.txs_out)) txs_in.extend(tx.txs_in[:smaller]) txs_out.extend(tx.txs_out[:smaller]) unspents.extend(tx.unspents[:smaller]) for tx in txs: smaller = min(len(tx.txs_in), len(tx.txs_out)) txs_in.extend(tx.txs_in[smaller:]) txs_out.extend(tx.txs_out[smaller:]) unspents.extend(tx.unspents[smaller:]) for spendable in spendables: txs_in.append(spendable.tx_in()) unspents.append(spendable) for address, coin_value in payables: script = standard_tx_out_script(address) txs_out.append(TxOut(coin_value, script)) lock_time = args.lock_time version = args.transaction_version # if no lock_time is explicitly set, inherit from the first tx or use default if lock_time is None: if txs: lock_time = txs[0].lock_time else: lock_time = DEFAULT_LOCK_TIME # if no version is explicitly set, inherit from the first tx or use default if version is None: if txs: version = txs[0].version else: version = DEFAULT_VERSION if args.remove_tx_in: s = set(args.remove_tx_in) txs_in = [tx_in for idx, tx_in in enumerate(txs_in) if idx not in s] if args.remove_tx_out: s = set(args.remove_tx_out) txs_out = [ tx_out for idx, tx_out in enumerate(txs_out) if idx not in s ] tx = Tx(txs_in=txs_in, txs_out=txs_out, lock_time=lock_time, version=version, unspents=unspents) fee = args.fee try: distribute_from_split_pool(tx, fee) except ValueError as ex: print("warning: %s" % ex.args[0], file=sys.stderr) unsigned_before = tx.bad_signature_count() if unsigned_before > 0 and key_iters: def wif_iter(iters): while len(iters) > 0: for idx, iter in enumerate(iters): try: wif = next(iter) yield wif except StopIteration: iters = iters[:idx] + iters[idx + 1:] break print("signing...", file=sys.stderr) sign_tx(tx, wif_iter(key_iters), p2sh_lookup=p2sh_lookup) unsigned_after = tx.bad_signature_count() if unsigned_after > 0 and key_iters: print("warning: %d TxIn items still unsigned" % unsigned_after, file=sys.stderr) if len(tx.txs_in) == 0: print("warning: transaction has no inputs", file=sys.stderr) if len(tx.txs_out) == 0: print("warning: transaction has no outputs", file=sys.stderr) include_unspents = (unsigned_after > 0) tx_as_hex = tx.as_hex(include_unspents=include_unspents) if args.output_file: f = args.output_file if f.name.endswith(".hex"): f.write(tx_as_hex.encode("utf8")) else: tx.stream(f) if include_unspents: tx.stream_unspents(f) f.close() elif args.show_unspents: for spendable in tx.tx_outs_as_spendable(): print(spendable.as_text()) else: if not tx.missing_unspents(): check_fees(tx) dump_tx(tx, args.network) if include_unspents: print( "including unspents in hex dump since transaction not fully signed" ) print(tx_as_hex) if args.cache: if tx_db is None: warning_tx_cache = message_about_tx_cache_env() warning_get_tx = message_about_get_tx_env() tx_db = get_tx_db() tx_db.put(tx) if args.bitcoind_url: if tx_db is None: warning_tx_cache = message_about_tx_cache_env() warning_get_tx = message_about_get_tx_env() tx_db = get_tx_db() validate_bitcoind(tx, tx_db, args.bitcoind_url) if tx.missing_unspents(): print("\n** can't validate transaction as source transactions missing", file=sys.stderr) else: try: if tx_db is None: warning_tx_cache = message_about_tx_cache_env() warning_get_tx = message_about_get_tx_env() tx_db = get_tx_db() tx.validate_unspents(tx_db) print('all incoming transaction values validated') except BadSpendableError as ex: print("\n**** ERROR: FEES INCORRECTLY STATED: %s" % ex.args[0], file=sys.stderr) except Exception as ex: print( "\n*** can't validate source transactions as untampered: %s" % ex.args[0], file=sys.stderr) # print warnings for m in [warning_tx_cache, warning_get_tx, warning_spendables]: if m: print("warning: %s" % m, file=sys.stderr)
def deposit(request): if request.method == "GET": html_dict = dict(form_capcha=CaptchaTestForm(), form_address=AddressForm(), current=request.path, client_id=gvars.client_id.lower()) unspent = [] try: unspent = json.loads( Popen([ 'coin-cli', '-rpcconnect={}_coind'.format( gvars.client_id.lower()), 'listunspent', '0' ], stdout=PIPE).communicate()[0]) unspent_filtered = [] for i in unspent: if i.get('amount') >= gvars.minimum_amount: unspent_filtered.append(i) except ValueError: #unspent_filtered = [] #TODO move this before try? logging.debug( 'ValueError in deposit.get 0 view.\nIs the coin daemon active?' ) request.session['error_message'] = general_error_message except OSError: #unspent_filtered = [] #TODO move this before try? logging.debug( 'OSError in deposit.get 0 view.\nIs the coin daemon installed?' ) request.session['error_message'] = general_error_message error_message = request.session.get('error_message', False) if error_message: html_dict.update(error_message=error_message) del request.session['error_message'] html_dict.update(count=len(unspent_filtered)) html_dict.update(csrf(request)) return render_to_response('deposit_get.html', html_dict) if request.method == 'POST': form = CaptchaTestForm(request.POST) # check valid capcha if not form.is_valid(): request.session['error_message'] = 'Invalid captcha.' return redirect('deposit') # check valid address if not is_address_valid( request.POST['return_address']) == gvars.client_id: request.session[ 'error_message'] = 'Invalid {} return address.'.format( gvars.client.title()) return redirect('deposit') # placed before internal address check on purpose try: deposit_address = Popen([ 'coin-cli', '-rpcconnect={}_coind'.format( gvars.client_id.lower()), "getnewaddress" ], stdout=PIPE).communicate()[0].strip() except ValueError: logging.debug( 'ValueError in deposit.post 0 view.\nIs the coin daemon active?' ) request.session['error_message'] = general_error_message # allow chaining if not gvars.chaining: try: internal_address_list = json.loads( Popen([ 'coin-cli', '-rpcconnect={}_coind'.format( gvars.client_id.lower()), 'getaddressesbyaccount', "" ], stdout=PIPE).communicate()[0]) except ValueError: logging.debug( 'ValueError in deposit.post 1 view.\nIs the coin daemon active?' ) request.session['error_message'] = general_error_message if request.POST['return_address'] in internal_address_list: request.session['error_message'] = 'Chain betting is disabled' return redirect('deposit') # create address model AddressModel.objects.create( deposit_address=deposit_address, return_address=request.POST['return_address']).save() html_dict = dict(deposit_address=deposit_address, minimum_amount=gvars.minimum_amount, client_id=gvars.client_id, client=gvars.client, current=request.path) return render_to_response('deposit_post.html', html_dict)
def test_standard(self): wif = self.api.create_key() address = self.api.get_address(wif) self.assertTrue( validate.is_address_valid(address, allowable_netcodes=['XTN']))
def validate_addr(self, addr): if settings.USE_TESTNET: if is_address_valid(addr) == 'XTN': return addr if is_address_valid(addr) == 'LTC': return addr