Пример #1
0
def get_blockchain_record(fqu):

    # hack to ensure local, until we update client
    from blockstack_client import client as bs_client
    # start session using blockstack_client
    bs_client.session(server_host=BLOCKSTACKD_IP, server_port=BLOCKSTACKD_PORT,
                      set_global=True)

    data = {}

    try:
        resp = bs_client.get_name_blockchain_record(fqu)
    except Exception as e:
        data['error'] = e
        return data

    return resp
Пример #2
0
def recipientNotReady(address):
    """
        Check if address can own more names or not
    """

    # hack to ensure local, until we update client
    from blockstack_client import client as bs_client
    # start session using blockstack_client
    bs_client.session(server_host=BLOCKSTACKD_IP, server_port=BLOCKSTACKD_PORT,
                      set_global=True)

    resp = bs_client.get_names_owned_by_address(address)
    names_owned = resp

    if len(names_owned) > MAXIMUM_NAMES_PER_ADDRESS:
        return True

    # if tests pass, then can use the address
    return False
Пример #3
0
def run_cli(argv=None, config_path=CONFIG_PATH):
    """
    Run a CLI command from arguments (defaults to sys.argv)
    Return the result of the command on success.
    The result will be a dict, and will have 'error' defined on error condition.
    """

    if argv is None:
        argv = sys.argv

    # only version?
    if '-v' in argv or '--version' in argv:
        print config.VERSION
        sys.exit(0)

    # alternative config path?
    if '-c' in argv or '--config' in argv:
        i = 1
        while i < len(argv):
            if argv[i] == '-c' or argv[i] == '--config':
                if i + 1 >= len(argv):
                    print >> sys.stderr, "%s: missing path" % argv[i]
                    sys.exit(1)

                config_path = argv[i+1]
                argv.pop(i)
                argv.pop(i)

            else:
                i+=1

    conf = config.get_config(path=config_path)

    if conf is None:
        return {'error': 'Failed to load config'}

    conf_version = conf.get('client_version', '')
    if not semver_match( conf_version, VERSION ):
        exit_with_error("Invalid configuration file: %s != %s" % (conf_version, VERSION), \
                "Your configuration file (%s) is out of date.  Please move it and try again in order to automatically generate a new config file." % config_path)

    advanced_mode = conf.get('advanced_mode', False)

    parser = argparse.ArgumentParser(
            description='Blockstack cli version {}'.format(config.VERSION))

    all_methods = []
    subparsers = parser.add_subparsers(dest='action')
    
    # add basic methods 
    basic_methods = get_cli_basic_methods()
    basic_method_info = parse_methods( basic_methods )
    build_method_subparsers( subparsers, basic_method_info )

    all_methods = basic_method_info 

    if advanced_mode:
        # add advanced methods 
        log.debug("Enabling advanced methods")
        advanced_methods = get_cli_advanced_methods()
        advanced_method_info = parse_methods( advanced_methods )
        build_method_subparsers( subparsers, advanced_method_info )
        all_methods += advanced_method_info

    # Print default help message, if no argument is given
    if len(argv) == 1 or '-h' in argv:
        parser.print_help()
        return {}

    interactive = False
    args = None
    directive = None

    try:
        args, unknown_args = parser.parse_known_args(args=argv[1:])
        directive = args.action
    except SystemExit:
        # bad arguments
        # special case: if the method is specified, but no method arguments are given,
        # then switch to prompting the user for individual arguments.
        try:
            directive_parser = argparse.ArgumentParser(description='Blockstack cli version {}'.format(config.VERSION))
            directive_subparsers = directive_parser.add_subparsers(dest='action')

            # only parse the directive
            build_method_subparsers( directive_subparsers, all_methods, include_args=False, include_opts=False ) 
            directive_args, directive_unknown_args = directive_parser.parse_known_args( args=argv[1:] )

            # want interactive prompting
            interactive = True
            directive = directive_args.action

        except SystemExit:
            # still invalid 
            parser.print_help()
            return {'error': 'Invalid arguments.  Try passing "-h".'}

    result = {}

    blockstack_server = conf['server']
    blockstack_port = conf['port']

    # initialize blockstack connection
    session(conf=conf, server_host=blockstack_server,
            server_port=blockstack_port, set_global=True)

    # dispatch to the apporpriate method  
    for method_info in all_methods:
        if directive != method_info['command']:
            continue

        method = method_info['method']
        
        # interactive?
        if interactive:
            print ""
            print "Interactive prompt engaged.  Press Ctrl+C to quit"
            print "Help for '%s': %s" % (method_info['command'], method_info['help'])
            print ""
            
            required_args = prompt_args( method_info['args'], lambda arghelp, argname: raw_input("%s ('%s'): " % (arghelp, argname)) )
            if required_args is None:
                return {'error': 'Failed to prompt for arguments'}

            optional_args = prompt_args( method_info['opts'], lambda arghelp, argname: raw_input("optional: %s ('%s'): " % (arghelp, argname) ))
            if optional_args is None:
                return {'error': 'Failed to prompt for arguments'}

            full_args = [method_info['command']] + required_args + optional_args
            try:
                args, unknown_args = parser.parse_known_args( args=full_args )
            except SystemExit:
                # invalid arguments
                return {'error': 'Invalid arguments.  Please try again.'}

        result = method( args, config_path=config_path )
        return result

    # not found 
    return {'error': "No such command '%s'" % args.action}
Пример #4
0
def run_cli(argv=None, config_path=CONFIG_PATH):
    """
    Run a CLI command from arguments (defaults to sys.argv)
    Return the result of the command on success.
    The result will be a dict, and will have 'error' defined on error condition.
    """

    if argv is None:
        argv = sys.argv

    # alternative config path?
    if '-c' in argv or '--config' in argv:
        i = 1
        while i < len(argv):
            if argv[i] == '-c' or argv[i] == '--config':
                if i + 1 >= len(argv):
                    print >> sys.stderr, "%s: missing path" % argv[i]
                    sys.exit(1)

                config_path = argv[i+1]
                argv.pop(i)
                argv.pop(i)

            else:
                i+=1

    conf = config.get_config(path=config_path)

    if conf is None:
        return {'error': 'Failed to load config'}

    conf_version = conf.get('client_version', '')
    if not semver_match( conf_version, VERSION ):
        exit_with_error("Invalid configuration file: %s != %s" % (conf_version, VERSION), \
                "Your configuration file (%s) is out of date.  Please move it and try again in order to automatically generate a new config file." % config_path)

    advanced_mode = conf.get('advanced_mode', False)

    parser = argparse.ArgumentParser(
            description='Blockstack cli version {}'.format(config.VERSION))

    all_methods = []
    subparsers = parser.add_subparsers(dest='action')
    
    # add basic methods 
    basic_methods = get_cli_basic_methods()
    basic_method_info = parse_methods( basic_methods )
    build_method_subparsers( subparsers, basic_method_info )

    all_methods = basic_method_info 

    if advanced_mode:
        # add advanced methods 
        log.debug("Enabling advanced methods")
        advanced_methods = get_cli_advanced_methods()
        advanced_method_info = parse_methods( advanced_methods )
        build_method_subparsers( subparsers, advanced_method_info )
        all_methods += advanced_method_info

    # Print default help message, if no argument is given
    if len(argv) == 1:
        parser.print_help()
        return {}

    interactive = False
    args = None
    directive = None

    try:
        args, unknown_args = parser.parse_known_args(args=argv[1:])
        directive = args.action
    except SystemExit:
        # bad arguments
        # special case: if the method is specified, but no method arguments are given,
        # then switch to prompting the user for individual arguments.
        try:
            directive_parser = argparse.ArgumentParser(description='Blockstack cli version {}'.format(config.VERSION))
            directive_subparsers = directive_parser.add_subparsers(dest='action')

            # only parse the directive
            build_method_subparsers( directive_subparsers, all_methods, include_args=False, include_opts=False ) 
            directive_args, directive_unknown_args = directive_parser.parse_known_args( args=argv[1:] )

            # want interactive prompting
            interactive = True
            directive = directive_args.action

        except SystemExit:
            # still invalid 
            parser.print_help()
            return {'error': 'Invalid arguments.  Try passing "-h".'}

    result = {}

    blockstack_server = conf['server']
    blockstack_port = conf['port']

    # initialize blockstack connection
    session(conf=conf, server_host=blockstack_server,
            server_port=blockstack_port, set_global=True)

    # dispatch to the apporpriate method  
    for method_info in all_methods:
        if directive != method_info['command']:
            continue

        method = method_info['method']
        
        # interactive?
        if interactive:
            print ""
            print "Interactive prompt engaged.  Press Ctrl+C to quit"
            print "Help for '%s': %s" % (method_info['command'], method_info['help'])
            print ""
            
            required_args = prompt_args( method_info['args'], lambda arghelp, argname: raw_input("%s ('%s'): " % (arghelp, argname)) )
            if required_args is None:
                return {'error': 'Failed to prompt for arguments'}

            optional_args = prompt_args( method_info['opts'], lambda arghelp, argname: raw_input("optional: %s ('%s'): " % (arghelp, argname) ))
            if optional_args is None:
                return {'error': 'Failed to prompt for arguments'}

            full_args = [method_info['command']] + required_args + optional_args
            try:
                args, unknown_args = parser.parse_known_args( args=full_args )
            except SystemExit:
                # invalid arguments
                return {'error': 'Invalid arguments.  Please try again.'}

        result = method( args, config_path=config_path )
        return result

    # not found 
    return {'error': "No such command '%s'" % args.action}
Пример #5
0
def update(fqu, profile):
    """
        Update a previously registered fqu (step #3)

        @fqu: fully qualified name e.g., muneeb.id
        @profile: new profile json, hash(profile) goes to blockchain

        Internal use:
        @owner_address: fetches the owner_address that can update

        Returns True/False and stores tx_hash in queue
    """

    # hack to ensure local, until we update client
    from blockstack_client import client as bs_client
    # start session using blockstack_client
    bs_client.session(server_host=BLOCKSTACKD_IP, server_port=BLOCKSTACKD_PORT,
                      set_global=True)

    if alreadyinQueue(update_queue, fqu):
        log.debug("Already in update queue: %s" % fqu)
        return False

    if not nameRegistered(fqu):
        log.debug("Not yet registered %s" % fqu)
        return False

    data = get_blockchain_record(fqu)

    owner_address = data['address']
    profile_hash = get_hash(profile)
    owner_privkey = wallet.get_privkey_from_address(owner_address)

    if owner_privkey is None:
        log.debug("Registrar doens't own this name.")
        return False

    if dontuseAddress(owner_address):
        log.debug("Owner address not ready: %s" % owner_address)
        return False

    elif underfundedAddress(owner_address):
        log.debug("Owner address under funded: %s" % owner_address)
        return False

    log.debug("Updating (%s, %s)" % (fqu, profile_hash))

    resp = {}

    try:
        resp = bs_client.update(fqu, profile_hash, owner_privkey)
    except Exception as e:
        log.debug(e)

    if 'tx_hash' in resp:
        add_to_queue(update_queue, fqu, profile=profile,
                     profile_hash=profile_hash, owner_address=owner_address,
                     tx_hash=resp['tx_hash'])
    else:
        log.debug("Error updating: %s" % fqu)
        log.debug(resp)
        return False

    return True
Пример #6
0
def run_cli(argv=None, config_path=CONFIG_PATH):
    """
    Run a CLI command from arguments (defaults to sys.argv)
    Return the result of the command on success.
    The result will be a dict, and will have 'error' defined on error condition.
    """

    if argv is None:
        argv = sys.argv

    global_cli_args = {
        'debug': {
            'short': '-d',
            'long': '--debug',
            'has_arg': False,
            're-exec': True,
            'env': 'BLOCKSTACK_DEBUG',
            'help': 'Enable global debugging messages',
            'similar': ['--dbg', '-dd', '-ddd', '-dddd', '--verbose'],
            'secret': False,
        },
        'config': {
            'short': '-c',
            'long': '--config',
            'has_arg': True,
            're-exec': True,
            'env': 'BLOCKSTACK_CLIENT_CONFIG',
            'help':
            'Path to alternative configuration file and associated state',
            'similar': ['--conf'],
            'secret': False,
        },
        'default_yes': {
            'short': '-y',
            'long': '--yes',
            'has_arg': False,
            're-exec': False,
            'env': 'BLOCKSTACK_CLIENT_INTERACTIVE_YES',
            'help': 'Assume default/yes response to all queries',
            'similar': [],
            'secret': False,
        },
        'api_pass': {
            'short': '-a',
            'long': '--api_password',
            'has_arg': True,
            're-exec': False,
            'env': 'BLOCKSTACK_API_PASSWORD',
            'help': 'API password to use',
            'similar': ['--api-password', '--api-pass', '--api_pass'],
            'secret': True,
        },
        'api_session': {
            'short': '-A',
            'long': '--api_session',
            'has_arg': True,
            're-exec': False,
            'env': 'BLOCKSTACK_API_SESSION',
            'help': 'API session token to use',
            'similar': ['--api-session', '--session', '--ses'],
            'secret': True,
        },
        'api_bind': {
            'short': '-b',
            'long': '--bind',
            'has_arg': True,
            're-exec': False,
            'env': 'BLOCKSTACK_API_BIND',
            'help': 'Address or hostname to bind the API server',
            'similar': [],
            'secret': False,
        },
        'dry_run': {
            'short': '-n',
            'long': '--dry_run',
            'has_arg': False,
            're-exec': True,
            'env': 'BLOCKSTACK_DRY_RUN',
            'help':
            'Do not send transactions. Return the signed transaction instead.',
            'similar': ['--dry-run', '--dryrun'],
            'secret': False,
        },
        'wallet_password': {
            'short': '-p',
            'long': '--password',
            'has_arg': True,
            're-exec': False,
            'env': 'BLOCKSTACK_CLIENT_WALLET_PASSWORD',
            'help': 'Wallet decryption password',
            'similar': ['--pass', '--passwd'],
            'secret': True,
        },
        'indexer_host': {
            'short': '-H',
            'long': '--host',
            'has_arg': True,
            're-exec': False,
            'env': 'BLOCKSTACK_CLI_SERVER_HOST',
            'help':
            'Hostname or IP address of the Blockstack blockchain indexer',
            'similar': ['--ip', '--ipv4'],
            'secret': False,
        },
        'indexer_port': {
            'short': '-P',
            'long': '--port',
            'has_arg': True,
            're-exec': False,
            'env': 'BLOCKSTACK_CLI_SERVER_PORT',
            'help': 'Port number of the Blockstack blockchain indexer',
            'similar': [],
            'secret': False,
        },
        'secret_fd': {
            'short': '-f',
            'long': '--secrets',
            'has_arg': True,
            're-exec': False,
            'help':
            'Used internally; file descriptor number to serialized secrets preserved across execv(2).',
            'similar': [],
            'secret': False,
        },
    }

    if '-v' in argv or '--version' in argv:
        print(VERSION)
        sys.exit(0)

    arg_info = parse_args(global_cli_args, argv, config_path=config_path)
    if 'error' in arg_info:
        print("Failed to parse global CLI arguments: {}".format(
            arg_info['error']),
              file=sys.stderr)
        print("Global CLI arguments:\n{}\n".format("\n".join([
            "\t{}/{}\n\t\t{}".format(cliarg['short'], cliarg['long'],
                                     cliarg['help'])
            for argname, cliarg in global_cli_args.items()
        ])),
              file=sys.stderr)

        if 'similar' in arg_info:
            siminfo = arg_info['similar']
            assert len(siminfo.keys()) == 1
            opt = siminfo.keys()[0]
            arg = siminfo[opt]

            print("Suggestion:  Use '{}' instead of '{}'".format(opt, arg),
                  file=sys.stderr)

        sys.exit(1)

    cli_debug = arg_info['args'].get('debug')
    cli_config_argv = (arg_info['args'].has_key('config'))

    # set (non-secret) environment variables
    for envar, enval in arg_info['envs'].items():
        if os.environ.get(envar) is None:
            if cli_debug:
                print("Set {} to {}".format(envar, enval), file=sys.stderr)

            os.environ[envar] = enval

    # set secrets...
    for secvar, secval in arg_info['secrets'].items():
        set_secret(secvar, secval)

    # re-exec?
    if arg_info['re-exec']:

        new_argv = arg_info['new_argv']

        if len(arg_info['secrets']) > 0:
            secbuf = serialize_secrets()
            fd = write_secrets(secbuf)

            new_argv += ['--secrets', str(fd)]

        new_argv = [sys.executable] + new_argv
        if cli_debug:
            print("Re-exec as `{}`".format(", ".join(
                ['"{}"'.format(i) for i in new_argv])),
                  file=sys.stderr)

        try:
            os.execv(new_argv[0], new_argv)
        except:
            import traceback as tb
            tb.print_exc()
            sys.exit(1)

    # load secrets
    if arg_info['args'].has_key('secret_fd'):
        fd_str = arg_info['args']['secret_fd']
        if fd_str:
            try:
                fd = int(fd_str)
            except:
                print('Invalid secret fd {}'.format(fd_str), file=sys.stderr)
                sys.exit(1)

            log.debug("Load secrets from {}".format(fd))

            try:
                os.lseek(fd, 0, os.SEEK_SET)
                secbuf = os.read(fd, 65536)
                os.close(fd)

                load_secrets(secbuf)
            except Exception as e:
                traceback.print_exc()
                sys.exit(1)

    # do one-time opt-in request
    uuid_path = client_uuid_path(config_dir=os.path.dirname(config_path))
    first_time = False
    client_uuid = None

    if not os.path.exists(uuid_path):
        first_time = True
        client_uuid = get_or_set_uuid(config_dir=os.path.dirname(config_path))

    res = config.setup_config(
        config_path=config_path,
        interactive=(os.environ.get("BLOCKSTACK_CLIENT_INTERACTIVE_YES") !=
                     '1'))
    if 'error' in res:
        exit_with_error("Failed to load and verify config file: {}".format(
            res['error']))

    conf = res['config']

    # if the wallet exists, make sure that it's the latest version
    wallet_path = os.path.join(os.path.dirname(config_path), WALLET_FILENAME)
    if os.path.exists(wallet_path):
        res = inspect_wallet(wallet_path=wallet_path)
        if 'error' in res:
            exit_with_error(
                "Failed to inspect wallet at {}".format(wallet_path))

        if res['migrate'] or res['format'] != 'current':
            if len(sys.argv) <= 1 or sys.argv[1] != 'setup_wallet':
                exit_with_error(
                    "Wallet is in legacy format.  Please unlock and migrate it with `blockstack setup_wallet`."
                )

    parser = BlockstackArgumentParser(
        description='Blockstack cli version {}'.format(config.VERSION))

    all_methods = []
    subparsers = parser.add_subparsers(dest='action')

    # add basic methods
    all_method_names = get_cli_methods()
    all_methods = parse_methods(all_method_names)
    build_method_subparsers(subparsers, all_methods)

    # Print default help message, if no argument is given
    if len(argv) == 1 or '-h' in argv or '--help' in argv:
        parser.print_help()
        sys.exit(0)

    interactive, args, directive = False, None, None

    try:
        # capture stderr so we don't repeat ourselves
        args, unknown_args = parser.parse_known_args(args=argv[1:])
        directive = args.action
    except SystemExit:
        # bad arguments
        # special case: if the method is specified, but no method arguments are given,
        # then switch to prompting the user for individual arguments.
        try:
            directive_parser = BlockstackArgumentParser(
                description='Blockstack cli version {}'.format(config.VERSION))
            directive_subparsers = directive_parser.add_subparsers(
                dest='action')

            # only parse the directive
            build_method_subparsers(directive_subparsers,
                                    all_methods,
                                    include_args=False,
                                    include_opts=False)

            directive_args, directive_unknown_args = directive_parser.parse_known_args(
                args=argv[1:])

            # want interactive prompting
            interactive, directive = True, directive_args.action

        except SystemExit:
            # still invalid
            return {'error': 'Invalid arguments.  Try passing "-h".'}

    result = {}

    blockstack_server, blockstack_port = conf['blockstack-client'][
        'server'], conf['blockstack-client']['port']

    # initialize blockstack connection
    session(server_host=blockstack_server,
            server_port=blockstack_port,
            set_global=True)

    prompt_func_arg = lambda help, name: raw_input('required: {} ("{}"): '.
                                                   format(help, name))
    prompt_func_opt = lambda help, name: raw_input('optional: {} ("{}"): '.
                                                   format(help, name))

    # dispatch to the apporpriate method
    for method_info in all_methods:
        if directive != method_info['command']:
            continue

        method = method_info['method']
        pragmas = method_info['pragmas']

        # interactive?
        if interactive:
            arg_names = [mi['name'] for mi in method_info['args']]
            opt_names = [mi['name'] for mi in method_info['opts']]
            arg_usage = ' '.join(arg_names)
            opt_usage = ' '.join(['[{}]'.format(opt) for opt in opt_names])

            print('')
            print('Interactive prompt engaged.  Press Ctrl+C to quit')
            print('Help for "{}": {}'.format(method_info['command'],
                                             method_info['help']))
            print('Arguments: {} {} {}'.format(method_info['command'],
                                               arg_usage, opt_usage))
            print('')

            required_args = prompt_args(method_info['args'], prompt_func_arg)
            if required_args is None:
                return {'error': 'Failed to prompt for arguments'}

            optional_args = prompt_args(method_info['opts'], prompt_func_opt)
            if optional_args is None:
                return {'error': 'Failed to prompt for arguments'}

            full_args = [method_info['command']
                         ] + required_args + optional_args
            try:
                args, unknown_args = parser.parse_known_args(args=full_args)
            except SystemExit:
                # invalid arguments
                return {'error': 'Invalid arguments.  Please try again.'}

        result = method(args, config_path=config_path)
        return {'status': True, 'result': result, 'pragmas': pragmas}

    # not found
    return {'error': 'No such command "{}"'.format(args.action)}
Пример #7
0
def subsidized_transfer(fqu, transfer_address, owner_privkey, payment_address,
                        payment_privkey=None):
    """
        Transfer a previously registered fqu, using a different payment address

        @fqu: fully qualified name e.g., muneeb.id
        @transfer_address: new owner address
        @owner_privkey: privkey of current owner address, to sign tx
        @payment_address: the address which is paying for the cost

        Returns True/False and stores tx_hash in queue
    """

    # hack to ensure local, until we update client
    from blockstack_client import client as bs_client
    # start session using blockstack_client
    bs_client.session(server_host=BLOCKSTACKD_IP, server_port=BLOCKSTACKD_PORT,
                      set_global=True)

    if alreadyinQueue(transfer_queue, fqu):
        log.debug("Already in transfer queue: %s" % fqu)
        return False

    if not nameRegistered(fqu):
        log.debug("Not yet registered %s" % fqu)
        return False

    if ownerName(fqu, transfer_address):
        log.debug("Already transferred %s" % fqu)
        return True

    if recipientNotReady(transfer_address):
        log.debug("Address %s owns too many names already." % transfer_address)
        return False

    blockchain_record = get_blockchain_record(fqu)
    owner_address = blockchain_record['address']

    check_address = get_address_from_privkey(owner_privkey)

    if check_address != owner_address:
        log.debug("Given privkey/address doens't own this name.")
        return False

    if dontuseAddress(payment_address):
        log.debug("Payment address not ready: %s" % payment_address)
        return False

    elif underfundedAddress(payment_address):
        log.debug("Payment address under funded: %s" % payment_address)
        return False

    owner_public_key = get_pubkey_from_privkey(owner_privkey)

    if payment_privkey is None:
        payment_privkey = wallet.get_privkey_from_address(payment_address)

    log.debug("Transferring (%s, %s)" % (fqu, transfer_address))
    log.debug("<owner, payment> (%s, %s)" % (owner_address, payment_address))

    resp = {}

    try:
        # format for transfer RPC call is:
        # (name, address, keep_data, public_key, subsidy_key)
        resp = bs_client.transfer_subsidized(fqu, transfer_address, True,
                                             public_key=owner_public_key,
                                             subsidy_key=payment_privkey)
    except Exception as e:
        log.debug(e)

    if 'subsidized_tx' in resp:
        unsigned_tx = resp['subsidized_tx']
    else:
        log.debug("Error transferring: %s" % fqu)
        log.debug(pprint(resp))
        return False

    broadcast_resp = send_subsidized(owner_privkey, unsigned_tx)

    if 'tx_hash' in broadcast_resp:
        add_to_queue(transfer_queue, fqu, owner_address=owner_address,
                     transfer_address=transfer_address,
                     tx_hash=broadcast_resp['tx_hash'])
    else:
        log.debug("Error transferring: %s" % fqu)
        log.debug(broadcast_resp)
        return False

    return True
Пример #8
0
    along with Blockstack-client. If not, see <http://www.gnu.org/licenses/>.
"""

import os
import sys
import json
import unittest

from blockstack_client import client
from blockstack_client.utils import print_result as pprint
from blockstack_client.config import BLOCKSTACKD_SERVER, BLOCKSTACKD_PORT, CONFIG_DIR

# start session
if not os.path.exists( CONFIG_DIR ):
    os.makedirs( CONFIG_DIR )
client.session(server_host=BLOCKSTACKD_SERVER, server_port=BLOCKSTACKD_PORT)

test_names = ["muneeb.id", "fredwilson.id"]


class BlockstackClientTest(unittest.TestCase):

    def tearDown(self):
        pass

    def test_ping(self):
        """ Check ping
        """

        resp = client.ping()
Пример #9
0
def transfer(fqu, transfer_address):
    """
        Transfer a previously registered fqu (step #4)

        @fqu: fully qualified name e.g., muneeb.id
        @transfer_address: new owner address of @fqu

        Internal use:
        @owner_address: fetches the owner_address that can transfer

        Returns True/False and stores tx_hash in queue
    """

    # hack to ensure local, until we update client
    from blockstack_client import client as bs_client
    # start session using blockstack_client
    bs_client.session(server_host=BLOCKSTACKD_IP,
                      server_port=BLOCKSTACKD_PORT,
                      set_global=True)

    if alreadyinQueue(transfer_queue, fqu):
        log.debug("Already in transfer queue: %s" % fqu)
        return False

    if ownerName(fqu, transfer_address):
        log.debug("Already transferred %s" % fqu)
        return True

    if recipientNotReady(transfer_address):
        log.debug("Address %s owns too many names already." % transfer_address)
        return False

    data = get_blockchain_record(fqu)
    owner_address = data['address']
    owner_privkey = wallet.get_privkey_from_address(owner_address)

    if dontuseAddress(owner_address):
        log.debug("Owner address not ready: %s" % owner_address)
        return False

    elif underfundedAddress(owner_address):
        log.debug("Owner address under funded: %s" % owner_address)
        return False

    log.debug("Transferring (%s, %s)" % (fqu, transfer_address))

    resp = {}

    try:
        # format for transfer RPC call is (name, address, keepdata, privatekey)
        resp = bs_client.transfer(fqu, transfer_address, True, owner_privkey)
    except Exception as e:
        log.debug(e)

    if 'tx_hash' in resp:
        add_to_queue(transfer_queue,
                     fqu,
                     owner_address=owner_address,
                     transfer_address=transfer_address,
                     tx_hash=resp['tx_hash'])
    else:
        log.debug("Error transferring: %s" % fqu)
        log.debug(resp)
        return False

    return True
Пример #10
0
def update(fqu, profile):
    """
        Update a previously registered fqu (step #3)

        @fqu: fully qualified name e.g., muneeb.id
        @profile: new profile json, hash(profile) goes to blockchain

        Internal use:
        @owner_address: fetches the owner_address that can update

        Returns True/False and stores tx_hash in queue
    """

    # hack to ensure local, until we update client
    from blockstack_client import client as bs_client
    # start session using blockstack_client
    bs_client.session(server_host=BLOCKSTACKD_IP,
                      server_port=BLOCKSTACKD_PORT,
                      set_global=True)

    if alreadyinQueue(update_queue, fqu):
        log.debug("Already in update queue: %s" % fqu)
        return False

    if not nameRegistered(fqu):
        log.debug("Not yet registered %s" % fqu)
        return False

    data = get_blockchain_record(fqu)

    owner_address = data['address']
    profile_hash = get_hash(profile)
    owner_privkey = wallet.get_privkey_from_address(owner_address)

    if owner_privkey is None:
        log.debug("Registrar doens't own this name.")
        return False

    if dontuseAddress(owner_address):
        log.debug("Owner address not ready: %s" % owner_address)
        return False

    elif underfundedAddress(owner_address):
        log.debug("Owner address under funded: %s" % owner_address)
        return False

    log.debug("Updating (%s, %s)" % (fqu, profile_hash))

    resp = {}

    try:
        resp = bs_client.update(fqu, profile_hash, owner_privkey)
    except Exception as e:
        log.debug(e)

    if 'tx_hash' in resp:
        add_to_queue(update_queue,
                     fqu,
                     profile=profile,
                     profile_hash=profile_hash,
                     owner_address=owner_address,
                     tx_hash=resp['tx_hash'])
    else:
        log.debug("Error updating: %s" % fqu)
        log.debug(resp)
        return False

    return True
Пример #11
0
def register(fqu,
             payment_address=None,
             owner_address=None,
             payment_privkey=None,
             auto_preorder=True):
    """
        Register a previously preordered fqu (step #2)

        @fqu: fully qualified name e.g., muneeb.id
        @auto_preorder: automatically preorder, if true

        Uses from preorder queue:
        @payment_address: used for making the payment
        @owner_address: will own the fqu (must be same as preorder owner_address)

        Returns True/False and stores tx_hash in queue
    """

    # hack to ensure local, until we update client
    from blockstack_client import client as bs_client
    # start session using blockstack_client
    bs_client.session(server_host=BLOCKSTACKD_IP,
                      server_port=BLOCKSTACKD_PORT,
                      set_global=True)

    # check register_queue first
    # stale preorder will get removed from preorder_queue
    if alreadyinQueue(register_queue, fqu):
        log.debug("Already in register queue: %s" % fqu)
        return False

    if not alreadyinQueue(preorder_queue, fqu):
        if auto_preorder:
            return preorder(fqu, payment_address, owner_address)
        else:
            log.debug("No preorder sent yet: %s" % fqu)
            return False

    if nameRegistered(fqu):
        log.debug("Already registered %s" % fqu)
        return False

    preorder_entry = preorder_queue.find_one({"fqu": fqu})
    preorder_tx = preorder_entry['tx_hash']

    tx_confirmations = get_tx_confirmations(preorder_tx)

    if tx_confirmations < PREORDER_CONFIRMATIONS:
        log.debug("Waiting on preorder confirmations: (%s, %s)" %
                  (preorder_tx, tx_confirmations))

        return False

    if payment_privkey is None:
        # use the correct owner_address from preorder operation
        try:
            owner_address = preorder_entry['owner_address']
            payment_address = preorder_entry['payment_address']

        except:
            log.debug("Error getting preorder addresses")
            return False

        payment_privkey = wallet.get_privkey_from_address(payment_address)
    else:
        payment_address = get_address_from_privkey(payment_privkey)

    if dontuseAddress(payment_address):
        log.debug("Payment address not ready: %s" % payment_address)
        return False

    elif underfundedAddress(payment_address):
        log.debug("Payment address under funded: %s" % payment_address)
        return False

    log.debug("Registering (%s, %s, %s)" %
              (fqu, payment_address, owner_address))

    resp = {}

    try:
        resp = bs_client.register(fqu, payment_privkey, owner_address)
    except Exception as e:
        log.debug(e)

    if 'tx_hash' in resp:
        add_to_queue(register_queue,
                     fqu,
                     payment_address=payment_address,
                     tx_hash=resp['tx_hash'],
                     owner_address=owner_address)
    else:
        log.debug("Error registering: %s" % fqu)
        log.debug(pprint(resp))
        return False

    return True
    Resolver
    ~~~~~
    :copyright: (c) 2014-2016 by Halfmoon Labs, Inc.
    :copyright: (c) 2016 blockstack.org
    :license: MIT, see LICENSE for more details.
"""

import json

from config import BLOCKSTACKD_IP
from config import BLOCKSTACKD_PORT
from config import NAMES_FILE, NEW_NAMES_FILE
# hack to ensure local, until we update client
from blockstack_client import client as bs_client
# start session using blockstack_client
bs_client.session(server_host=BLOCKSTACKD_IP, server_port=BLOCKSTACKD_PORT,
                  set_global=True)

if __name__ == "__main__":

    total_names = []

    offset = 0
    count = 50

    try:
        fout = open(NAMES_FILE, 'r')
        data = fout.read()
        data = json.loads(data)

        old_counter = len(data)
    except:
Пример #13
0
def preorder(fqu, payment_address, owner_address, payment_privkey=None):
    """
        Preorder a fqu (step #1)

        @fqu: fully qualified name e.g., muneeb.id
        @payment_address: used for making the payment
        @owner_address: will own the fqu

        Returns True/False and stores tx_hash in queue
    """

    # hack to ensure local, until we update client
    from blockstack_client import client as bs_client
    # start session using blockstack_client
    bs_client.session(server_host=BLOCKSTACKD_IP, server_port=BLOCKSTACKD_PORT,
                      set_global=True)

    # stale preorder will get removed from preorder_queue
    if alreadyinQueue(register_queue, fqu):
        log.debug("Already in register queue: %s" % fqu)
        return False

    if alreadyinQueue(preorder_queue, fqu):
        log.debug("Already in preorder queue: %s" % fqu)
        return False

    if recipientNotReady(owner_address):
        log.debug("Address %s owns too many names already." % owner_address)
        return False

    if payment_privkey is None:
        payment_privkey = wallet.get_privkey_from_address(payment_address)
    else:
        payment_address = get_address_from_privkey(payment_privkey)

    if dontuseAddress(payment_address):
        log.debug("Payment address not ready: %s" % payment_address)
        return False

    elif underfundedAddress(payment_address):
        log.debug("Payment address under funded: %s" % payment_address)
        return False

    log.debug("Preordering (%s, %s, %s)" % (fqu, payment_address, owner_address))

    resp = {}

    try:
        resp = bs_client.preorder(fqu, payment_privkey, owner_address)
    except Exception as e:
        log.debug(e)

    if 'tx_hash' in resp:
        add_to_queue(preorder_queue, fqu, payment_address=payment_address,
                     tx_hash=resp['tx_hash'],
                     owner_address=owner_address)
    else:
        log.debug("Error preordering: %s" % fqu)
        log.debug(pprint(resp))
        raise ValueError('Error preordering')
        return False

    return True
Пример #14
0
def transfer(fqu, transfer_address):
    """
        Transfer a previously registered fqu (step #4)

        @fqu: fully qualified name e.g., muneeb.id
        @transfer_address: new owner address of @fqu

        Internal use:
        @owner_address: fetches the owner_address that can transfer

        Returns True/False and stores tx_hash in queue
    """

    # hack to ensure local, until we update client
    from blockstack_client import client as bs_client
    # start session using blockstack_client
    bs_client.session(server_host=BLOCKSTACKD_IP, server_port=BLOCKSTACKD_PORT,
                      set_global=True)

    if alreadyinQueue(transfer_queue, fqu):
        log.debug("Already in transfer queue: %s" % fqu)
        return False

    if ownerName(fqu, transfer_address):
        log.debug("Already transferred %s" % fqu)
        return True

    if recipientNotReady(transfer_address):
        log.debug("Address %s owns too many names already." % transfer_address)
        return False

    data = get_blockchain_record(fqu)
    owner_address = data['address']
    owner_privkey = wallet.get_privkey_from_address(owner_address)

    if dontuseAddress(owner_address):
        log.debug("Owner address not ready: %s" % owner_address)
        return False

    elif underfundedAddress(owner_address):
        log.debug("Owner address under funded: %s" % owner_address)
        return False

    log.debug("Transferring (%s, %s)" % (fqu, transfer_address))

    resp = {}

    try:
        # format for transfer RPC call is (name, address, keepdata, privatekey)
        resp = bs_client.transfer(fqu, transfer_address, True, owner_privkey)
    except Exception as e:
        log.debug(e)

    if 'tx_hash' in resp:
        add_to_queue(transfer_queue, fqu,
                     owner_address=owner_address,
                     transfer_address=transfer_address,
                     tx_hash=resp['tx_hash'])
    else:
        log.debug("Error transferring: %s" % fqu)
        log.debug(resp)
        return False

    return True
Пример #15
0
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import math
import os

from flask import Flask, jsonify
from flask_crossdomain import crossdomain

from blockstack_client import client as bs_client
import blockstack_client
session = bs_client.session(server_host="localhost",
                            server_port=6264,
                            set_global=True)

app = Flask(__name__)


@app.route('/get_all_namespaces', methods=['GET'])
@crossdomain(origin='*')
def get_all_namespaces():
    try:
        namespaces = session.get_all_namespaces()
        return jsonify(namespaces), 200, {
            'Cache-Control': 'public, max-age=300'
        }
    except Exception as e:
        return jsonify(str(e)), 500


@app.route('/get_name_blockchain_history/<fqu>', methods=['GET'])
Пример #16
0
def preorder(fqu, payment_address, owner_address, payment_privkey=None):
    """
        Preorder a fqu (step #1)

        @fqu: fully qualified name e.g., muneeb.id
        @payment_address: used for making the payment
        @owner_address: will own the fqu

        Returns True/False and stores tx_hash in queue
    """

    # hack to ensure local, until we update client
    from blockstack_client import client as bs_client
    # start session using blockstack_client
    bs_client.session(server_host=BLOCKSTACKD_IP,
                      server_port=BLOCKSTACKD_PORT,
                      set_global=True)

    # stale preorder will get removed from preorder_queue
    if alreadyinQueue(register_queue, fqu):
        log.debug("Already in register queue: %s" % fqu)
        return False

    if alreadyinQueue(preorder_queue, fqu):
        log.debug("Already in preorder queue: %s" % fqu)
        return False

    if recipientNotReady(owner_address):
        log.debug("Address %s owns too many names already." % owner_address)
        return False

    if payment_privkey is None:
        payment_privkey = wallet.get_privkey_from_address(payment_address)
    else:
        payment_address = get_address_from_privkey(payment_privkey)

    if dontuseAddress(payment_address):
        log.debug("Payment address not ready: %s" % payment_address)
        return False

    elif underfundedAddress(payment_address):
        log.debug("Payment address under funded: %s" % payment_address)
        return False

    log.debug("Preordering (%s, %s, %s)" %
              (fqu, payment_address, owner_address))

    resp = {}

    try:
        resp = bs_client.preorder(fqu, payment_privkey, owner_address)
    except Exception as e:
        log.debug(e)

    if 'tx_hash' in resp:
        add_to_queue(preorder_queue,
                     fqu,
                     payment_address=payment_address,
                     tx_hash=resp['tx_hash'],
                     owner_address=owner_address)
    else:
        log.debug("Error preordering: %s" % fqu)
        log.debug(pprint(resp))
        raise ValueError('Error preordering')
        return False

    return True
Пример #17
0
def run_cli(argv=None, config_path=CONFIG_PATH):
    """
    Run a CLI command from arguments (defaults to sys.argv)
    Return the result of the command on success.
    The result will be a dict, and will have 'error' defined on error condition.
    """

    if argv is None:
        argv = sys.argv

    cli_debug = False
    cli_config_argv = False
    cli_default_yes = False
    cli_api_pass = None
    cli_dry_run = False

    if '-v' in argv or '--version' in argv:
        print(VERSION)
        sys.exit(0)

    # debug?
    new_argv, cli_debug = find_arg(argv, False, '-d', '--debug')
    if new_argv is None:
        # invalid
        sys.exit(1)

    if cli_debug:
        os.environ['BLOCKSTACK_DEBUG'] = '1'
        log.setLevel(logging.DEBUG)
        log.debug("Activated debugging")

    # alternative config path?
    new_argv, cli_config_path = find_arg(argv, True, '-c', '--config')
    if new_argv is None:
        # invalid
        sys.exit(1)

    argv = new_argv
    if cli_config_path:
        cli_config_argv = True
        config_path = cli_config_path
        log.debug('Use config file {}'.format(config_path))

    os.environ['BLOCKSTACK_CLIENT_CONFIG'] = config_path

    # CLI-given password?
    new_argv, cli_password = find_arg(argv, True, '-p', '--password')
    if new_argv is None:
        # invalid
        sys.exit(1)

    argv = new_argv
    if cli_password and os.environ.get(
            'BLOCKSTACK_CLIENT_WALLET_PASSWORD') is None:
        log.debug("Use CLI password")
        os.environ["BLOCKSTACK_CLIENT_WALLET_PASSWORD"] = cli_password

    # assume YES to all prompts?
    new_argv, cli_default_yes = find_arg(argv, False, '-y', '--yes')
    if new_argv is None:
        # invalid
        sys.exit(1)

    if cli_default_yes or os.environ.get(
            "BLOCKSTACK_CLIENT_INTERACTIVE_YES") == "1":
        if cli_debug:
            print("Assume YES to all interactive prompts", file=sys.stderr)

        os.environ["BLOCKSTACK_CLIENT_INTERACTIVE_YES"] = '1'

    # API password?
    new_argv, cli_api_pass = find_arg(argv, True, '-a', '--api_password')
    if new_argv is None:
        # invalid
        sys.exit(1)

    argv = new_argv
    if cli_api_pass:
        os.environ['BLOCKSTACK_API_PASSWORD'] = cli_api_pass

    # dry-run?
    new_argv, cli_dry_run = find_arg(argv, False, '-n', '--dry-run')
    if new_argv is None:
        # invalid
        sys.exit(1)

    if cli_dry_run or os.environ.get("BLOCKSTACK_DRY_RUN") == "1":
        if cli_debug:
            print('Dry-run; no transactions will be sent', file=sys.stderr)

        os.environ['BLOCKSTACK_DRY_RUN'] = "1"

    if cli_config_argv or cli_debug or cli_dry_run:
        # re-exec to reset variables
        if cli_debug:
            print("Re-exec {} with {}".format(argv[0], argv), file=sys.stderr)

        os.execv(argv[0], argv)

    # do one-time opt-in request
    uuid_path = client_uuid_path(config_dir=os.path.dirname(config_path))
    first_time = False
    client_uuid = None

    if not os.path.exists(uuid_path):
        first_time = True
        client_uuid = get_or_set_uuid(config_dir=os.path.dirname(config_path))

        if os.environ.get('BLOCKSTACK_CLIENT_INTERACTIVE_YES') != '1':
            # interactive allowed
            # prompt for email
            print(
                "Would you like to receive an email when there is a new release of this software available?"
            )
            email_addr = raw_input("Email address (leave blank to opt out): ")

            # will only process real email addresses when we email announcements out
            if len(email_addr) > 0:
                analytics_user_register(client_uuid, email_addr)

    conf = config.get_config(
        path=config_path,
        interactive=(os.environ.get('BLOCKSTACK_CLIENT_INTERACTIVE_YES') !=
                     '1'))
    if conf is None:
        return {'error': 'Failed to load config'}

    conf_version = conf.get('client_version', '')
    if not semver_match(conf_version, VERSION):
        # back up the config file
        if not cli_config_argv:
            # default config file
            backup_path = config.backup_config_file(config_path=config_path)
            if not backup_path:
                exit_with_error(
                    "Failed to back up legacy configuration file {}".format(
                        config_path))

            else:
                exit_with_error(
                    "Backed up legacy configuration file from {} to {} and re-generated a new, default configuration.  Please restart."
                    .format(config_path, backup_path))

    advanced_mode = conf.get('advanced_mode', False)

    parser = argparse.ArgumentParser(
        description='Blockstack cli version {}'.format(config.VERSION))

    all_methods = []
    subparsers = parser.add_subparsers(dest='action')

    # add basic methods
    all_method_names = get_cli_methods()
    all_methods = parse_methods(all_method_names)
    build_method_subparsers(subparsers, all_methods)

    if not advanced_mode:
        # remove advanced methods
        all_methods = filter(lambda m: 'advanced' not in m['pragmas'],
                             all_methods)

    # Print default help message, if no argument is given
    if len(argv) == 1 or '-h' in argv or '--help' in argv:
        parser.print_help()
        sys.exit(0)

    interactive, args, directive = False, None, None

    try:
        args, unknown_args = parser.parse_known_args(args=argv[1:])
        directive = args.action
    except SystemExit:
        # bad arguments
        # special case: if the method is specified, but no method arguments are given,
        # then switch to prompting the user for individual arguments.
        try:
            directive_parser = argparse.ArgumentParser(
                description='Blockstack cli version {}'.format(config.VERSION))
            directive_subparsers = directive_parser.add_subparsers(
                dest='action')

            # only parse the directive
            build_method_subparsers(directive_subparsers,
                                    all_methods,
                                    include_args=False,
                                    include_opts=False)
            directive_args, directive_unknown_args = directive_parser.parse_known_args(
                args=argv[1:])

            # want interactive prompting
            interactive, directive = True, directive_args.action

        except SystemExit:
            # still invalid
            parser.print_help()
            return {'error': 'Invalid arguments.  Try passing "-h".'}

    result = {}

    blockstack_server, blockstack_port = conf['server'], conf['port']

    # initialize blockstack connection
    session(conf=conf,
            server_host=blockstack_server,
            server_port=blockstack_port,
            set_global=True)

    prompt_func = lambda help, name: raw_input('optional: {} ("{}"): '.format(
        help, name))

    # dispatch to the apporpriate method
    for method_info in all_methods:
        if directive != method_info['command']:
            continue

        method = method_info['method']
        pragmas = method_info['pragmas']

        # interactive?
        if interactive:
            print('')
            print('Interactive prompt engaged.  Press Ctrl+C to quit')
            print('Help for "{}": {}'.format(method_info['command'],
                                             method_info['help']))
            print('')

            required_args = prompt_args(method_info['args'], prompt_func)
            if required_args is None:
                return {'error': 'Failed to prompt for arguments'}

            optional_args = prompt_args(method_info['opts'], prompt_func)
            if optional_args is None:
                return {'error': 'Failed to prompt for arguments'}

            full_args = [method_info['command']
                         ] + required_args + optional_args
            try:
                args, unknown_args = parser.parse_known_args(args=full_args)
            except SystemExit:
                # invalid arguments
                return {'error': 'Invalid arguments.  Please try again.'}

        result = method(args, config_path=config_path)
        return {'status': True, 'result': result, 'pragmas': pragmas}

    # not found
    return {'error': 'No such command "{}"'.format(args.action)}
Пример #18
0
    try:
        fout = open(NAMES_FILE, 'r')
        data = fout.read()
        data = json.loads(data)

        old_counter = len(data)
    except:
        old_counter = 0

    print old_counter

    while 1:

        # start session using blockstack_client
        bs_client.session(server_host=BLOCKSTACKD_IP,
                          server_port=BLOCKSTACKD_PORT,
                          set_global=True)

        new_names = bs_client.get_all_names(offset, count)
        if len(new_names) == 0:
            break

        # check for blockstack errors
        if len(new_names) == 1 and "error" in new_names:
            print "Blockstack error: " + new_names["error"]
            break

        total_names += new_names
        offset += count

        print offset
Пример #19
0
def run_cli(argv=None, config_path=CONFIG_PATH):
    """
    Run a CLI command from arguments (defaults to sys.argv)
    Return the result of the command on success.
    The result will be a dict, and will have 'error' defined on error condition.
    """

    if argv is None:
        argv = sys.argv

    global_cli_args = {
        'debug': {
            'short': '-d',
            'long': '--debug',
            'has_arg': False,
            're-exec': True,
            'env': 'BLOCKSTACK_DEBUG',
            'help': 'Enable global debugging messages',
            'similar': ['--dbg', '-dd', '-ddd', '-dddd', '--verbose'],
            'secret': False,
        },
        'config': {
            'short': '-c',
            'long': '--config',
            'has_arg': True,
            're-exec': True,
            'env': 'BLOCKSTACK_CLIENT_CONFIG',
            'help': 'Path to alternative configuration file and associated state',
            'similar': ['--conf'],
            'secret': False,
        },
        'default_yes': {
            'short': '-y',
            'long': '--yes',
            'has_arg': False,
            're-exec': False,
            'env': 'BLOCKSTACK_CLIENT_INTERACTIVE_YES',
            'help': 'Assume default/yes response to all queries',
            'similar': [],
            'secret': False,
        },
        'api_pass': {
            'short': '-a',
            'long': '--api_password',
            'has_arg': True,
            're-exec': False,
            'env': 'BLOCKSTACK_API_PASSWORD',
            'help': 'API password to use',
            'similar': ['--api-password', '--api-pass', '--api_pass'],
            'secret': True,
        },
        'api_session': {
            'short': '-A',
            'long': '--api_session',
            'has_arg': True,
            're-exec': False,
            'env': 'BLOCKSTACK_API_SESSION',
            'help': 'API session token to use',
            'similar': ['--api-session', '--session', '--ses'],
            'secret': True,
        },
        'api_bind': {
            'short': '-b',
            'long': '--bind',
            'has_arg': True,
            're-exec': False,
            'env': 'BLOCKSTACK_API_BIND',
            'help': 'Address or hostname to bind the API server',
            'similar': [],
            'secret': False,
        },
        'dry_run': {
            'short': '-n',
            'long': '--dry_run',
            'has_arg': False,
            're-exec': True,
            'env': 'BLOCKSTACK_DRY_RUN',
            'help': 'Do not send transactions. Return the signed transaction instead.',
            'similar': ['--dry-run', '--dryrun'],
            'secret': False,
        },
        'wallet_password': {
            'short': '-p',
            'long': '--password',
            'has_arg': True,
            're-exec': False,
            'env': 'BLOCKSTACK_CLIENT_WALLET_PASSWORD',
            'help': 'Wallet decryption password',
            'similar': ['--pass', '--passwd'],
            'secret': True,
        },
        'indexer_host': {
            'short': '-H',
            'long': '--host',
            'has_arg': True,
            're-exec': False,
            'env': 'BLOCKSTACK_CLI_SERVER_HOST',
            'help': 'Hostname or IP address of the Blockstack blockchain indexer',
            'similar': ['--ip', '--ipv4'],
            'secret': False,
        },
        'indexer_port': {
            'short': '-P',
            'long': '--port',
            'has_arg': True,
            're-exec': False,
            'env': 'BLOCKSTACK_CLI_SERVER_PORT',
            'help': 'Port number of the Blockstack blockchain indexer',
            'similar': [],
            'secret': False,
        },
        'secret_fd': {
            'short': '-f',
            'long': '--secrets',
            'has_arg': True,
            're-exec': False,
            'help': 'Used internally; file descriptor number to serialized secrets preserved across execv(2).',
            'similar': [],
            'secret': False,
        },
    }

    if '-v' in argv or '--version' in argv:
        print(VERSION)
        sys.exit(0)

    arg_info = parse_args( global_cli_args, argv, config_path=config_path )
    if 'error' in arg_info:
        print("Failed to parse global CLI arguments: {}".format(arg_info['error']), file=sys.stderr)
        print("Global CLI arguments:\n{}\n".format( "\n".join( ["\t{}/{}\n\t\t{}".format(cliarg['short'], cliarg['long'], cliarg['help']) for argname, cliarg in global_cli_args.items()] )), file=sys.stderr)

        if 'similar' in arg_info:
            siminfo = arg_info['similar']
            assert len(siminfo.keys()) == 1
            opt = siminfo.keys()[0]
            arg = siminfo[opt]

            print("Suggestion:  Use '{}' instead of '{}'".format(opt, arg), file=sys.stderr)

        sys.exit(1)

    cli_debug = arg_info['args'].get('debug')
    cli_config_argv = (arg_info['args'].has_key('config'))

    # set (non-secret) environment variables
    for envar, enval in arg_info['envs'].items():
        if os.environ.get(envar) is None:
            if cli_debug:
                print("Set {} to {}".format(envar, enval), file=sys.stderr)

            os.environ[envar] = enval

    # set secrets...
    for secvar, secval in arg_info['secrets'].items():
        set_secret(secvar, secval)

    # re-exec?
    if arg_info['re-exec']:
 
        new_argv = arg_info['new_argv']

        if len(arg_info['secrets']) > 0:
            secbuf = serialize_secrets()
            fd = write_secrets(secbuf)

            new_argv += ['--secrets', str(fd)]

        new_argv = [sys.executable] + new_argv
        if cli_debug:
            print("Re-exec as `{}`".format(", ".join([
                '"{}"'.format(i) for i in new_argv])), file=sys.stderr)

        try:
            os.execv(new_argv[0], new_argv)
        except:
            import traceback as tb
            tb.print_exc()
            sys.exit(1)

    # load secrets
    if arg_info['args'].has_key('secret_fd'):
        fd_str = arg_info['args']['secret_fd']
        if fd_str:
            try:
                fd = int(fd_str)
            except:
                print('Invalid secret fd {}'.format(fd_str), file=sys.stderr)
                sys.exit(1)

            log.debug("Load secrets from {}".format(fd))

            try:
                os.lseek(fd, 0, os.SEEK_SET)
                secbuf = os.read(fd, 65536)
                os.close(fd)

                load_secrets(secbuf)
            except Exception as e:
                traceback.print_exc()
                sys.exit(1)

    # do one-time opt-in request
    uuid_path = client_uuid_path(config_dir=os.path.dirname(config_path))
    first_time = False
    client_uuid = None
    
    if not os.path.exists(uuid_path):
        first_time = True
        client_uuid = get_or_set_uuid(config_dir=os.path.dirname(config_path))

        if os.environ.get('BLOCKSTACK_CLIENT_INTERACTIVE_YES') != '1':
            # interactive allowed
            # prompt for email 
            print("Would you like to receive an email when there is a new release of this software available?")
            email_addr = raw_input("Email address (leave blank to opt out): ")

            # will only process real email addresses when we email announcements out
            if len(email_addr) > 0:
                analytics_user_register( client_uuid, email_addr )

  
    res = config.setup_config(config_path=config_path, interactive=(os.environ.get("BLOCKSTACK_CLIENT_INTERACTIVE_YES") != '1'))
    if 'error' in res:
        exit_with_error("Failed to load and verify config file: {}".format(res['error']))
   
    conf = res['config']

    # if the wallet exists, make sure that it's the latest version 
    wallet_path = os.path.join(os.path.dirname(config_path), WALLET_FILENAME)
    if os.path.exists(wallet_path):
        res = inspect_wallet(wallet_path=wallet_path)
        if 'error' in res:
            exit_with_error("Failed to inspect wallet at {}".format(wallet_path))

        if res['migrate'] or res['format'] != 'current':
            if len(sys.argv) <= 1 or sys.argv[1] != 'setup_wallet':
                exit_with_error("Wallet is in legacy format.  Please unlock and migrate it with `blockstack setup_wallet`.")

    parser = BlockstackArgumentParser(
        description='Blockstack cli version {}'.format(config.VERSION)
    )

    all_methods = []
    subparsers = parser.add_subparsers(dest='action')

    # add basic methods
    all_method_names = get_cli_methods()
    all_methods = parse_methods(all_method_names)
    build_method_subparsers(subparsers, all_methods)

    # Print default help message, if no argument is given
    if len(argv) == 1 or '-h' in argv or '--help' in argv:
        parser.print_help()
        sys.exit(0)

    interactive, args, directive = False, None, None

    try:
        # capture stderr so we don't repeat ourselves
        args, unknown_args = parser.parse_known_args(args=argv[1:])
        directive = args.action
    except SystemExit:
        # bad arguments
        # special case: if the method is specified, but no method arguments are given,
        # then switch to prompting the user for individual arguments.
        try:
            directive_parser = BlockstackArgumentParser(
                description='Blockstack cli version {}'.format(config.VERSION)
            )
            directive_subparsers = directive_parser.add_subparsers(
                dest='action'
            )

            # only parse the directive
            build_method_subparsers(
                directive_subparsers, all_methods, include_args=False, include_opts=False
            )

            directive_args, directive_unknown_args = directive_parser.parse_known_args(
                args=argv[1:]
            )

            # want interactive prompting
            interactive, directive = True, directive_args.action

        except SystemExit:
            # still invalid
            return {'error': 'Invalid arguments.  Try passing "-h".'}

    result = {}

    blockstack_server, blockstack_port = conf['blockstack-client']['server'], conf['blockstack-client']['port']

    # initialize blockstack connection
    session(
        server_host=blockstack_server,
        server_port=blockstack_port, set_global=True
    )

    prompt_func = lambda help, name: raw_input('optional: {} ("{}"): '.format(help, name))

    # dispatch to the apporpriate method
    for method_info in all_methods:
        if directive != method_info['command']:
            continue

        method = method_info['method']
        pragmas = method_info['pragmas']

        # interactive?
        if interactive:
            arg_names = [mi['name'] for mi in method_info['args']]
            opt_names = [mi['name'] for mi in method_info['opts']]
            arg_usage = ' '.join(arg_names)
            opt_usage = ' '.join( ['[{}]'.format(opt) for opt in opt_names] )

            print('')
            print('Interactive prompt engaged.  Press Ctrl+C to quit')
            print('Help for "{}": {}'.format(method_info['command'], method_info['help']))
            print('Arguments: {} {}'.format(method_info['command'], arg_usage, opt_usage))
            print('')

            required_args = prompt_args(method_info['args'], prompt_func)
            if required_args is None:
                return {'error': 'Failed to prompt for arguments'}

            optional_args = prompt_args(method_info['opts'], prompt_func)
            if optional_args is None:
                return {'error': 'Failed to prompt for arguments'}

            full_args = [method_info['command']] + required_args + optional_args
            try:
                args, unknown_args = parser.parse_known_args(args=full_args)
            except SystemExit:
                # invalid arguments
                return {'error': 'Invalid arguments.  Please try again.'}

        result = method(args, config_path=config_path)
        return {'status': True, 'result': result, 'pragmas': pragmas}

    # not found
    return {'error': 'No such command "{}"'.format(args.action)}
Пример #20
0
def subsidized_update(fqu, profile, owner_privkey, payment_address,
                      payment_privkey=None):
    """
        Update a previously registered fqu, using a different payment address

        @fqu: fully qualified name e.g., muneeb.id
        @profile: new profile json, hash(profile) goes to blockchain
        @owner_privkey: privkey of owner address, to sign update
        @payment_address: the address which is paying for the cost

        Returns True/False and stores tx_hash in queue
    """

    # hack to ensure local, until we update client
    from blockstack_client import client as bs_client
    # start session using blockstack_client
    bs_client.session(server_host=BLOCKSTACKD_IP, server_port=BLOCKSTACKD_PORT,
                      set_global=True)

    if alreadyinQueue(update_queue, fqu):
        log.debug("Already in update queue: %s" % fqu)
        return False

    if not nameRegistered(fqu):
        log.debug("Not yet registered %s" % fqu)
        return False

    profile_hash = get_hash(profile)

    blockchain_record = get_blockchain_record(fqu)
    owner_address = blockchain_record['address']

    check_address = get_address_from_privkey(owner_privkey)

    if check_address != owner_address:
        log.debug("Given privkey/address doens't own this name.")
        return False

    if dontuseAddress(payment_address):
        log.debug("Payment address not ready: %s" % payment_address)
        return False

    elif underfundedAddress(payment_address):
        log.debug("Payment address under funded: %s" % payment_address)
        return False

    owner_public_key = get_pubkey_from_privkey(owner_privkey)

    if payment_privkey is None:
        payment_privkey = wallet.get_privkey_from_address(payment_address)

    log.debug("Updating (%s, %s)" % (fqu, profile_hash))
    log.debug("<owner, payment> (%s, %s)" % (owner_address, payment_address))

    resp = {}

    try:
        resp = bs_client.update_subsidized(fqu, profile_hash,
                                           public_key=owner_public_key,
                                           subsidy_key=payment_privkey)
    except Exception as e:
        log.debug(e)

    if 'subsidized_tx' in resp:
        unsigned_tx = resp['subsidized_tx']
    else:
        log.debug("Error updating: %s" % fqu)
        log.debug(resp)
        return False

    broadcast_resp = send_subsidized(owner_privkey, unsigned_tx)

    if 'tx_hash' in broadcast_resp:
        add_to_queue(update_queue, fqu, profile=profile,
                     profile_hash=profile_hash, owner_address=owner_address,
                     tx_hash=broadcast_resp['tx_hash'])
    else:
        log.debug("Error updating: %s" % fqu)
        log.debug(broadcast_resp)
        return False

    return True
Пример #21
0
def run_cli():
    """ run cli
    """

    conf = config.get_config()

    if conf is None:
        log.error("Failed to load config")
        sys.exit(1)

    advanced_mode = conf['advanced_mode']

    parser = argparse.ArgumentParser(
        description='Blockstack cli version {}'.format(config.VERSION))

    parser.register('action', 'parsers', AliasedSubParsersAction)

    subparsers = parser.add_subparsers(dest='action')

    add_subparsers(subparsers)

    if advanced_mode == "on":
        add_advanced_subparsers(subparsers)

    # Print default help message, if no argument is given
    if len(sys.argv) == 1:
        parser.print_help()
        sys.exit(1)

    args, unknown_args = parser.parse_known_args()
    result = {}

    conf = config.get_config()

    blockstack_server = conf['server']
    blockstack_port = conf['port']

    proxy = client.session(conf=conf,
                           server_host=blockstack_server,
                           server_port=blockstack_port,
                           set_global=True)

    # start the two background processes (rpc daemon and monitor queue)
    start_background_daemons()

    if args.action == 'balance':

        if not os.path.exists(WALLET_PATH):
            initialize_wallet()

        total_balance, addresses = get_total_balance()
        result['total_balance'] = total_balance
        if args.details:
            result['addresses'] = addresses

    elif args.action == 'price':

        fqu = str(args.name)
        check_valid_name(fqu)

        try:
            resp = client.get_name_cost(fqu)
        except socket_error:
            exit_with_error("Error connecting to server")

        if 'error' in resp:
            exit_with_error(resp['error'])

        data = get_total_fees(resp)

        result = data

    elif args.action == 'config':
        data = {}

        settings_updated = False

        data["message"] = "Updated settings for"

        if args.host is not None:
            config.update_config('blockstack-client', 'server', args.host)
            data["message"] += " host"
            settings_updated = True

        if args.port is not None:
            config.update_config('blockstack-client', 'port', args.port)
            data["message"] += " port"
            settings_updated = True

        if args.advanced is not None:

            if args.advanced != "on" and args.advanced != "off":
                exit_with_error("Use --advanced=on or --advanced=off")
            else:
                config.update_config('blockstack-client', 'advanced_mode',
                                     args.advanced)
                data["message"] += " advanced"
                settings_updated = True

        # reload conf
        conf = config.get_config()

        if settings_updated:
            result['message'] = data['message']
        else:
            result['message'] = "No config settings were updated."

    elif args.action == 'deposit':

        if not os.path.exists(WALLET_PATH):
            initialize_wallet()

        result['message'] = 'Send bitcoins to the address specified.'
        result['address'], owner_address = get_addresses_from_file()

    elif args.action == 'import':

        if not os.path.exists(WALLET_PATH):
            initialize_wallet()

        result['message'] = 'Send the name you want to receive to the'
        result['message'] += ' address specified.'
        payment_address, result['address'] = get_addresses_from_file()

    elif args.action == 'names':

        if not os.path.exists(WALLET_PATH):
            initialize_wallet()

        result['names_owned'] = get_all_names_owned()

        if args.details:
            result['addresses'] = get_owner_addresses()

    elif args.action in ('info', 'status', 'ping', 'details'):

        resp = client.getinfo()

        result = {}

        result['server_host'] = conf['server']
        result['server_port'] = str(conf['port'])
        result['cli_version'] = config.VERSION
        result['advanced_mode'] = conf['advanced_mode']

        if 'error' in resp:
            result['server_alive'] = False
            result['server_error'] = resp['error']
        else:
            result['server_alive'] = True
            result['server_version'] = resp['blockstore_version']
            try:
                result['last_block_processed'] = resp['last_block']
            except:
                result['last_block_processed'] = resp['blocks']
            result['last_block_seen'] = resp['bitcoind_blocks']
            result['consensus_hash'] = resp['consensus']

            if advanced_mode == 'on':
                result['testset'] = resp['testset']

            proxy = get_local_proxy()

            if proxy is not False:

                current_state = json.loads(proxy.state())

                queue = {}
                pending_queue = []
                preorder_queue = []
                register_queue = []
                update_queue = []
                transfer_queue = []

                def format_new_entry(entry):
                    new_entry = {}
                    new_entry['name'] = entry['fqu']
                    confirmations = get_tx_confirmations(entry['tx_hash'])
                    if confirmations is None:
                        confirmations = 0
                    new_entry['confirmations'] = confirmations
                    return new_entry

                def format_queue_display(preorder_queue, register_queue):

                    for entry in register_queue:

                        name = entry['name']

                        for check_entry in preorder_queue:

                            if check_entry['name'] == name:
                                preorder_queue.remove(check_entry)

                for entry in current_state:

                    if 'type' in entry:
                        if entry['type'] == 'preorder':
                            preorder_queue.append(format_new_entry(entry))
                        elif entry['type'] == 'register':
                            register_queue.append(format_new_entry(entry))
                        elif entry['type'] == 'update':
                            update_queue.append(format_new_entry(entry))
                        elif entry['type'] == 'transfer':
                            transfer_queue.append(format_new_entry(entry))

                format_queue_display(preorder_queue, register_queue)

                if len(preorder_queue) != 0:
                    queue['preorder'] = preorder_queue

                if len(register_queue) != 0:
                    queue['register'] = register_queue

                if len(update_queue) != 0:
                    queue['update'] = update_queue

                if len(transfer_queue) != 0:
                    queue['transfer'] = transfer_queue

                if queue != {}:
                    result['queue'] = queue

    elif args.action == 'lookup':
        data = {}

        blockchain_record = None
        fqu = str(args.name)

        check_valid_name(fqu)

        try:
            blockchain_record = client.get_name_blockchain_record(fqu)
        except socket_error:
            exit_with_error("Error connecting to server.")

        if 'value_hash' not in blockchain_record:
            exit_with_error("%s is not registered" % fqu)

        data_id = blockchain_record['value_hash']
        owner_address = blockchain_record['address']
        profile = client.get_immutable(str(args.name), data_id)['data']

        zone_file = profile
        profile = resolve_zone_file_to_profile(profile, owner_address)

        if not is_profile_in_legacy_format(profile):
            data['data_record'] = profile
            data['zone_file'] = zone_file
        else:
            data['data_record'] = json.loads(profile)
        #except Exception as e:
        #    print e
        #    data['data_record'] = None

        result = data

    elif args.action == 'whois':
        data = {}

        record = None
        fqu = str(args.name)

        check_valid_name(fqu)

        try:
            record = client.get_name_blockchain_record(fqu)
        except socket_error:
            exit_with_error("Error connecting to server.")

        if 'value_hash' not in record:
            result['registered'] = False
        else:
            result['registered'] = True
            result['block_preordered_at'] = record['preorder_block_number']
            result['block_renewed_at'] = record['last_renewed']
            result['owner_address'] = record['address']
            result['owner_public_key'] = record['sender_pubkey']
            result['owner_script'] = record['sender']
            result['preorder_transaction_id'] = record['txid']

    elif args.action == 'register':

        if not os.path.exists(WALLET_PATH):
            initialize_wallet()

        result = {}
        fqu = str(args.name)
        check_valid_name(fqu)
        cost = client.get_name_cost(fqu)

        if 'error' in cost:
            exit_with_error(cost['error'])

        if nameRegistered(fqu):
            exit_with_error("%s is already registered." % fqu)

        if not walletUnlocked():
            unlock_wallet()

        fees = get_total_fees(cost)

        try:
            cost = fees['total_estimated_cost']
            input_prompt = "Registering %s will cost %s BTC." % (fqu, cost)
            input_prompt += " Continue? (y/n): "
            user_input = raw_input(input_prompt)
            user_input = user_input.lower()

            if user_input != 'y':
                print "Not registering."
                exit(0)
        except KeyboardInterrupt:
            print "\nExiting."
            exit(0)

        payment_address, owner_address = get_addresses_from_file()

        if not hasEnoughBalance(payment_address, fees['total_estimated_cost']):
            msg = "Address %s doesn't have enough balance." % payment_address
            exit_with_error(msg)

        if recipientNotReady(owner_address):
            msg = "Address %s owns too many names already." % owner_address
            exit_with_error(msg)

        if dontuseAddress(payment_address):
            msg = "Address %s has pending transactions." % payment_address
            msg += " Wait and try later."
            exit_with_error(msg)

        proxy = get_local_proxy()

        try:
            resp = proxy.preorder(fqu)
        except:
            exit_with_error("Error talking to server, try again.")

        if 'success' in resp and resp['success']:
            result = resp
        else:
            if 'error' in resp:
                exit_with_error(resp['error'])

            if 'message' in resp:
                exit_with_error(resp['message'])

    elif args.action == 'update':

        if not os.path.exists(WALLET_PATH):
            initialize_wallet()

        fqu = str(args.name)
        check_valid_name(fqu)

        user_data = str(args.data)
        try:
            user_data = json.loads(user_data)
        except:
            exit_with_error("Data is not in JSON format.")

        tests_for_update_and_transfer(fqu)

        if profileonBlockchain(fqu, user_data):
            msg = "Data is same as current data record, update not needed."
            exit_with_error(msg)

        if not walletUnlocked():
            unlock_wallet()

        proxy = get_local_proxy()

        try:
            resp = proxy.update(fqu, user_data)
        except:
            exit_with_error("Error talking to server, try again.")

        if 'success' in resp and resp['success']:
            result = resp
        else:
            if 'error' in resp:
                exit_with_error(resp['error'])

            if 'message' in resp:
                exit_with_error(resp['message'])

    elif args.action == 'transfer':

        if not os.path.exists(WALLET_PATH):
            initialize_wallet()

        fqu = str(args.name)
        check_valid_name(fqu)
        transfer_address = str(args.address)

        tests_for_update_and_transfer(fqu, transfer_address=transfer_address)

        if not walletUnlocked():
            unlock_wallet()

        proxy = get_local_proxy()

        try:
            resp = proxy.transfer(fqu, transfer_address)
        except:
            exit_with_error("Error talking to server, try again.")

        if 'success' in resp and resp['success']:
            result = resp
        else:
            if 'error' in resp:
                exit_with_error(resp['error'])

            if 'message' in resp:
                exit_with_error(resp['message'])

    # ---------------------- Advanced options ---------------------------------
    elif args.action == 'wallet':

        if not os.path.exists(WALLET_PATH):
            result = initialize_wallet()
        else:
            unlock_wallet(display_enabled=True)

    elif args.action == 'consensus':

        if args.block_height is None:
            # by default get last indexed block
            resp = client.getinfo()

            if 'error' in resp:
                exit_with_error("Error connecting to server.")

            elif 'last_block' in resp or 'blocks' in resp:

                if 'last_block' in resp:
                    args.block_height = client.getinfo()['last_block']
                elif 'blocks' in resp:
                    args.block_height = client.getinfo()['blocks']
                else:
                    result['error'] = "Server is indexing. Try again"
                    exit(0)

        resp = client.get_consensus_at(int(args.block_height))

        data = {}
        data['consensus'] = resp
        data['block_height'] = args.block_height

        result = data

    elif args.action == 'register_tx':
        result = client.register(str(args.name),
                                 str(args.privatekey),
                                 str(args.addr),
                                 tx_only=True)

    elif args.action == 'register_subsidized':
        result = client.register_subsidized(str(args.name),
                                            str(args.privatekey),
                                            str(args.addr),
                                            str(args.subsidy_key))

    elif args.action == 'update_tx':

        txid = None
        if args.txid is not None:
            txid = str(args.txid)

        result = client.update(str(args.name),
                               str(args.record_json),
                               str(args.privatekey),
                               txid=txid,
                               tx_only=True)

    elif args.action == 'update_subsidized':

        txid = None
        if args.txid is not None:
            txid = str(args.txid)

        result = client.update_subsidized(str(args.name),
                                          str(args.record_json),
                                          str(args.public_key),
                                          str(args.subsidy_key),
                                          txid=txid)

    elif args.action == 'transfer_tx':
        keepdata = False
        if args.keepdata.lower() not in ["on", "false"]:
            print >> sys.stderr, "Pass 'true' or 'false' for keepdata"
            sys.exit(1)

        if args.keepdata.lower() == "on":
            keepdata = True

        result = client.transfer(str(args.name),
                                 str(args.address),
                                 keepdata,
                                 str(args.privatekey),
                                 tx_only=True)

    elif args.action == 'preorder':

        register_addr = None
        if args.address is not None:
            register_addr = str(args.address)

        result = client.preorder(str(args.name),
                                 str(args.privatekey),
                                 register_addr=register_addr)

    elif args.action == 'preorder_tx':

        register_addr = None
        if args.address is not None:
            register_addr = str(args.address)

        result = client.preorder(str(args.name),
                                 str(args.privatekey),
                                 register_addr=register_addr,
                                 tx_only=True)

    elif args.action == 'preorder_subsidized':

        result = client.preorder_subsidized(str(args.name),
                                            str(args.public_key),
                                            str(args.address),
                                            str(args.subsidy_key))

    elif args.action == 'transfer_subsidized':
        keepdata = False
        if args.keepdata.lower() not in ["on", "false"]:
            print >> sys.stderr, "Pass 'true' or 'false' for keepdata"
            sys.exit(1)

        if args.keepdata.lower() == "on":
            keepdata = True

        result = client.transfer_subsidized(str(args.name), str(args.address),
                                            keepdata, str(args.public_key),
                                            str(args.subsidy_key))

    elif args.action == 'renew':
        result = client.renew(str(args.name), str(args.privatekey))

    elif args.action == 'renew_tx':
        result = client.renew(str(args.name),
                              str(args.privatekey),
                              tx_only=True)

    elif args.action == 'renew_subsidized':
        result = client.renew_subsidized(str(args.name), str(args.public_key),
                                         str(args.subsidy_key))

    elif args.action == 'revoke':
        result = client.revoke(str(args.name), str(args.privatekey))

    elif args.action == 'revoke_tx':
        result = client.revoke(str(args.name),
                               str(args.privatekey),
                               tx_only=True)

    elif args.action == 'revoke_subsidized':
        result = client.revoke_subsidized(str(args.name), str(args.public_key),
                                          str(args.subsidy_key))

    elif args.action == 'name_import':
        result = client.name_import(str(args.name), str(args.address),
                                    str(args.hash), str(args.privatekey))

    elif args.action == 'namespace_preorder':

        reveal_addr = None
        if args.address is not None:
            reveal_addr = str(args.address)

        result = client.namespace_preorder(str(args.namespace_id),
                                           str(args.privatekey),
                                           reveal_addr=reveal_addr)

    elif args.action == 'namespace_reveal':
        bucket_exponents = args.bucket_exponents.split(',')
        if len(bucket_exponents) != 16:
            raise Exception("bucket_exponents must be a 16-value CSV \
                             of integers")

        for i in xrange(0, len(bucket_exponents)):
            try:
                bucket_exponents[i] = int(bucket_exponents[i])
            except:
                raise Exception("bucket_exponents must contain integers in \
                                range [0, 16)")

        lifetime = int(args.lifetime)
        if lifetime < 0:
            lifetime = 0xffffffff  # means "infinite" to blockstack-server

        result = client.namespace_reveal(str(args.namespace_id),
                                         str(args.addr), lifetime,
                                         int(args.coeff), int(args.base),
                                         bucket_exponents,
                                         int(args.nonalpha_discount),
                                         int(args.no_vowel_discount),
                                         str(args.privatekey))

    elif args.action == 'namespace_ready':
        result = client.namespace_ready(str(args.namespace_id),
                                        str(args.privatekey))

    elif args.action == 'put_mutable':
        result = client.put_mutable(str(args.name), str(args.data_id),
                                    str(args.data), str(args.privatekey))

    elif args.action == 'put_immutable':
        result = client.put_immutable(str(args.name),
                                      str(args.data),
                                      str(args.privatekey),
                                      conf=conf)

    elif args.action == 'get_mutable':
        result = client.get_mutable(str(args.name),
                                    str(args.data_id),
                                    conf=conf)

    elif args.action == 'get_immutable':
        result = client.get_immutable(str(args.name), str(args.hash))

    elif args.action == 'delete_immutable':
        result = client.delete_immutable(str(args.name), str(args.hash),
                                         str(args.privatekey))

    elif args.action == 'delete_mutable':
        result = client.delete_mutable(str(args.name), str(args.data_id),
                                       str(args.privatekey))

    elif args.action == 'get_name_blockchain_record':
        result = client.get_name_blockchain_record(str(args.name))

    elif args.action == 'get_namespace_blockchain_record':
        result = client.get_namespace_blockchain_record(str(args.namespace_id))

    elif args.action == 'lookup_snv':
        result = client.lookup_snv(str(args.name), int(args.block_id),
                                   str(args.consensus_hash))

    elif args.action == 'get_name_record':
        result = client.get_name_record(str(args.name))

    elif args.action == 'get_names_owned_by_address':
        result = client.get_names_owned_by_address(str(args.address))

    elif args.action == 'get_namespace_cost':
        result = client.get_namespace_cost(str(args.namespace_id))

    elif args.action == 'get_all_names':
        offset = None
        count = None

        if args.offset is not None:
            offset = int(args.offset)

        if args.count is not None:
            count = int(args.count)

        result = client.get_all_names(offset, count)

    elif args.action == 'get_names_in_namespace':
        offset = None
        count = None

        if args.offset is not None:
            offset = int(args.offset)

        if args.count is not None:
            count = int(args.count)

        result = client.get_names_in_namespace(str(args.namespace_id), offset,
                                               count)

    elif args.action == 'get_nameops_at':
        result = client.get_nameops_at(int(args.block_id))

    print_result(result)
Пример #22
0
"""

import os
import sys
import json
import unittest

from blockstack_client import client
from blockstack_client.utils import print_result as pprint
from blockstack_client.config import BLOCKSTACKD_SERVER, BLOCKSTACKD_PORT, CONFIG_DIR

# start session
if not os.path.exists( CONFIG_DIR ):
    os.makedirs( CONFIG_DIR )

client.session(server_host=BLOCKSTACKD_SERVER, server_port=BLOCKSTACKD_PORT)

test_names = ["muneeb.id", "fredwilson.id"]


class BlockstackClientTest(unittest.TestCase):

    def tearDown(self):
        pass

    def test_ping(self):
        """ Check ping
        """

        resp = client.ping()
Пример #23
0
def register(fqu, payment_address=None, owner_address=None,
             payment_privkey=None, auto_preorder=True):
    """
        Register a previously preordered fqu (step #2)

        @fqu: fully qualified name e.g., muneeb.id
        @auto_preorder: automatically preorder, if true

        Uses from preorder queue:
        @payment_address: used for making the payment
        @owner_address: will own the fqu (must be same as preorder owner_address)

        Returns True/False and stores tx_hash in queue
    """

    # hack to ensure local, until we update client
    from blockstack_client import client as bs_client
    # start session using blockstack_client
    bs_client.session(server_host=BLOCKSTACKD_IP, server_port=BLOCKSTACKD_PORT,
                      set_global=True)

    # check register_queue first
    # stale preorder will get removed from preorder_queue
    if alreadyinQueue(register_queue, fqu):
        log.debug("Already in register queue: %s" % fqu)
        return False

    if not alreadyinQueue(preorder_queue, fqu):
        if auto_preorder:
            return preorder(fqu, payment_address, owner_address)
        else:
            log.debug("No preorder sent yet: %s" % fqu)
            return False

    if nameRegistered(fqu):
        log.debug("Already registered %s" % fqu)
        return False

    preorder_entry = preorder_queue.find_one({"fqu": fqu})
    preorder_tx = preorder_entry['tx_hash']

    tx_confirmations = get_tx_confirmations(preorder_tx)

    if tx_confirmations < PREORDER_CONFIRMATIONS:
        log.debug("Waiting on preorder confirmations: (%s, %s)"
                  % (preorder_tx, tx_confirmations))

        return False

    if payment_privkey is None:
        # use the correct owner_address from preorder operation
        try:
            owner_address = preorder_entry['owner_address']
            payment_address = preorder_entry['payment_address']

        except:
            log.debug("Error getting preorder addresses")
            return False

        payment_privkey = wallet.get_privkey_from_address(payment_address)
    else:
        payment_address = get_address_from_privkey(payment_privkey)

    if dontuseAddress(payment_address):
        log.debug("Payment address not ready: %s" % payment_address)
        return False

    elif underfundedAddress(payment_address):
        log.debug("Payment address under funded: %s" % payment_address)
        return False

    log.debug("Registering (%s, %s, %s)" % (fqu, payment_address, owner_address))

    resp = {}

    try:
        resp = bs_client.register(fqu, payment_privkey, owner_address)
    except Exception as e:
        log.debug(e)

    if 'tx_hash' in resp:
        add_to_queue(register_queue, fqu, payment_address=payment_address,
                     tx_hash=resp['tx_hash'],
                     owner_address=owner_address)
    else:
        log.debug("Error registering: %s" % fqu)
        log.debug(pprint(resp))
        return False

    return True