Beispiel #1
0
def clear_testnet_cache(verbosity=None):
    ''' Remove wallet files associated with the current testnet.
    '''

    if not setup.file_prefix():
        return
    logger.TRACE('''
    Removing testnet cache for prefix `{}`
    '''.format(setup.file_prefix()))

    kill_keosd() # otherwise the manager may protects the wallet files
    dir = config.keosd_wallet_dir()
    files = os.listdir(dir)
    try:
        for file in files:
            if file.startswith(setup.file_prefix()):
                os.remove(os.path.join(dir, file))
    except Exception as e:
        raise errors.Error('''
        Cannot remove testnet cache. The error message is:
        {}
        '''.format(str(e)))
    logger.TRACE('''
    Testnet cache successfully removed.
    ''')
Beispiel #2
0
    def remove_key(self, account_or_key):
        '''
        '''
        self.open_unlock()

        removed_keys = []
        account_name = None
        if isinstance(account_or_key, interface.Account):
            cleos.WalletRemove_key(interface.key_arg(account_or_key,
                                                     is_owner_key=True,
                                                     is_private_key=True),
                                   self.name,
                                   is_verbose=False)
            removed_keys.append(
                interface.key_arg(account_or_key,
                                  is_owner_key=True,
                                  is_private_key=False))

            cleos.WalletRemove_key(interface.key_arg(account_or_key,
                                                     is_owner_key=False,
                                                     is_private_key=True),
                                   self.name,
                                   is_verbose=False)
            removed_keys.append(
                interface.key_arg(account_or_key,
                                  is_owner_key=False,
                                  is_private_key=False))
        else:
            cleos.WalletRemove_key(interface.key_arg(account_or_key,
                                                     is_private_key=True),
                                   self.name,
                                   is_verbose=False)
            removed_keys.append(
                interface.key_arg(account_or_key, is_private_key=False))

        if account_name is None:
            if len(removed_keys) > 0:
                logger.TRACE(
                    '''
                    Removing key '{}' 
                    from the wallet '{}'
                    '''.format(removed_keys[0], self.name), verbosity)
        else:
            logger.TRACE('''
                Removing keys of the account '{}' from the wallet '{}'
                '''.format(account_name, self.name))

        wallet_keys = cleos.WalletKeys(is_verbose=False)

        for key in removed_keys:
            if key in wallet_keys.json:
                raise errors.Error('''
                Failed to remove key '{}' from the wallet '{}'
                '''.format(key, self.name))

        logger.TRACE('''
        * Cross-checked: all listed keys removed from the wallet.
        ''')
        return True
Beispiel #3
0
def put_account_to_wallet_and_on_stack(account_object_name,
                                       account_object,
                                       logger=None):
    if logger is None:
        logger = account_object

    global wallet_singleton

    if account_object.owner_key:
        if wallet_singleton.keys_in_wallets([
                account_object.owner_key.key_private,
                account_object.active_key.key_private
        ]):
            wallet_singleton.map_account(account_object)
        else:
            if wallet_singleton.import_key(account_object):
                wallet_singleton.map_account(account_object)
            else:
                logger.TRACE('''
                Wrong or missing keys for the account ``{}`` in the wallets.
                '''.format(account_object.name))
                return False

    # export the account object to the globals in the wallet module:
    global wallet_globals
    wallet_globals[account_object_name] = account_object
    account_object.in_wallet_on_stack = True
    return True
Beispiel #4
0
    def deploy(self, permission=None, dont_broadcast=None, payer=None):
        '''Deploy the contract.
        '''
        if not self.is_built():
            raise errors.Error('''
            Contract needs to be built before deployment.
            ''')
            return
        if dont_broadcast is None:
            dont_broadcast = self.dont_broadcast
        try:
            result = cleos_set.SetContract(self.account,
                                           self.contract_dir,
                                           self.wasm_file,
                                           self.abi_file,
                                           permission,
                                           self.expiration_sec,
                                           self.skip_sign,
                                           dont_broadcast,
                                           self.force_unique,
                                           self.max_cpu_usage,
                                           self.max_net_usage,
                                           self.ref_block,
                                           self.delay_sec,
                                           is_verbose=False,
                                           json=False)

        except errors.LowRamError as e:
            logger.TRACE('''
            * RAM needed is {}.kByte, buying RAM {}.kByte.
            '''.format(e.needs_kbyte, e.deficiency_kbyte))

            buy_ram_kbytes = str(e.deficiency_kbyte + 1)
            if not payer:
                payer = self.account

            payer.buy_ram(buy_ram_kbytes, self.account)

            result = cleos_set.SetContract(self.account,
                                           self.contract_dir,
                                           self.wasm_file,
                                           self.abi_file,
                                           permission,
                                           self.expiration_sec,
                                           self.skip_sign,
                                           dont_broadcast,
                                           self.force_unique,
                                           self.max_cpu_usage,
                                           self.max_net_usage,
                                           self.ref_block,
                                           self.delay_sec,
                                           is_verbose=False,
                                           json=False)

        logger.INFO('''
        * Contract {} 
            is deployed. 
        '''.format(self.contract_dir))

        self.contract = result
Beispiel #5
0
 def unlock(self):
     ''' Unlock the wallet.
     Returns `WalletUnlock` object.
     '''
     cleos.WalletUnlock(self.name, self.password, is_verbose=False)
     logger.TRACE('''
     * Wallet ``{}`` unlocked.
     '''.format(self.name))
Beispiel #6
0
 def open(self):
     ''' Opens the wallet.
     Returns `WalletOpen` object
     '''
     cleos.WalletOpen(self.name, is_verbose=False)
     logger.TRACE('''
     * Wallet ``{}`` opened.
     '''.format(self.name))
Beispiel #7
0
    def __init__(self, name=None, password="", verbosity=None, file=False):

        cleos.set_local_nodeos_address_if_none()
        if name is None:
            name = setup.wallet_default_name
        else:
            name = setup.file_prefix() + name

        if not self.wallet is None:
            raise errors.Error('''
            It can be only one ``Wallet`` object in the script; there is one
            named ``{}``.
            '''.format(wallet.name))
            return

        self.wallet_dir = manager.wallet_dir()

        logger.INFO('''
                * Wallet name is ``{}``, wallet directory is
                    {}.
                '''.format(name, self.wallet_dir))

        if not password:  # look for password:
            passwords = wallet_json_read()
            if name in passwords:
                password = passwords[name]
                logger.INFO(
                    '''
                    The password is restored from the file:
                    {}
                    '''.format(
                        os.path.join(self.wallet_dir, setup.password_map)),
                    verbosity)

        cleos.WalletCreate.__init__(self, name, password, is_verbose=False)

        if self.is_created:  # new password
            logger.INFO(
                '''
                * Created wallet ``{}``.
                '''.format(self.name), verbosity)
            ###############################################################################
            # TO DO: detect live node!!!!!!!!!!
            if manager.is_local_testnet() or file or True:
                ###############################################################################
                password_map = wallet_json_read()
                password_map[name] = self.password
                wallet_json_write(password_map)
                logger.INFO(
                    '''
                    * Password is saved to the file ``{}`` in the wallet directory.
                    '''.format(setup.password_map), verbosity)
            else:
                logger.OUT(self.out_msg)
        else:
            logger.TRACE('''
                    Opened wallet ``{}``
                    '''.format(self.name))
Beispiel #8
0
    def set_action_permission(self,
                              code,
                              type,
                              requirement,
                              permission=None,
                              expiration_sec=None,
                              skip_sign=0,
                              dont_broadcast=0,
                              return_packed=0,
                              force_unique=0,
                              max_cpu_usage=0,
                              max_net_usage=0,
                              ref_block=None,
                              delay_sec=0):
        '''Set parameters dealing with account permissions.

        Call *EOSIO cleos* with the *set action permission* command. Store the 
        result, which is an object of the 
        class :class:`.cleos_set.SetActionPermission`, as the value of the *action_permission* attribute.

        Args:
            code (str or .interface.Account): The account that owns the code for \
                the action.
            type (str): The type of the action.
            requirement (str): The permission name require for executing the given 
                action.

        See definitions of the remaining parameters: \
        :func:`.cleos.common_parameters`.
        '''
        stop_if_account_is_not_set(self)
        logger.TRACE('''
        * Set action permission.
        ''')

        result = SetActionPermission(self,
                                     code,
                                     type,
                                     requirement,
                                     permission,
                                     expiration_sec,
                                     skip_sign,
                                     dont_broadcast,
                                     return_packed,
                                     force_unique,
                                     max_cpu_usage,
                                     max_net_usage,
                                     ref_block,
                                     delay_sec,
                                     is_verbose=False,
                                     json=True)

        logger.INFO('''
            * action permission ``{}``:
            '''.format(type))

        self.action_permission = result
Beispiel #9
0
    def __init__(self,
                 account_object_name,
                 name=None,
                 owner_key=None,
                 active_key=None,
                 verbosity=None):

        self.account_object_name = account_object_name
        if name is None:
            self.name = cleos.account_name()
        else:
            self.name = name

        if active_key is None:
            active_key = owner_key

        self.exists = False
        self.in_wallet_on_stack = False
        self.has_keys = not owner_key is None

        try:
            cleos.GetAccount.__init__(self,
                                      self.name,
                                      is_info=False,
                                      is_verbose=False)
        except errors.AccountDoesNotExistError:
            return

        self.exists = True
        if owner_key is None:
            self.owner_key = cleos.CreateKey(
                self.json["permissions"][1]["required_auth"]["keys"] \
                [0]["key"],
                is_verbose=0)
        else:  # an orphan account, private key is restored from cache
            self.owner_key = cleos.CreateKey(
                self.json["permissions"][1]["required_auth"]["keys"] \
                [0]["key"], interface.key_arg(
                    owner_key, is_owner_key=True, is_private_key=True),
                is_verbose=0)

        if active_key is None:
            self.owner_key = cleos.CreateKey(
                self.json["permissions"][0]["required_auth"]["keys"] \
                [0]["key"],
                is_verbose=0)
        else:  # an orphan account, private key is restored from cache
            self.active_key = cleos.CreateKey(
                self.json["permissions"][0]["required_auth"]["keys"] \
                [0]["key"], interface.key_arg(
                    active_key, is_owner_key=False, is_private_key=True),
                is_verbose=0)

        logger.TRACE('''
            * Account *{}* exists in the blockchain.
            '''.format(self.name))
Beispiel #10
0
    def private_keys(self):
        ''' Lists public keys from all unlocked wallets.
        Returns `cleos.WalletKeys` object.
        '''
        self.open_unlock()

        self.wallet_private_keys = cleos.WalletPrivateKeys(is_verbose=False)
        logger.TRACE('''
            Keys in all open walets:
            {}
            '''.format(json.dumps(self.wallet_private_keys.json, indent=4)))
Beispiel #11
0
 def keys(self):
     ''' Lists public keys from all unlocked wallets.
     Returns `cleos.WalletKeys` object.
     '''
     self.open_unlock()
     wallet_keys = cleos.WalletKeys(is_verbose=False)
     logger.TRACE('''
         Keys in all open walets:
         {}
         '''.format(wallet_keys.out_msg))
     return wallet_keys
Beispiel #12
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]
Beispiel #13
0
def test():
    stop()
    nodeos([
        "--http-server-address",
        config.http_server_address(), "--data-dir",
        config.data_dir(), "--config-dir",
        config.config_dir(), "--chain-state-db-size-mb",
        config.chain_state_db_size_mb(), "--contracts-console",
        "--verbose-http-errors", "--enable-stale-production",
        "--producer-name eosio", "--signature-provider " +
        config.eosio_key_public() + "=KEY:" + config.eosio_key_private(),
        "--plugin eosio::producer_plugin", "--plugin eosio::chain_api_plugin",
        "--plugin eosio::http_plugin", "--plugin eosio::history_api_plugin",
        "--genesis-json",
        config.genesis_json(), "--delete-all-blocks"
    ])
    node_probe()
    stop()
    if not node_probe():
        logger.TRACE("Confirmed, node is stopped.")

    nodeos([
        "--http-server-address",
        config.http_server_address(), "--data-dir",
        config.data_dir(), "--config-dir",
        config.config_dir(), "--chain-state-db-size-mb",
        config.chain_state_db_size_mb(), "--contracts-console",
        "--verbose-http-errors", "--enable-stale-production",
        "--producer-name eosio", "--signature-provider " +
        config.eosio_key_public() + "=KEY:" + config.eosio_key_private(),
        "--plugin eosio::producer_plugin", "--plugin eosio::chain_api_plugin",
        "--plugin eosio::http_plugin", "--plugin eosio::history_api_plugin"
    ])
    node_probe()
    stop()

    src_file = os.path.join(config.eosf_dir(),
                            "contracts/01_hello_world/src/hello_world.cpp")

    #"contracts/01_hello_world/src/hello_world.cpp")

    abi_file = os.path.join(config.eosf_dir(),
                            "contracts/01_hello_world/build/hello_world.abi")
    abi(src_file, abi_file)

    wasm_file = os.path.join(
        config.eosf_dir(), "contracts/01_hello_world/build/hello_world.wasm")
    wasm(src_file, wasm_file)
Beispiel #14
0
    def add_methods_and_finalize(cls, account_object_name, account):
        '''Ascribes methodes to the given *account*, and finalizes the creation 
        of this *account*.
        '''
        account.account_object_name = account_object_name

        if not isinstance(account, cls): 
            account.__class__.__bases__ += (cls,)

        get_account = cleos.GetAccount(account, is_info=False, is_verbose=0)

        logger.TRACE('''
        * Cross-checked: account object ``{}`` mapped to an existing 
            account ``{}``.
        '''.format(account_object_name, account.name), translate=False)
        return put_account_to_wallet_and_on_stack(account_object_name, account)
Beispiel #15
0
    def map_account(self, account_object_name, account_object):
        '''
        '''
        if not self.is_name_taken(account_object_name, account_object.name):
            account_map_json = manager.account_map(self)
            if account_map_json is None:
                return

            account_map_json[account_object.name] = account_object_name

            with open(self.wallet_dir + setup.account_map, "w") as out:
                out.write(
                    json.dumps(account_map_json, indent=3, sort_keys=True))

            logger.TRACE('''
                * Account object ``{}`` stored in the file 
                    ``{}`` in the wallet directory:
                    {}
                '''.format(account_object_name, setup.account_map,
                           self.wallet_dir + setup.account_map))
Beispiel #16
0
def WASM(
        contract_dir_hint, c_cpp_properties_path=None,
        compile_only=False, verbosity=None):
    '''Produce WASM code.
    '''
    contract_dir = config.contract_dir(contract_dir_hint)
    # source_files[0] is directory, source_files[1] is contents:
    contract_source_files = config.contract_source_files(contract_dir)

    source_files = []
    source_ext = [".c", ".cpp",".cxx", ".c++"]
    for file in contract_source_files[1]:
        if os.path.splitext(file)[1].lower() in source_ext:
            source_files.append(file)

    if not source_files:
        raise errors.Error('''
        "The source is empty. The assumed contract dir is   
            {}
        '''.format(contract_dir))
        return

    code_name = os.path.splitext(os.path.basename(source_files[0]))[0]
    target_dir = get_target_dir(contract_source_files[0])
    target_path = os.path.normpath(
                        os.path.join(target_dir, code_name  + ".wasm"))

    c_cpp_properties = get_c_cpp_properties(
                                        contract_dir, c_cpp_properties_path)

    command_line = [config.eosio_cpp()]

    for entry in c_cpp_properties[CONFIGURATIONS][0][INCLUDE_PATH]:
        if WORKSPACE_FOLDER in entry:
            entry = entry.replace(WORKSPACE_FOLDER, contract_dir)
            command_line.append("-I=" + utils.wslMapWindowsLinux(entry))
        else:
            if not EOSIO_CPP_INCLUDE in entry:
                command_line.append(
                    "-I=" + utils.wslMapWindowsLinux(strip_wsl_root(entry)))

    for entry in c_cpp_properties[CONFIGURATIONS][0]["libs"]:
        command_line.append(
            "-l=" + utils.wslMapWindowsLinux(strip_wsl_root(entry)))

    for entry in c_cpp_properties[CONFIGURATIONS][0]["compilerOptions"]:
        command_line.append(entry)
    
    for file in source_files:
        command_line.append(file)

    if setup.is_print_command_line:
        print("######## \n{}:".format(" ".join(command_line)))


    if compile_only:
        command_line.append("-c=")

    command_line.append("-o=" + target_path)

    try:
        eosio_cpp(command_line, target_dir)
    except Exception as e:                       
        raise errors.Error(str(e))

    if not compile_only:
        logger.TRACE('''
            WASM file writen to file: 
                {}
            '''.format(os.path.normpath(target_path)), verbosity)
Beispiel #17
0
    def import_key(self, account_or_key):
        ''' Imports private keys into wallet.

        Return list of `cleos.WalletImport` objects

        Args:
            account_or_key (str or .interface.Key or .interface.Account):
                A private key to import. If *account_or_key* is an 
                .interface.Account object, both owner and active keys are 
                imported.
        '''
        self.open_unlock()
        imported_keys = []
        account_name = None
        if isinstance(account_or_key, interface.Account):
            account_name = account_or_key.name
            cleos.WalletImport(interface.key_arg(account_or_key,
                                                 is_owner_key=True,
                                                 is_private_key=True),
                               self.name,
                               is_verbose=False)
            imported_keys.append(
                interface.key_arg(account_or_key,
                                  is_owner_key=True,
                                  is_private_key=False))

            cleos.WalletImport(interface.key_arg(account_or_key,
                                                 is_owner_key=False,
                                                 is_private_key=True),
                               self.name,
                               is_verbose=False)
            imported_keys.append(
                interface.key_arg(account_or_key,
                                  is_owner_key=False,
                                  is_private_key=False))
            logger.TRACE('''
                * Importing keys of the account ``{}`` 
                    into the wallet ``{}``
                '''.format(account_name, self.name))
        else:
            cleos.WalletImport(interface.key_arg(account_or_key,
                                                 is_private_key=True),
                               self.name,
                               is_verbose=False)

            logger.TRACE('''
                * Importing keys into the wallet ``{}``
                '''.format(self.name))
            return True

        wallet_keys = cleos.WalletKeys(is_verbose=False)

        if len(imported_keys) == 0:
            raise errors.Error('''
                The list of imported keys is empty.
                ''')

        ok = True
        for key in imported_keys:
            if not key in wallet_keys.json:
                ok = False
                raise errors.Error('''
                Failed to import keys of the account '{}' into the wallet '{}'
                '''.format(account_name if account_name else "n/a", self.name))

        if ok:
            logger.TRACE('''
            * Cross-checked: all account keys are in the wallet.
            ''')
        return True
Beispiel #18
0
def WAST(contract_dir_hint,
         c_cpp_properties_path=None,
         compile_only=False,
         verbosity=None):
    '''Produce WASM code.
    '''
    contract_dir = config.contract_dir(contract_dir_hint)
    # source_files[0] is directory, source_files[1] is contents:
    contract_source_files = config.contract_source_files(contract_dir)

    source_files = []
    source_ext = [".c", ".cpp", ".cxx", ".c++"]
    for file in contract_source_files[1]:
        if os.path.splitext(file)[1].lower() in source_ext:
            source_files.append(file)

    if not source_files:
        raise errors.Error('''
        "The source is empty. The assumed contract dir is   
        {}
        '''.format(contract_dir))
        return

    code_name = os.path.splitext(os.path.basename(source_files[0]))[0]
    target_path = os.path.normpath(
        os.path.join(get_target_dir(contract_source_files[0]),
                     code_name + ".wasm"))

    c_cpp_properties = get_c_cpp_properties(contract_dir,
                                            c_cpp_properties_path)

    command_line = [config.eosio_cpp()]

    for entry in c_cpp_properties["configurations"][0]["includePath"]:
        if entry == "${workspaceFolder}":
            command_line.append("-I=" + contract_dir)
        else:
            command_line.append("-I=" + strip_wsl_root(entry))

    for entry in c_cpp_properties["configurations"][0]["libs"]:
        command_line.append("-l=" + strip_wsl_root(entry))

    for entry in c_cpp_properties["configurations"][0]["compilerOptions"]:
        command_line.append(entry)

    for file in source_files:
        command_line.append(file)

    if setup.is_print_command_line:
        print("######## \n{}:".format(" ".join(command_line)))

    if not compile_only:
        command_line.append("-o=" + target_path)

    try:
        process(command_line)
    except Exception as e:
        raise errors.Error(str(e))

    if not compile_only:
        logger.TRACE(
            '''
            WASM file writen to file: {}
            '''.format(os.path.normpath(target_path)), verbosity)
Beispiel #19
0
 def lock_all(self):
     ''' Lock the wallet.
     Returns `cleos.WalletLock` object.
     '''
     cleos.WalletLockAll(is_verbose=False)
     logger.TRACE("All wallets locked.")
Beispiel #20
0
def build(
        contract_dir_hint, c_cpp_properties_path=None,
        compile_only=False, is_test_mode=False, is_execute=False, 
        verbosity=None):
    '''Produce ABI and WASM files.

    Compiler options come with the argument 'c_cpp_properties_path', as 
    components of 'compilerOptions' list. Option can be any of the 'eosio-cpp'
    options, plus the following ones:

    * --src - list of the source files, absolute or relative to 'src' or
        project directories, for example:
        --src hello.cpp tests/hello_test.cpp
    * -o - the same as the corresponding eosio-cpp option, but may be relative
        to 'build' directory

    Without any option set, the only source file is determined as a result of the function :func:`.core.config.contract_source_files`, if the result is a 
    single file. If it is not, an error is thrown, stating that the source file has to be specified with the '--src' option.

    The ABI and WASM targets are named after the contract source file. 

    Args:
        contract_dir_hint (str): Path, may be partial, to the project directory.
        c_cpp_properties_path (str): If set, the path to a c_cpp_properties json 
            file in '.vscode' folder in the project directory.
        compile_only (bool): If set, do not link.
        verbosity (([.core.logger.Verbosity])): Verbosity parameter, used in 
            loggers.
    '''
    contract_dir = config.contract_dir(contract_dir_hint)
    # contract_source_files[0] is directory, contract_source_files[1] is contents:
    contract_source_files = config.contract_source_files(contract_dir)
    c_cpp_properties = get_c_cpp_properties(
                                        contract_dir, c_cpp_properties_path)
    build_dir = get_target_dir(contract_dir)
    target_path = None
    compile_options = []
    source_files = []
    
    ############################################################################
    # begin compiler option logics
    ############################################################################
    recardian_dir = "-R=" + get_recardian_dir(contract_source_files[0])

    if is_test_mode \
                and vscode.TEST_OPTIONS in c_cpp_properties[CONFIGURATIONS][0]:
        compile_options_ = c_cpp_properties[CONFIGURATIONS][0]\
                                                        [vscode.TEST_OPTIONS]
    elif not is_test_mode \
                and vscode.CODE_OPTIONS in c_cpp_properties[CONFIGURATIONS][0]:
        compile_options_ = c_cpp_properties[CONFIGURATIONS][0]\
                                                        [vscode.CODE_OPTIONS]
    else:
        compile_options_ = []

    contract_src_name = None
    is_verbose = False

    if not "-abigen" in compile_options_:
        compile_options.append("-abigen")
    if is_test_mode and not "-fnative" in compile_options_:
        compile_options.append("-fnative")
    
    for i in range(0, len(compile_options_)):
        entry = compile_options_[i]
        if "-R=" in entry:
            recardian_dir = entry
        elif "-contract=" in entry:
            contract_src_name = entry.replace("-contract=", "").strip()
            compile_options.append(entry)
        elif "--verbose" in entry:
            is_verbose = True
        elif "-o" in entry:
            target_path = utils.wslMapWindowsLinux(
                                            entry.replace("-o", "").strip())
            if not target_path:
                if i + 1 < len(compile_options_):
                    target_path = compile_options_[i + 1]
                else:
                    raise errors.Error('''
The option '-o' does not has its value set:
{}
                    '''.format(compile_options_))

            if not os.path.isabs(target_path):
                target_path = os.path.join(build_dir, target_path)
                target_dir = os.path.dirname(target_path)
                if not os.path.exists(target_dir):
                    try:
                        os.makedirs(target_dir)
                    except Exception as e:
                        raise errors.Error('''
Cannot make directory set with the option '-o'.
{}
                        '''.format(str(e)))
        
        elif "-abigen_output" in entry:
            abigen_path = utils.wslMapWindowsLinux(
                                    entry.replace("-abigen_output=", "").strip())

            if not os.path.isabs(abigen_path):
                abigen_path = os.path.join(build_dir, abigen_path)
                abigen_dir = os.path.dirname(abigen_path)
                if not os.path.exists(abigen_dir):
                    try:
                        os.makedirs(abigen_dir)
                    except Exception as e:
                        raise errors.Error('''
Cannot make directory set with the option '-abigen_output'.
{}
                        '''.format(str(e)))

            compile_options.append("-abigen_output={}".format(abigen_path))
        elif "--src" in entry:
            input_files_ = utils.wslMapWindowsLinux(
                                            entry.replace("--src", "").strip())
            if not input_files_:
                next_index = i + 1
                while True:
                    if next_index >= len(compile_options_):
                        break

                    next_item = compile_options_[next_index]
                    if "-" in next_item:
                        break
                    
                    input_files_ = input_files_ + " " + next_item
                    
            if not input_files_:
                raise errors.Error('''
The option '--src' does not has its value set:
{}
                '''.format(compile_options_))

            for input_file in input_files_.split(" "):
                temp = input_file
                if not os.path.isabs(temp):
                    temp = os.path.join(contract_source_files[0], input_file)
                    if not contract_src_name:
                        contract_src_name = os.path.splitext(
                                                    os.path.basename(temp))[0]
                    if not os.path.exists(temp):
                        temp = os.path.join(contract_dir, input_file)

                if not os.path.exists(temp):
                    raise errors.Error('''
The source file
{} 
cannot be found. It is neither absolute nor relative to the contract directory
or relative to the 'src' directory.
                    '''.format(input_file))

                temp = os.path.normpath(temp)
                if not temp in source_files:
                    source_files.append(temp)
        else:
            compile_options.append(entry)

    compile_options.append(recardian_dir)

    if not source_files:
        source_files = contract_source_files[1]
    
    if not source_files:
        raise errors.Error('''
Cannot find any source file (".c", ".cpp",".cxx", ".c++") in the contract folder.
        ''')

    if not is_test_mode and len(source_files) > 1: 
            raise errors.Error('''
Cannot determine the source file of the contract. There is many files in 
the 'src' directory, namely:
{}
Specify the file with the compiler option '--src', for
example:
--src src_dir/hello.cpp
The file path is to be absolute or relative to the project directory.
            '''.format("\n".join(source_files)))

    if not contract_src_name:
        contract_src_name = os.path.splitext(
                                        os.path.basename(source_files[0]))[0]

    if not contract_src_name and len(source_files) == 1:
            contract_src_name = os.path.splitext(
                                        os.path.basename(source_files[0]))[0]
        
    ############################################################################
    # end compiler option logics
    ############################################################################

    if not target_path:
        target_path = os.path.normpath(
                        os.path.join(build_dir, contract_src_name  + ".wasm"))
        abigen_path = os.path.normpath(
                        os.path.join(build_dir, contract_src_name  + ".abi"))
    if is_execute:
        logger.TRACE('''
            Executing target
                {}
        '''.format(target_path))
        command_line = [target_path]

        if setup.is_print_command_lines and setup.is_save_command_lines:
            setup.add_to__command_line_file(" ".join(command_line))
        if setup.is_print_command_lines or is_verbose:
            logger.DEBUG('''
                ######## command line:
                {}
                '''.format(" ".join(command_line)), [logger.Verbosity.DEBUG])
        utils.long_process(command_line, build_dir, is_verbose=True, 
                                                            prompt=target_path)
        return

    command_line = [config.eosio_cpp()]

    if compile_only:
        command_line.append("-c")
    else:
        command_line.extend(["-o", target_path])

    for entry in c_cpp_properties[CONFIGURATIONS][0][vscode.INCLUDE_PATH]:
        if WORKSPACE_FOLDER in entry:
            entry = entry.replace(WORKSPACE_FOLDER, contract_dir)
            command_line.append("-I=" + linuxize_path(entry))
        else:
            path = linuxize_path(entry)
            if not path in config.eosio_cpp_includes():
                command_line.append(
                    "-I=" + path)

    for entry in c_cpp_properties[CONFIGURATIONS][0][vscode.LIBS]:
        command_line.append(
            "-l=" + linuxize_path(entry))

    for entry in compile_options:
        command_line.append(entry)

    for input_file in source_files:
        command_line.append(input_file)

    if setup.is_print_command_lines and setup.is_save_command_lines:
        setup.add_to__command_line_file(" ".join(command_line))
    if setup.is_print_command_lines or is_verbose:
        logger.DEBUG('''
            ######## command line:
            {}
            '''.format(" ".join(command_line)), [logger.Verbosity.DEBUG])
        
    utils.long_process(command_line, build_dir, is_verbose=True, 
                                                            prompt="eosio-cpp")
    if not compile_only:
        if "wasm" in target_path:
            logger.TRACE('''
                ABI file writen to file: 
                    {}
                '''.format(os.path.normpath(abigen_path)), verbosity)        
            logger.TRACE('''
                WASM file writen to file: 
                    {}
                '''.format(os.path.normpath(target_path)), verbosity)
        else:
            logger.TRACE('''
                terget writen to file: 
                    {}
                '''.format(os.path.normpath(target_path)), verbosity)
    print("eosio-cpp: OK")            
Beispiel #21
0
def ABI(contract_dir_hint=None, c_cpp_properties_path=None, verbosity=None):
    '''Given a hint to a contract directory, produce ABI file.
    '''
    contract_dir = config.contract_dir(contract_dir_hint)
    # source_files[0] is directory, source_files[1] is contents:
    contract_source_files = config.contract_source_files(contract_dir)

    source_files = []
    source_ext = [".c", ".cpp", ".cxx", ".c++"]
    for file in contract_source_files[1]:
        if os.path.splitext(file)[1].lower() in source_ext:
            source_files.append(file)

    if not source_files:
        raise errors.Error('''
        "The source is empty. The assumed contract dir is   
        {}
        '''.format(contract_dir))
        return

    code_name = os.path.splitext(os.path.basename(source_files[0]))[0]
    target_path = os.path.normpath(
        os.path.join(get_target_dir(contract_source_files[0]),
                     code_name + ".abi"))

    for file in contract_source_files[1]:
        if os.path.splitext(file)[1].lower() == ".abi":
            logger.INFO(
                '''
            NOTE:
            An ABI exists in the source directory. Cannot overwrite it:
            {}
            Just copying it to the target directory.
            '''.format(file), verbosity)
            shutil.move(file, target_path)
            return

    command_line = [
        config.eosio_cpp(), "-contract=" + code_name,
        "-R=" + get_resources_dir(contract_source_files[0]), "-abigen",
        "-abigen_output=" + target_path
    ]

    c_cpp_properties = get_c_cpp_properties(contract_dir,
                                            c_cpp_properties_path)

    for entry in c_cpp_properties["configurations"][0]["includePath"]:
        if entry == "${workspaceFolder}":
            command_line.append("-I=" + contract_dir)
        else:
            command_line.append("-I=" + strip_wsl_root(entry))

    for file in source_files:
        command_line.append(file)

    try:
        process(command_line)
    except Exception as e:
        raise errors.Error(str(e))

    logger.TRACE(
        '''
    ABI file writen to file: {}
    '''.format(target_path), verbosity)
Beispiel #22
0
def create_master_account(account_object_name,
                          account_name=None,
                          owner_key=None,
                          active_key=None,
                          verbosity=None):
    '''Create account object in caller's global namespace.

    - **parameters**::

        account_object_name:: the name of the account object
        account_name: the name of the account; random, if not set
        verbosity: argument to the internal logger

    ### Preconditions

    Check the following conditions:
    * precisely one ``Wallet`` object is defined;
    
    ### Local testnet

    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**.

    ### Remote testnet

    Otherwise, an outer testnet has to be defined with 
    ``setup.set_nodeos_address(<url>)``.

    ### Existing account

    If the ``account_name`` argument is set, check the testnet for presence of the 
    account. If present, create the 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, 
    described in the next paragraph.

    ### Registration to a remote testnet

    If the ``account_name`` argument is not set or it does not address any existing
    account, see the previous paragraph, start a registration procedure.

    * if the ``account_name`` argument 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
    
    ### Name conflict between account objects

    If the new account object 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.
    '''

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

    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.    
        '''
        is_wallet_defined(logger, globals)

        global wallet_singleton
        if wallet_singleton is None:
            return

        if account_object_name in globals:

            if not isinstance(globals[account_object_name], interface.Account):
                raise errors.Error('''
                The global variable {} type is not ``Account``.
                '''.format(account_object_name))
                return

            logger.INFO('''
                ######## Account object ``{}`` restored from the blockchain.
                '''.format(account_object_name))
            return

            #wallet_singleton.is_name_taken(account_object_name, account_name)

    if isinstance(account_name, testnet.Testnet):
        owner_key = account_name.owner_key
        active_key = account_name.active_key
        account_name = account_name.account_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**.
    '''
    account_object = Eosio(account_object_name)

    if is_local_testnet_running(account_object):
        put_account_to_wallet_and_on_stack(account_object_name, account_object,
                                           logger)
        return
    '''
    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.
            ''')

        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 = GetAccount(account_object_name, account_name,
                                    owner_key, active_key, verbosity)

        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))
            return
        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 append_account_methods_and_finish(
                            account_object_name, account_object):
                        logger.TRACE('''
                            * The account ``{}`` is in the wallet.
                            '''.format(account_object.name))
                        return
                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
        else:
            owner_key_new = cleos.CreateKey("owner", is_verbose=False)
            active_key_new = cleos.CreateKey("active", 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
                else:
                    if is_ready == "go":
                        break
            account_name = account_object.name
            owner_key = owner_key_new
            active_key = active_key_new
Beispiel #23
0
def append_account_methods_and_finish(account_object_name, account_object):
    def code(account_object, code="", abi="", wasm=False):
        result = cleos.GetCode(account_object, is_verbose=False)
        logger.INFO('''
        * code()
        ''')
        logger.OUT(str(result))

    account_object.code = types.MethodType(code, account_object)

    def is_code(account_object):
        get_code = cleos.GetCode(account_object.name, is_verbose=False)
        if get_code.code_hash == \
        "0000000000000000000000000000000000000000000000000000000000000000":
            return ""
        else:
            return get_code.code_hash

    account_object.is_code = types.MethodType(is_code, account_object)

    def set_contract(account_object,
                     contract_dir,
                     wast_file="",
                     abi_file="",
                     permission=None,
                     expiration_sec=30,
                     skip_signature=0,
                     dont_broadcast=0,
                     forceUnique=0,
                     max_cpu_usage=0,
                     max_net_usage=0,
                     ref_block=None):

        result = cleos.SetContract(account_object,
                                   contract_dir,
                                   wast_file,
                                   abi_file,
                                   permission,
                                   expiration_sec,
                                   skip_signature,
                                   dont_broadcast,
                                   forceUnique,
                                   max_cpu_usage,
                                   max_net_usage,
                                   ref_block,
                                   is_verbose=False)
        logger.OUT(result)
        account_object.set_contract = result

    account_object.set_contract = types.MethodType(set_contract,
                                                   account_object)

    def push_action(account_object,
                    action,
                    data,
                    permission=None,
                    expiration_sec=30,
                    skip_signature=0,
                    dont_broadcast=0,
                    forceUnique=0,
                    max_cpu_usage=0,
                    max_net_usage=0,
                    ref_block=None,
                    json=False):
        data = _data_json(data)

        result = cleos.PushAction(account_object,
                                  action,
                                  data,
                                  permission,
                                  expiration_sec,
                                  skip_signature,
                                  dont_broadcast,
                                  forceUnique,
                                  max_cpu_usage,
                                  max_net_usage,
                                  ref_block,
                                  is_verbose=False,
                                  json=True)

        logger.INFO('''
            * Push action ``{}``:
            '''.format(action))

        logger.INFO('''
            {}
        '''.format(re.sub(' +', ' ', data)))

        account_object.action = result
        try:
            account_object._console = result.console
            logger.DEBUG(account_object._console)
        except:
            pass
        if json:
            logger.OUT(result.out_msg)

        account_object.action = result

    account_object.push_action = types.MethodType(push_action, account_object)

    def show_action(account_object, action, data, permission=None):
        ''' Implements the `push action` command without broadcasting. 
        '''
        account_object.push_action(action,
                                   data,
                                   permission,
                                   dont_broadcast=1,
                                   json=True)

    account_object.show_action = types.MethodType(show_action, account_object)

    def table(account_object,
              table_name,
              scope="",
              binary=False,
              limit=10,
              key="",
              lower="",
              upper=""):

        logger.INFO('''
        * Table ``{}`` for ``{}``
        '''.format(table_name, scope))

        result = cleos.GetTable(account_object,
                                table_name,
                                scope,
                                binary,
                                limit,
                                key,
                                lower,
                                upper,
                                is_verbose=False)

        try:
            account_map = manager.account_map()
            scope = account_map[str(scope)]
        except:
            pass

        logger.OUT(result.out_msg)
        return result

    account_object.table = types.MethodType(table, account_object)

    def __str__(account_object):
        return account_object.name

    account_object.__str__ = types.MethodType(__str__, account_object)

    def buy_ram(account_object,
                amount_kbytes,
                receiver=None,
                expiration_sec=30,
                skip_signature=0,
                dont_broadcast=0,
                forceUnique=0,
                max_cpu_usage=0,
                max_net_usage=0,
                ref_block=None):

        if manager.is_local_testnet():
            return

        if receiver is None:
            receiver = account_object

        buy_ram_kbytes = 1

        result = cleosys.BuyRam(account_object,
                                receiver,
                                amount_kbytes,
                                buy_ram_kbytes,
                                expiration_sec,
                                skip_signature,
                                dont_broadcast,
                                forceUnique,
                                max_cpu_usage,
                                max_net_usage,
                                ref_block,
                                is_verbose=0)

        logger.INFO('''
            * Transfered RAM from {} to {} kbytes: {}
            '''.format(result.payer, result.receiver, result.amount))

    account_object.buy_ram = types.MethodType(buy_ram, account_object)

    def delegate_bw(account_object,
                    stake_net_quantity,
                    stake_cpu_quantity,
                    receiver=None,
                    permission=None,
                    transfer=False,
                    expiration_sec=30,
                    skip_signature=0,
                    dont_broadcast=0,
                    forceUnique=0,
                    max_cpu_usage=0,
                    max_net_usage=0,
                    ref_block=None,
                    is_verbose=1):

        if manager.is_local_testnet():
            return

        if receiver is None:
            receiver = account_object

        result = cleosys.DelegateBw(account_object,
                                    receiver,
                                    stake_net_quantity,
                                    stake_cpu_quantity,
                                    permission,
                                    transfer,
                                    expiration_sec,
                                    skip_signature,
                                    dont_broadcast,
                                    forceUnique,
                                    max_cpu_usage,
                                    max_net_usage,
                                    ref_block,
                                    is_verbose=0)

        logger.INFO('''
        * Delegated stake from {} to {} NET: {} CPU: {}
        '''.format(result.payer, result.receiver, result.stake_net_quantity,
                   result.stake_cpu_quantity))

    account_object.delegate_bw = types.MethodType(delegate_bw, account_object)

    def info(account_object):
        print("Account object name: {}\n{}".format(
            account_object_name,
            str(cleos.GetAccount(account_object.name, is_verbose=0))))

    account_object.info = types.MethodType(info, account_object)

    get_account = cleos.GetAccount(account_object, is_info=False, is_verbose=0)

    logger.TRACE('''
    * Cross-checked: account object ``{}`` mapped to an existing account ``{}``.
    '''.format(account_object_name, account_object.name),
                 translate=False)

    return put_account_to_wallet_and_on_stack(account_object_name,
                                              account_object)
Beispiel #24
0
def create_account(account_object_name,
                   creator,
                   account_name="",
                   owner_key="",
                   active_key="",
                   stake_net=3,
                   stake_cpu=3,
                   permission=None,
                   buy_ram_kbytes=8,
                   buy_ram="",
                   transfer=False,
                   expiration_sec=30,
                   skip_signature=0,
                   dont_broadcast=0,
                   forceUnique=0,
                   max_cpu_usage=0,
                   max_net_usage=0,
                   ref_block=None,
                   restore=False,
                   verbosity=None):

    global wallet_singleton
    globals = inspect.stack()[1][0].f_globals
    '''
    Check the conditions:
    * a ``Wallet`` object is defined;
    * the account object name is not in use, already.
    '''
    is_wallet_defined(logger)
    if wallet_singleton is None:
        return
    #wallet_singleton.is_name_taken(account_object_name, account_name)

    if account_object_name in globals:

        if not isinstance(globals[account_object_name], interface.Account):
            raise errors.Error('''
            The global variable ``{}`` type is not ``Account``.
            '''.format(account_object_name))
            return

        logger.INFO('''
            ######## Account object ``{}`` restored from the blockchain.
            '''.format(account_object_name))
        return

    logger.INFO('''
        ######### Create an account object ``{}``.
        '''.format(account_object_name))
    '''
    Create an account object.
    '''
    account_object = None

    if restore:
        if creator:
            account_name = creator
        logger.INFO('''
                    ... for an existing blockchain account ``{}`` mapped as ``{}``.
                    '''.format(account_name, account_object_name),
                    translate=False)
        account_object = RestoreAccount(account_name, verbosity)
        account_object.account_object_name = account_object_name
    else:
        if not account_name:
            account_name = cleos.account_name()
        if owner_key:
            if not active_key:
                active_key = owner_key
        else:
            owner_key = cleos.CreateKey("owner", is_verbose=False)
            active_key = cleos.CreateKey("active", is_verbose=False)

        if stake_net and not manager.is_local_testnet():
            logger.INFO('''
                        ... delegating stake to a new blockchain account ``{}`` mapped as ``{}``.
                        '''.format(account_name, account_object_name))

            try:
                account_object = SystemNewaccount(
                    creator, account_name, owner_key, active_key, stake_net,
                    stake_cpu, permission, buy_ram_kbytes, buy_ram, transfer,
                    expiration_sec, skip_signature, dont_broadcast,
                    forceUnique, max_cpu_usage, max_net_usage, ref_block,
                    verbosity)
            except errors.LowRamError as e:
                logger.TRACE('''
                * RAM needed is {}.kByte, buying RAM {}.kByte.
                '''.format(e.needs_kbyte, e.deficiency_kbyte))

                buy_ram_kbytes = str(e.deficiency_kbyte + 1)
                account_object = SystemNewaccount(
                    creator, account_name, owner_key, active_key, stake_net,
                    stake_cpu, permission, buy_ram_kbytes, buy_ram, transfer,
                    expiration_sec, skip_signature, dont_broadcast,
                    forceUnique, max_cpu_usage, max_net_usage, ref_block,
                    verbosity)
        else:
            logger.INFO('''
                        ... for a new blockchain account ``{}``.
                        '''.format(account_name))
            account_object = CreateAccount(creator, account_name, owner_key,
                                           active_key, permission,
                                           expiration_sec, skip_signature,
                                           dont_broadcast, forceUnique,
                                           max_cpu_usage, max_net_usage,
                                           ref_block, verbosity)

        account_object.account_object_name = account_object_name
        account_object.owner_key = owner_key
        account_object.active_key = active_key

    logger.TRACE('''
        * The account object is created.
        ''')
    append_account_methods_and_finish(account_object_name, account_object)
Beispiel #25
0
    def set_account_permission(self,
                               permission_name,
                               authority,
                               parent_permission_name,
                               permission=None,
                               expiration_sec=None,
                               skip_sign=0,
                               dont_broadcast=0,
                               return_packed=0,
                               force_unique=0,
                               max_cpu_usage=0,
                               max_net_usage=0,
                               ref_block=None,
                               delay_sec=0):
        '''Set parameters dealing with account permissions.

        Call *EOSIO cleos* with the *set account permission* command. Store
        the result, which is an object of the 
        class :class:`.cleos_set.SetAccountPermission`, as the value of the *account_permission* attribute.

        Args:
            permission_name (str or .Permission): The permission to set/delete an 
                authority for.
            parent_permission_name (str or .Permission): The permission name of 
                this parents permission (defaults to: "active").
            authority (str or dict or filename):  None to delete.

        Exemplary values of the argument *authority*::

            # bob, carol are account objects created with 
            # shell.account.create_account factory function

            str_value = "EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV"

            permission_value = bob.active()

            dict_value = {
                "threshold" : 100, 
                "keys" : [], 
                "accounts" : 
                    [
                        {
                            "permission":
                                {
                                    "actor": bob.active(),
                                    "permission":"active"
                                },
                            "weight":100
                        }
                    ]
            }

        See definitions of the remaining parameters: \
        :func:`.cleos.common_parameters`.
        '''
        stop_if_account_is_not_set(self)
        logger.TRACE('''
            * Set action permission.
            ''')
        result = cleos_set.SetAccountPermission(self,
                                                permission_name,
                                                authority,
                                                parent_permission_name,
                                                permission,
                                                expiration_sec,
                                                skip_sign,
                                                dont_broadcast,
                                                return_packed,
                                                force_unique,
                                                max_cpu_usage,
                                                max_net_usage,
                                                ref_block,
                                                delay_sec,
                                                is_verbose=False,
                                                json=True)

        logger.INFO('''
            * account permission ``{}``:
            '''.format(authority))

        self.account_permission = result
Beispiel #26
0
def ABI(
        contract_dir_hint=None, c_cpp_properties_path=None,
        verbosity=None):
    '''Given a hint to a contract directory, produce ABI file.
    '''
    contract_dir = config.contract_dir(contract_dir_hint)
    # source_files[0] is directory, source_files[1] is contents:
    contract_source_files = config.contract_source_files(contract_dir)

    source_files = []
    source_ext = [".c", ".cpp",".cxx", ".c++"]
    for file in contract_source_files[1]:
        if os.path.splitext(file)[1].lower() in source_ext:
            source_files.append(file)

    if not source_files:
        raise errors.Error('''
        "The source is empty. The assumed contract dir is   
        {}
        '''.format(contract_dir))
        return

    code_name = os.path.splitext(os.path.basename(source_files[0]))[0]
    target_dir = get_target_dir(contract_source_files[0])
    target_path = os.path.normpath(
                        os.path.join(target_dir, code_name  + ".abi"))

    for file in contract_source_files[1]:
        if os.path.splitext(file)[1].lower() == ".abi":
            logger.INFO('''
            NOTE:
            An ABI exists in the source directory. Cannot overwrite it:
            {}
            Just copying it to the target directory.
            '''.format(file), verbosity)
            shutil.move(file, target_path)
            return

    command_line = [
        config.eosio_cpp(),
        "-contract=" + code_name,
        "-R=" + get_resources_dir(contract_source_files[0]),
        "-abigen",
        "-abigen_output=" + target_path]

    c_cpp_properties = get_c_cpp_properties(
                                    contract_dir, c_cpp_properties_path)

    for entry in c_cpp_properties[CONFIGURATIONS][0][INCLUDE_PATH]:
        if WORKSPACE_FOLDER in entry:
            entry = entry.replace(WORKSPACE_FOLDER, contract_dir)
            command_line.append(
                "-I" + utils.wslMapWindowsLinux(entry))
        else:
            if not EOSIO_CPP_INCLUDE in entry:
                command_line.append(
                    "-I" + utils.wslMapWindowsLinux(
                        strip_wsl_root(entry)))

    for file in source_files:
        command_line.append(file)

    try:
        eosio_cpp(command_line, target_dir)
    except Exception as e:
        raise errors.Error(str(e))

    logger.TRACE('''
    ABI file writen to file: 
        {}
    '''.format(target_path), verbosity)
Beispiel #27
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
Beispiel #28
0
def create_account(account_object_name,
                   creator,
                   account_name="",
                   owner_key="",
                   active_key="",
                   stake_net=3,
                   stake_cpu=3,
                   permission=None,
                   expiration_sec=None,
                   skip_sign=0,
                   dont_broadcast=0,
                   force_unique=0,
                   max_cpu_usage=0,
                   max_net_usage=0,
                   ref_block=None,
                   delay_sec=0,
                   buy_ram_kbytes=8,
                   buy_ram="",
                   transfer=False,
                   restore=False):
    '''Create account object in caller's global namespace.
    
    Args:
        account_object_name (str): The name of the account object returned.
        creator (str or .core.interface.Account): The account creating the new 
            account
        account_name (str): The name of an valid EOSIO account. If not set, it 
            is random.
        owner_key (.core.interface.Key): The *owner* key pair. If not set, it
            is random.
        active_key (.core.interface.Key): The *active* key pair. If not set, 
            and the *owner_key* is set, it is substituted with the *owner_key*.
            Otherwise, it is random.
        stake_net (int): The amount of EOS delegated for net bandwidth.
        stake_cpu (int): The amount of EOS delegated for CPU bandwidth.
        buy_ram_kbytes (int): The amount of RAM bytes to purchase.
        transfer (bool): Transfer voting power and right to unstake EOS to 
            receiver.

    See definitions of the remaining parameters: \
    :func:`.cleos.common_parameters`.
    '''
    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):
        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 an account object ``{}``.
        '''.format(account_object_name))
    '''
    Create an account object.
    '''
    account_object = None

    if restore:
        if creator:
            account_name = creator
        logger.INFO('''
                    ... for an existing blockchain account ``{}`` 
                        mapped as ``{}``.
                    '''.format(account_name, account_object_name),
                    translate=False)
        account_object = account.RestoreAccount(account_name)
        account_object.account_object_name = account_object_name
    else:
        if not account_name:
            account_name = cleos.account_name()
        if owner_key:
            if not active_key:
                active_key = owner_key
        else:
            owner_key = cleos.CreateKey(is_verbose=False)
            active_key = cleos.CreateKey(is_verbose=False)

        if stake_net and not manager.is_local_testnet():
            logger.INFO('''
                        ... delegating stake to a new blockchain account ``{}`` mapped as ``{}``.
                        '''.format(account_name, account_object_name))

            try:
                account_object = account.SystemNewaccount(
                    creator, account_name, owner_key, active_key, stake_net,
                    stake_cpu, permission, buy_ram_kbytes, buy_ram, transfer,
                    expiration_sec, skip_sign, dont_broadcast, force_unique,
                    max_cpu_usage, max_net_usage, ref_block, delay_sec)
            except errors.LowRamError as e:
                logger.TRACE('''
                * RAM needed is {}.kByte, buying RAM {}.kByte.
                '''.format(e.needs_kbyte, e.deficiency_kbyte))

                buy_ram_kbytes = str(e.deficiency_kbyte + 1)
                account_object = account.SystemNewaccount(
                    creator, account_name, owner_key, active_key, stake_net,
                    stake_cpu, permission, buy_ram_kbytes, buy_ram, transfer,
                    expiration_sec, skip_sign, dont_broadcast, force_unique,
                    max_cpu_usage, max_net_usage, ref_block, delay_sec)
        else:
            logger.INFO('''
                        ... for a new blockchain account ``{}``.
                        '''.format(account_name))
            account_object = account.CreateAccount(
                creator, account_name, owner_key, active_key, permission,
                expiration_sec, skip_sign, dont_broadcast, force_unique,
                max_cpu_usage, max_net_usage, ref_block, delay_sec)

        account_object.account_object_name = account_object_name
        account_object.owner_key = owner_key
        account_object.active_key = active_key

    logger.TRACE('''
        * The account object is created.
        ''')
    Account.add_methods_and_finalize(account_object_name, account_object)
    return account_object
Beispiel #29
0
 def lock(self):
     ''' Lock the wallet.
     Returns `cleos.WalletLock` object.
     '''
     cleos.WalletLock(self.name, is_verbose=False)
     logger.TRACE("Wallet `{}` locked.".format(self.name))
Beispiel #30
0
def project_from_template(
        project_name, template=None, workspace_dir=None,
        c_cpp_prop_path=None,
        include=None,
        libs=None, 
        remove_existing=False, 
        open_vscode=False, throw_exists=False, 
        verbosity=None):
    '''Given the project name and template name, create a smart contract project.

    - **parameters**::

        project_name: The name of the project, or an existing path to 
            a directory.
        template: The name of the template used.
        workspace_dir: If set, the folder for the work-space. Defaults to the 
            value returned by the config.contract_workspace() function.
        include: If set, comma-separated list of include folders.
        libs: If set, comma-separated list of libraries.
        remove_existing: If set, overwrite any existing project.
        visual_studio_code: If set, open the ``VSCode``, if available.
        verbosity: The logging configuration.
    '''
    project_name = utils.wslMapWindowsLinux(project_name.strip())
    template = template.strip()

    template_dir = utils.wslMapWindowsLinux(template)
    if not os.path.isdir(template_dir):
        template_dir = os.path.join(
            config.eosf_dir(), TEMPLATE_CONTRACTS_DIR, template) 
    if not os.path.isdir(template_dir):
        raise errors.Error('''
        TemplateCreate '{}' does not exist.
        '''.format(template_dir)) 

    if c_cpp_prop_path:
        c_cpp_prop_path = utils.wslMapWindowsLinux(c_cpp_prop_path)
        if os.path.exists(c_cpp_prop_path):
            try:
                with open(c_cpp_prop_path, "r") as input:
                    c_cpp_properties = input.read()
            except Exception:
                c_cpp_properties = vscode.c_cpp_properties()
    else:
        c_cpp_properties = vscode.c_cpp_properties()

    c_cpp_properties = replace_templates(c_cpp_properties)

    if include:
        c_cpp_properties_json = json.loads(c_cpp_properties)
        c_cpp_properties_json[CONFIGURATIONS][0][INCLUDE_PATH].extend(
                                                        include.split(", "))
        c_cpp_properties_json[CONFIGURATIONS][0][BROWSE]["path"].extend(
                                                        include.split(", "))
        c_cpp_properties = json.dumps(c_cpp_properties_json, indent=4)

    if libs:
        c_cpp_properties_json = json.loads(c_cpp_properties)
        c_cpp_properties_json[CONFIGURATIONS][0]["libs"].extend(
                                                        libs.split(", "))
        c_cpp_properties = json.dumps(c_cpp_properties_json, indent=4)


    split = os.path.split(project_name)
    if os.path.isdir(split[0]):
        project_dir = project_name
        project_name = split[1]
    else:
        if not workspace_dir \
                                or not os.path.isabs(workspace_dir) \
                                or not os.path.exists(workspace_dir):
            workspace_dir = config.contract_workspace()
        workspace_dir = workspace_dir.strip()        
        project_dir = os.path.join(workspace_dir, project_name)

    if os.path.isdir(project_dir):
        if os.listdir(project_dir):
            if remove_existing:
                try:
                    shutil.rmtree(project_dir)
                except Exception as e:
                    raise errors.Error('''
Cannot remove the directory {}.
error message:
==============
{}
                    '''.format(project_dir, str(e)))
            else:
                msg = '''
                NOTE:
                Contract workspace
                '{}'
                already exists. Cannot overwrite it.
                '''.format(project_dir)
                if throw_exists:
                    raise errors.Error(msg)
                else:
                    raise errors.Error(msg)
                    return

    try:    # make contract directory and its build directory:
        os.makedirs(os.path.join(project_dir, "build"))
    except Exception as e:
            raise errors.Error(str(e))

    def copy_dir_contents(
            project_dir, template_dir, directory, project_name):
        contents = os.listdir(os.path.join(template_dir, directory))
        
        for item in contents:
            path = os.path.join(directory, item)
            template_path = os.path.join(template_dir, path)
            contract_path = os.path.join(
                project_dir, path.replace(
                                        TEMPLATE_NAME, project_name))
                          
            if os.path.isdir(template_path):
                os.mkdir(contract_path)
                copy_dir_contents(
                            project_dir, template_dir, path, project_name)
            elif os.path.isfile(template_path):

                copy(template_path, contract_path, project_name)

    def copy(template_path, contract_path, project_name):
        with open(template_path, "r") as input:
            template = input.read()

        if TEMPLATE_HOME in template or TEMPLATE_ROOT in template:
            home = os.environ["HOME"]
            root = ""
            if is_windows_ubuntu():
                replace_templates(template)

        template = template.replace("${" + TEMPLATE_NAME + "}", project_name)
        template = template.replace(C_CPP_PROP, c_cpp_properties)
        template = template.replace(TASK_JSON, vscode.TASKS)

        with open(contract_path, "w") as output:
            output.write(template)

    copy_dir_contents(project_dir, template_dir, "", project_name)

    logger.TRACE('''
    * Contract project '{}' created from template 
        '{}'
    '''.format(project_name, template_dir), verbosity)    

    if open_vscode:
        if is_windows_ubuntu():
            command_line = "cmd.exe /C code {}".format(
                utils.wslMapLinuxWindows(project_dir))
        elif uname() == "Darwin":
            command_line = "open -n -b com.microsoft.VSCode --args {}".format(
                project_dir)
        else:
            command_line = "code {}".format(project_dir)

        os.system(command_line)

    logger.INFO('''
    ######### Created contract project ``{}``, 
        originated from template 
        ``{}``.
    '''.format(project_name, template_dir), verbosity)

    return project_dir