예제 #1
0
def restore_account(
            account_object_name, testnet_account):
    '''Create a restored account object in caller's global namespace.

    Start a singleton :class:`.shell.wallet.Wallet` object if there is no one 
    in the global namespace already.

    If a local testnet is running, create an account object representing 
    the *eosio* account. Put the account into the wallet. Put the account
    object into the global namespace of the caller, and return.

    Otherwise, an outer testnet has to be defined with the function
    :func:`.core.setup.set_nodeos_address`.

    Args:
        account_object_name (str): The name of the account object returned.
        testnet_account (.core.testnet.Testnet): A testnet object defining the account to restore.
    '''

    globals = inspect.stack()[1][0].f_globals
    '''
    Check the conditions:
    * a *Wallet* object is defined.
    * the account object name is not in use, already.    
    ''' 
    if not is_wallet_defined(logger, globals):
        return
           
    account_name = testnet_account.account_name
    owner_key = testnet_account.owner_key
    active_key = testnet_account.active_key
    if not testnet_account.url:
        eosio = create_master_account("eosio")
        create_account(account_object_name, eosio, account_name)
        return globals[account_object_name]

    if is_in_globals(account_object_name, globals):
        return globals[account_object_name]

    '''
    Check the testnet for presence of the testnet account. If present, create 
    the corresponding object and see that it is in the wallets.
    '''
    account_object = account.GetAccount(
                    account_object_name, account_name, owner_key, active_key)

    logger.TRACE('''
        * The account object '{}' from testnet 
            @ {} 
        is restored.
        '''.format(account_name, testnet_account.url))
    Account.add_methods_and_finalize(account_object_name, account_object)
    return globals[account_object_name]
예제 #2
0
def create_master_account(account_object_name,
                          account_name=None,
                          owner_key=None,
                          active_key=None):
    '''Create master account object in caller's global namespace.

    Start a singleton :class:`.shell.wallet.Wallet` object if there is no one 
    in the global namespace already.

    If a local testnet is running, create an account object representing 
    the *eosio* account. Put the account into the wallet. Put the account
    object into the global namespace of the caller, and return.

    Otherwise, an outer testnet has to be defined with the function
    :func:`.core.setup.set_nodeos_address`.

    If the *account_name* argument is set, check the testnet for presence of the 
    account. If present, create a corresponding object and put the account 
    into the wallet, and put the account object into the global namespace of 
    the caller, and return. 
    
    Otherwise start a registration procedure:    
    
        - if the argument *account_name* is not set, make it random
        - print registration data, namely:
            - account name
            - owner public key
            - active public key
            - owner private key
            - active private key
        - wait for the user to register the master account
        - . . . . 
        - detect the named account on the remote testnet
        - put the account into the wallet
        - put the account object into the global namespace of the caller and \
            return

    Note: Name conflict:
        If a new account object, named as an existing one, is going to be added to 
        the wallet, an error is reported. Then an offer is given to edith the 
        mapping file in order to resolve the conflict. When the conflict is 
        resolved, the procedure finishes successfully.   

    Args:
        account_object_name (str): The name of the account object returned.
        account_name (str or .core.testnet.Testnet): The name of an valid EOSIO
            account. Must be set if the testnode is not local.
        owner_key (str or .core.interface.Key): The owner public key. Must 
            be set if the testnode is not local.
        active_key (str or .core.interface.Key): The active public key. Must 
            be set if the testnode is not local.
    '''

    globals = inspect.stack()[1][0].f_globals

    if isinstance(account_name, testnet.Testnet):
        owner_key = account_name.owner_key
        active_key = account_name.active_key
        account_name = account_name.account_name

    if account_object_name:  # account_object_name==None in register_testnet
        '''
        Check the conditions:
        * a *Wallet* object is defined.
        * the account object name is not in use, already.    
        '''
        if not is_wallet_defined(logger, globals):
            return None

        if is_in_globals(account_object_name, globals):
            logger.INFO('''
                ######## Account object ``{}`` restored from the blockchain.
                '''.format(account_object_name))
            return globals[account_object_name]

    logger.INFO('''
        ######### Create a master account object ``{}``.
        '''.format(account_object_name))
    '''
    If the local testnet is running, create an account object representing the 
    *eosio* account. Put the account into the wallet. Put the account object into 
    the global namespace of the caller, and **return**.
    '''
    if setup.is_local_address:
        account_object = account.Eosio(account_object_name)
        put_account_to_wallet_and_on_stack(account_object_name, account_object,
                                           logger)
        return account_object
    '''
    Otherwise, an outer testnet has to be defined with 
    *setup.set_nodeos_address(<url>)*.
    '''

    if manager.is_local_testnet():
        if teos.is_local_node_process_running():
            raise errors.Error('''
    There is an local testnode process running, but its 'eosio` account is not like 
    expected.
            ''')
            sys.exit()

            raise errors.Error('''
    If the local testnet is not running, an outer testnet has to be defined with 
    `setup.set_nodeos_address(<url>)`: use 'setup.set_nodeos_address(<URL>)'
        ''')
    '''
    If the *account_name* argument is not set, it is randomized. Check the 
    testnet for presence of the account. If present, create the corresponding 
    object and see whether it is in the wallets. If so, put the account object into 
    the global namespace of the caller. and **return**. 
    '''
    first_while = True
    while True:
        account_object = account.GetAccount(account_object_name, account_name,
                                            owner_key, active_key)

        if first_while and account_name and owner_key and active_key \
                        and not account_object.exists:
            raise errors.Error('''
            There is no account named ``{}`` in the blockchain.
            '''.format(account_name))

        first_while = False

        if account_object.exists:
            if account_object.has_keys:  # it is your account
                logger.TRACE('''
                    * Checking whether the wallet has keys to the account ``{}``
                    '''.format(account_object.name))

                logger.TRACE('''
                    * The account object is created.
                    ''')

                if account_object_name:
                    if Account.add_methods_and_finalize(
                            account_object_name, account_object):
                        logger.TRACE('''
                            * The account ``{}`` is in the wallet.
                            '''.format(account_object.name))
                        return account_object
                else:
                    return account_object

            else:  # the name is taken by somebody else
                logger.TRACE('''
                ###
                You can try another name. Do you wish to do this?
                ''')
                decision = input("y/n <<< ")
                if decision == "y":
                    account_name = input(
                        "enter the account name or nothing to make the name random <<< "
                    )
                else:
                    return None
        else:
            owner_key_new = cleos.CreateKey(is_verbose=False)
            active_key_new = cleos.CreateKey(is_verbose=False)

            logger.OUT('''
            Use the following data to register a new account on a public testnet:
            Account Name: {}
            Owner Public Key: {}
            Active Public Key: {}

            Owner Private Key: {}
            Active Private Key: {}
            '''.format(account_object.name, owner_key_new.key_public,
                       active_key_new.key_public, owner_key_new.key_private,
                       active_key_new.key_private))

            while True:
                is_ready = input("enter 'go' when ready or 'q' to quit <<< ")
                if is_ready == "q":
                    return None
                else:
                    if is_ready == "go":
                        break

            account_name = account_object.name
            owner_key = owner_key_new
            active_key = active_key_new