def restore_accounts(self): ''' ''' self.open_unlock() account_map = manager.account_map() new_map = {} wallet_keys = cleos.WalletKeys(is_verbose=0) if len(account_map) > 0: logger.INFO(''' ######### Restore cached account objects: ''') for name, object_name in account_map.items(): try: account_ = cleos.GetAccount(name, is_info=False, is_verbose=False) if account_.owner_key in wallet_keys.json and \ account_.active_key in wallet_keys.json: new_map[name] = object_name from eosfactory.shell.account import create_account create_account(object_name, name, restore=True, verbosity=None) except errors.AccountDoesNotExistError: pass manager.save_account_map(new_map) else: logger.INFO(''' * The wallet is empty. ''')
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))
def push_action( self, action, data="{}", 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): '''Push a transaction with a single action. Call *EOSIO cleos* with the *push action* command. Store the result, which is an object of the class :class:`.cleos.PushAction`, as the value of the *action* attribute. Args: action (str or json or filename): Definition of the action to execute on the contract. data (str): The arguments to the contract, defaults to empty json. permission: defaults to self. See definitions of the remaining parameters: \ :func:`.cleos.common_parameters`. Attributes: account_name (str): The EOSIO name of the contract's account. console (str): *["processed"]["action_traces"][0]["console"]* \ component of EOSIO cleos responce. data (str): *["processed"]["action_traces"][0]["act"]["data"]* \ component of EOSIO cleos responce. ''' stop_if_account_is_not_set(self) data = manager.data_json(data) if not permission: permission = self result = cleos.PushAction( self, action, data, permission, expiration_sec, skip_sign, dont_broadcast, force_unique, 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))) self.action = result try: self._console = result.console logger.DEBUG(self._console) except: pass self.action = result
def project_from_template(name, template="", user_workspace=None, remove_existing=False, visual_studio_code=False, verbosity=None): '''Given the template type and a name, create a contract workspace. - **parameters**:: name: The name of the new wallet, defaults to ``default``. template: The name of the template used. user_workspace: If set, the folder for the work-space. Defaults to the value of the ``EOSIO_CONTRACT_WORKSPACE`` env. variable. remove_existing: If set, overwrite any existing workspace. visual_studio_code: If set, open the ``VSCode``, if available. verbosity: The logging configuration. ''' logger.INFO(''' ######### Create contract ``{}`` from template ``{}``. '''.format(name, template)) contract_path_absolute = teos.template_create(name, template, user_workspace, remove_existing, visual_studio_code) return contract_path_absolute
def node_probe(): count = 10 num = 5 block_num = None while True: time.sleep(1) try: import eosfactory.core.cleos_get as cleos_get head_block_num = cleos_get.GetInfo(is_verbose=0).head_block except: head_block_num = 0 finally: print(".", end="", flush=True) if block_num is None: block_num = head_block_num if head_block_num - block_num >= num: print() logger.INFO(''' Local node is running. Block number is {} '''.format(head_block_num)) break count = count - 1 if count <= 0: raise errors.Error(''' The local node does not respond. ''')
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))
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
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
def node_stop(): # You can see if the process is a zombie by using top or # the following command: # ps aux | awk '$8=="Z" {print $2}' pids = get_pid() count = 10 if pids: for pid in pids: os.system("kill " + str(pid)) while count > 0: time.sleep(1) if not is_local_node_process_running(): break count = count -1 if count <= 0: raise errors.Error(''' Failed to kill {}. Pid is {}. '''.format(config.node_exe_name(), str(pids)) ) else: logger.INFO(''' Local node is stopped {}. '''.format(str(pids)))
def reboot(): logger.INFO(''' ######### Reboot EOSFactory session. ''') stop([]) import eosfactory.shell.account as account account.reboot()
def node_probe(): count = 10 num = 5 block_num = None while True: time.sleep(1) try: count = count - 1 head_block_num = int(get_info()) except: head_block_num = 0 finally: print(".", end="", flush=True) if block_num is None: block_num = head_block_num if head_block_num - block_num >= num: print() logger.INFO(''' Local node is running. Block number is {} '''.format(head_block_num)) return True if count <= 0: return False
def delegate_bw( self, stake_net_quantity, stake_cpu_quantity, receiver=None, permission=None, transfer=False, expiration_sec=None, skip_sign=0, dont_broadcast=0, force_unique=0, max_cpu_usage=0, max_net_usage=0, ref_block=None, is_verbose=1): stop_if_account_is_not_set(self) if manager.is_local_testnet(): return if receiver is None: receiver = self result = cleos_sys.DelegateBw( self, receiver, stake_net_quantity, stake_cpu_quantity, permission, transfer, expiration_sec, skip_sign, dont_broadcast, force_unique, 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))
def buy_ram( self, amount_kbytes, receiver=None, expiration_sec=None, skip_sign=0, dont_broadcast=0, force_unique=0, max_cpu_usage=0, max_net_usage=0, ref_block=None): stop_if_account_is_not_set(self) if manager.is_local_testnet(): return if receiver is None: receiver = self buy_ram_kbytes = 1 result = cleos_sys.BuyRam( self, receiver, amount_kbytes, buy_ram_kbytes, expiration_sec, skip_sign, dont_broadcast, force_unique, 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))
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
def table( self, table_name, scope="", binary=False, limit=10, lower="", upper="", index="", key_type="", encode_type="", reverse=False, show_payer=False ): '''Retrieve the contents of a database table Args: table (str): The name of the table as specified by the contract abi. scope (str or .interface.Account): The scope within the account in which the table is found. binary (bool): Return the value as BINARY rather than using abi to interpret as JSON. Default is *False*. limit (int): The maximum number of rows to return. Default is 10. lower (str): JSON representation of lower bound value of key, defaults to first. upper (str): JSON representation of upper bound value value of key, defaults to last. index (int or str): Index number, 1 - primary (first), 2 - secondary index (in order defined by multi_index), 3 - third index, etc. Number or name of index can be specified, e.g. 'secondary' or '2'. key_type (str): The key type of --index, primary only supports (i64), all others support (i64, i128, i256, float64, float128, ripemd160, sha256). Special type 'name' indicates an account name. encode_type (str): The encoding type of key_type (i64 , i128 , float64, float128) only support decimal encoding e.g. 'dec'i256 - supports both 'dec' and 'hex', ripemd160 and sha256 is 'hex' only. reverse (bool): Iterate in reverse order. show_payer (bool): Show RAM payer. Returns: :class:`.cleos_set.SetTable` object ''' stop_if_account_is_not_set(self) logger.INFO(''' * Table ``{}`` for ``{}`` '''.format(table_name, scope)) result = cleos_get.GetTable( self, table_name, scope, binary, limit, lower, upper, index, key_type, encode_type, reverse, show_payer, is_verbose=False) try: account_map = manager.account_map() scope = account_map[str(scope)] except: pass logger.OUT(result.out_msg) return result
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
def status(): ''' Display EOS node status. ''' logger.INFO(''' ######### Node ``{}``, head block number ``{}``. '''.format(setup.nodeos_address(), cleos_get.GetInfo(is_verbose=0).head_block))
def resume(nodeos_stdout=None, verbosity=None): ''' Resume the EOSIO local node. ''' if not cleos.set_local_nodeos_address_if_none(): logger.INFO(''' Not local nodeos is set: {} '''.format(setup.nodeos_address()), verbosity) node_start(nodeos_stdout=nodeos_stdout, verbosity=verbosity)
def reset(nodeos_stdout=None): ''' Start clean the local EOSIO node. The procedure addresses problems with instabilities of EOSIO *nodeos* executable: it happens that it blocks itself on clean restart. The issue is patched with one subsequent restart if the first attempt fails. However, it happens that both launches fail, rarely due to instability of *nodeos*, sometimes because of misconfiguration. When both launch attempts fail, an exception routine passes. At first, the command line is printed, for *example*:: ERROR: The local ``nodeos`` failed to start twice in sequence. Perhaps, something is wrong with configuration of the system. See the command line issued: /usr/bin/nodeosx --http-server-address 127.0.0.1:8888 --data-dir /mnt/c/Workspaces/EOS/eosfactory/localnode/ --config-dir /mnt/c/Workspaces/EOS/eosfactory/localnode/ --chain-state-db-size-mb 200 --contracts-console --verbose-http-errors --enable-stale-production --producer-name eosio --signature-provider EOS6MRyAjQq8ud7hVNYcfnVPJqcVpscN5So8BhtHuGYqET5GDW5CV=KEY:5KQwrPbwdL6PhXujxW37FSSQZ1JiwsST4cqQzDeyXtP79zkvFD3 --plugin eosio::producer_plugin --plugin eosio::chain_api_plugin --plugin eosio::http_plugin --plugin eosio::history_api_plugin --genesis-json /mnt/c/Workspaces/EOS/eosfactory/localnode/genesis.json --delete-all-blocks Next, the command line is executed, for *example*:: Now, see the result of an execution of the command line. /bin/sh: 1: /usr/bin/nodeosx: not found The exemplary case is easy, it explains itself. Generally, the command line given can be executed in a *bash* terminal separately, in order to understand a problem. Args: nodeos_stdout (str): If set, a file where *stdout* stream of the local *nodeos* is send. Note that the file can be included to the configuration of EOSFactory, see :func:`.core.config.nodeos_stdout`. If the file is set with the configuration, and in the same time it is set with this argument, the argument setting prevails. ''' if not cleos.set_local_nodeos_address_if_none(): logger.INFO(''' No local nodeos is set: {} '''.format(setup.nodeos_address())) import eosfactory.shell.account as account teos.keosd_start() account.reboot() clear_testnet_cache() node_start(clear=True, nodeos_stdout=nodeos_stdout)
def testnets(): mapping = get_mapping() if not mapping: logger.INFO(''' Testnet mapping is empty. ''') return for alias, testnet in mapping.items(): print("%25s: %13s @ %s" % (alias, testnet["account_name"], testnet["url"]))
def status(): ''' Display EOS node status. ''' get_info = cleos.GetInfo(is_verbose=0) logger.INFO(''' ######### Node ``{}``, head block number ``{}``. '''.format( setup.nodeos_address(), get_info.json["head_block_num"]))
def node_stop(verbose=True): # You can see if the process is a zombie by using top or # the following command: # ps aux | awk '$8=="Z" {print $2}' kill_keosd() pids = kill(os.path.splitext(os.path.basename(config.node_exe()))[0]) if verbose: logger.INFO(''' Local node is stopped {}. '''.format(str(pids)))
def testnets(): '''Print recorded :class:`.Testnet` objects. ''' mapping = manager.read_map(TESTNET_FILE) if not mapping: logger.INFO(''' Testnet mapping is empty. ''') return for name, testnet in mapping.items(): print("%25s: %13s @ %s" % (name, testnet["account_name"], testnet["url"]))
def verify_testnet_production(): result = is_head_block_num() domain = "LOCAL" if is_local_testnet() else "REMOTE" if not result: raise errors.Error(''' {} testnet is not running or is not responding @ {}. '''.format(domain, setup.nodeos_address())) else: logger.INFO(''' {} testnet is active @ {}. '''.format(domain, setup.nodeos_address())) return result
def reset(verbosity=None): ''' Start clean the EOSIO local node. ''' if not cleos.set_local_nodeos_address_if_none(): logger.INFO(''' No local nodeos is set: {} '''.format(setup.nodeos_address()), verbosity) import eosfactory.shell.account as account account.reboot() clear_testnet_cache() teos.node_start(clear=True, verbosity=verbosity)
def code(self, code=None, abi=None, wasm=False): '''Retrieve the code and ABI Args: code (str): If set, the name of the file to save the contract WAST/WASM to. abi (str): If set, the name of the file to save the contract ABI to. wasm (bool): Save contract as wasm. ''' result = cleos_get.GetCode(self, is_verbose=False) logger.INFO(''' * code() ''') logger.OUT(str(result))
def config_file(): file = os.path.join(eosf_dir(), CONFIG_JSON) if not os.path.exists(file): with open(file, "w") as output: output.write("{}") logger.INFO(''' Cannot find the config json file. It is expected to be '{}'. Creating an empty config file there. '''.format(file)) return file
def table(self, table_name, scope="", binary=False, limit=10, key="", lower="", upper=""): '''Retrieve the contents of a database table Args: scope (str or .interface.Account): The scope within the account in which the table is found. table (str): The name of the table as specified by the contract abi. binary (bool): Return the value as BINARY rather than using abi to interpret as JSON. Default is *False*. limit (int): The maximum number of rows to return. Default is 10. lower (str): JSON representation of lower bound value of key, defaults to first. upper (str): JSON representation of upper bound value value of key, defaults to last. Returns: :class:`.cleos_set.SetTable` object ''' logger.INFO(''' * Table ``{}`` for ``{}`` '''.format(table_name, scope)) result = cleos_get.GetTable(self, 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
def resume(nodeos_stdout=None): ''' Resume the local EOSIO node. Args: nodeos_stdout (str): If set, a file where *stdout* stream of the local *nodeos* is send. Note that the file can be included to the configuration of EOSFactory, see :func:`.core.config.nodeos_stdout`. If the file is set with the configuration, and in the same time it is set with this argument, the argument setting prevails. ''' if not cleos.set_local_nodeos_address_if_none(): logger.INFO(''' Not local nodeos is set: {} '''.format(setup.nodeos_address())) node_start(nodeos_stdout=nodeos_stdout)
def verify_testnet_production(): head_block_num = 0 try: # if running, json is produced head_block_num = cleos_get.GetInfo(is_verbose=False).head_block except: pass domain = "LOCAL" if is_local_testnet() else "REMOTE" if not head_block_num: raise errors.Error(''' {} testnet is not running or is not responding @ {}. '''.format(domain, setup.nodeos_address())) else: logger.INFO(''' {} testnet is active @ {}. '''.format(domain, setup.nodeos_address())) return head_block_num