Example #1
0
 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])
Example #2
0
 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)
Example #3
0
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)
Example #4
0
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
Example #5
0
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()
    ]))
Example #6
0
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")
Example #7
0
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, end='')
        address = input()
        is_valid = is_address_valid(address)
        if is_valid:
            return address
        print("invalid address, please try again")
Example #9
0
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'
Example #10
0
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()
    ]))
Example #11
0
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
Example #12
0
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()
Example #14
0
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)
Example #15
0
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)
Example #16
0
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())
Example #18
0
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())
Example #19
0
	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})
Example #20
0
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
Example #21
0
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
Example #22
0
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
Example #23
0
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)
    ''''''
Example #24
0
    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))
Example #26
0
[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))
Example #27
0
    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)
Example #28
0
 def verifyAddress(self, address):
     if self.use_production:
         return is_address_valid(address) == "BTC"
     else:
         return is_address_valid(address) == "XTN"
Example #29
0
 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']))
Example #30
0
    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)
Example #32
0
    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})
Example #33
0
def test_get_funding_addresses():
    address = lib.get_funding_address()
    assert (is_address_valid(address, allowable_netcodes=["XTN"]))
Example #34
0
def test_get_funding_addresses():
    address = lib.get_funding_address()
    assert(is_address_valid(address, allowable_netcodes=["XTN"]))
Example #35
0
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
Example #36
0
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
Example #37
0
 def verifyAddress(self, address):
     if self.use_production:
         return is_address_valid(address) == "BTC"
     else:
         return is_address_valid(address) == "XTN"
Example #38
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)
Example #39
0
 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
Example #40
0
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)
Example #41
0
File: tx.py Project: Zibbo/pycoin
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)
Example #42
0
 def validate_ltc(self, addr):
     if self.network == 'testnet':
         return is_address_valid(addr) == 'XTN'
     return is_address_valid(addr) == 'LTC'
Example #43
0
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)
Example #44
0
 def validate_address(self, address):
     netcodes = ['XTN'] if self.testnet else ['BTC']
     return bool(is_address_valid(address, allowable_netcodes=netcodes))
Example #45
0
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'
Example #46
0
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()
        }
Example #47
0
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)
Example #48
0
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)
Example #49
0
 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']))
Example #50
0
 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