def handle_invoke_config(project_dir_path: str, config: str): try: if config != '': config_path = os.path.join(project_dir_path, config) if not os.path.exists(config_path): if os.path.dirname(config) != '': raise PunicaException(PunicaError.other_error(config + ' not found')) else: config_path = os.path.join(project_dir_path, 'contracts', config) if not os.path.exists(config_path): raise PunicaException(PunicaError.other_error(config_path + ' not exist')) else: config_path = os.path.join(project_dir_path, 'contracts', DEFAULT_CONFIG) if not os.path.exists(config_path): raise PunicaException(PunicaError.other_error(config_path + ' not found')) with open(config_path, 'r') as f: config = json.load(f) except FileNotFoundError: raise PunicaException(PunicaError.config_file_not_found) try: wallet_file = config['defaultWallet'] invoke_config = config['invokeConfig'] password_config = config['password'] except KeyError: raise PunicaException(PunicaError.other_error('the config file lack invokeConfig or password')) if not isinstance(invoke_config, dict): raise PunicaException(PunicaError.config_file_error) return wallet_file, invoke_config, password_config
def list_all_functions(project_dir: str, config_name: str): if config_name == '': config_name = DEFAULT_CONFIG try: wallet_file, invoke_config, password_config = handle_invoke_config(project_dir, config_name) except Exception as e: print(e.args) return try: abi_file_name = invoke_config['abi'] except KeyError: raise PunicaException(PunicaError.config_file_error) abi_dir_path = os.path.join(project_dir, 'contracts', 'build') try: dict_abi = read_abi(abi_dir_path, abi_file_name) except PunicaException as e: print(e.args) return try: func_in_abi_list = dict_abi['functions'] except KeyError: raise PunicaException(PunicaError.other_error('abi file is wrong')) func_name_in_abi_list = list() for func_in_abi_dict in func_in_abi_list: try: func_name = func_in_abi_dict['name'] except KeyError: raise PunicaException(PunicaError.other_error('abi file is wrong')) func_name_in_abi_list.append(func_name) print("All Functions:") invoke_function_list = invoke_config['functions'] for function_information in invoke_function_list: if function_information['operation'] in func_name_in_abi_list: print('\t', function_information['operation'])
def read_wallet(project_path: str, wallet_file_name: str = '') -> WalletManager: if not os.path.isdir(project_path): raise PunicaException(PunicaError.directory_error) wallet_manager = WalletManager() if wallet_file_name == '' or wallet_file_name == '"': wallet_dir_path = os.path.join(project_path, 'wallet') dir_list = os.listdir(wallet_dir_path) if len(dir_list) == 1: wallet_path = os.path.join(wallet_dir_path, dir_list[0]) elif os.path.exists(os.path.join(wallet_dir_path, 'wallet.json')): print('Use the default wallet file: wallet.json') wallet_path = os.path.join(wallet_dir_path, 'wallet.json') else: raise PunicaException(PunicaError.wallet_file_unspecified) else: wallet_path = os.path.join(project_path, wallet_file_name) if not os.path.exists(wallet_path): if os.path.dirname(wallet_file_name) != '': raise PunicaException(PunicaError.other_error(wallet_file_name + ' not found')) wallet_path = os.path.join(project_path, 'wallet', wallet_file_name) if not os.path.exists(wallet_path): raise PunicaError.other_error(wallet_path, ' is error') try: wallet_manager.open_wallet(wallet_path) except SDKException as e: raise PunicaException(PunicaError.wallet_file_error) return wallet_manager
def handle_deploy_config(project_dir_path: str, config: str = ''): try: if config != '': config_path = os.path.join(project_dir_path, config) if os.path.exists(config_path): if not os.path.isfile(config_path): raise PunicaError.other_error(config_path, ' is not file') else: config_path = os.path.join(project_dir_path, 'contracts', config) if not os.path.exists(config_path): raise PunicaError.other_error(config_path, ' not exist') else: config_path = os.path.join(project_dir_path, 'contracts', DEFAULT_CONFIG) if not os.path.exists(config_path): print(config_path, ' not exist') os._exit(0) with open(config_path, 'r') as f: config = json.load(f) except FileNotFoundError: raise PunicaException(PunicaError.config_file_not_found) try: wallet_file = config['defaultWallet'] deploy_information = config['deployConfig'] password_information = config['password'] except KeyError: raise PunicaException(PunicaError.config_file_error) if not isinstance(deploy_information, dict): raise PunicaException(PunicaError.config_file_error) return wallet_file, deploy_information, password_information
def read_abi(abi_dir_path: str, abi_file_name: str) -> dict: if not os.path.isdir(abi_dir_path): raise PunicaException(PunicaError.other_error('build folder not exist, please compile first')) abi_file_path = os.path.join(abi_dir_path, abi_file_name) if not os.path.exists(abi_file_path): raise PunicaException(PunicaError.other_error('abi config file not exist')) with open(abi_file_path, 'r') as f: dict_abi = json.load(f) return dict_abi
def params_normalize2(list_param: list): list_params = list() for param in list_param: if isinstance(param, dict): item = param.get('value', '') if isinstance(item, bool): list_params.append(item) elif isinstance(item, int): list_params.append(item) elif isinstance(item, str): list_params.append(Invoke.handle_param_str2(item)) elif isinstance(item, list): list_temp = list() for i in item: list_temp.append(Invoke.parse_param(i)) list_params.append(list_temp) elif isinstance(item, dict): dict_temp = dict() for k, v in item.items(): dict_temp[k] = Invoke.parse_param(v) list_params.append(dict_temp) else: raise PunicaException( PunicaError.other_error('not support data type')) return list_params
def handle_network_config(config_dir_path: str, network: str = '', is_print: bool = True) -> str: try: print(config_dir_path) config_file_path = os.path.join(config_dir_path, 'punica-config.json') with open(config_file_path, 'r') as f: config = json.load(f) except FileNotFoundError: raise PunicaException(PunicaError.config_file_not_found) try: network_dict = config['networks'] default_net = config['defaultNet'] except KeyError: raise PunicaException(PunicaError.config_file_error) if network == '': if default_net == '': network = list(network_dict.keys())[0] else: default_network = network_dict.get(default_net, '') if default_network == '': raise PunicaException(PunicaError.other_error('there is not the network: ' + default_net)) else: network = default_net try: rpc_address = ''.join([network_dict[network]['host'], ':', str(network_dict[network]['port'])]) except KeyError: raise PunicaException(PunicaError.config_file_error) if is_print: print('Using network \'{}\'.\n'.format(network)) return rpc_address
def compile_contract(contract_path: str, local: bool = False, abi_save_path: str = '', avm_save_path: str = ''): if abi_save_path == '': split_path = os.path.split(contract_path) save_path = os.path.join(os.path.dirname(split_path[0]), 'build', split_path[1]) if save_path.endswith('.py'): abi_save_path = save_path.replace('.py', '_abi.json') else: abi_save_path = save_path.replace('.cs', '_abi.json') if avm_save_path == '': split_path = os.path.split(contract_path) save_path = os.path.join(os.path.dirname(split_path[0]), 'build', split_path[1]) if avm_save_path.endswith('.py'): avm_save_path = save_path.replace('.py', '.avm') else: avm_save_path = save_path.replace('.cs', '.avm') if not local: PunicaCompiler.compile_contract_remote(contract_path) return try: PunicaCompiler.generate_avm_file(contract_path, avm_save_path) PunicaCompiler.generate_abi_file(contract_path, abi_save_path) print('Compiled, Thank you') except PermissionError as error: if error.args[0] == 13: raise PunicaException(PunicaError.permission_error) else: raise PunicaException(PunicaError.other_error(error.args[1]))
def save_avm_file(avm_code: str, to_path: str): try: with open(to_path, 'w') as f: f.write(avm_code.lstrip('b\'').rstrip('\'')) except PermissionError as error: if error.args[0] == 13: raise PunicaException(PunicaError.permission_error) else: raise PunicaException(PunicaError.other_error(error.args[1]))
def get_password(): while True: acct_password = getpass.getpass('Please input password: '******'Please repeat password: '******'password not match'))
def params_normalize(dict_params: dict) -> list: list_params = list() if len(dict_params) == 0: return list_params for param in dict_params.values(): if isinstance(param, list): for i in range(len(param)): list_params2 = list() if isinstance(param[i], dict): for p in param[i].values(): if isinstance(p, str): list_p = p.split(':') if len(list_p) != 2: raise PunicaError.other_error('parameters error') if list_p[0] == 'ByteArray': if len(list_p[1]) == 34: list_params2.append(Address.b58decode(list_p[1]).to_array()) else: list_params2.append(list_p[1].encode()) elif list_p[0] == 'String': list_params2.append(list_p[1]) elif isinstance(p, int): list_params2.append(p) list_params.append(list_params2) elif isinstance(param, str): list_p = param.split(':') if len(list_p) != 2: raise PunicaError.other_error("parameters error") if list_p[0] == 'ByteArray': if len(list_p[1]) == 34: try: bs = Address.b58decode(list_p[1]).to_array() list_params.append(bs) except SDKException: list_params.append(list_p[1].encode()) else: list_params.append(list_p[1].encode()) elif list_p[0] == 'String': list_params.append(list_p[1]) elif isinstance(param, int): list_params.append(param) return list_params
def compile_contract_remote(contract_path: str): with open(contract_path, "r") as f: contract = f.read() dict_payload = dict() if contract_path.endswith('.py'): dict_payload['type'] = 'Python' dict_payload['code'] = contract url = PYTHON_COMPILE_URL else: dict_payload['type'] = 'CSharp' dict_payload['code'] = contract url = CSHARP_COMPILE_URL header = {'Content-type': 'application/json'} timeout = 10 path = os.path.dirname(contract_path) file_name = os.path.basename(contract_path).split(".") requests.packages.urllib3.disable_warnings(InsecureRequestWarning) session = requests.session() response = session.post(url, json=dict_payload, headers=header, timeout=timeout, verify=False) if response.status_code != 200: raise PunicaException( PunicaError.get_error(5000, 'Remote compile failed.')) result = json.loads(response.content.decode('utf-8')) if result["errcode"] == 0: avm_save_path = os.path.join(path, 'build', file_name[0] + ".avm") if not os.path.exists(os.path.join(path, 'build')): os.makedirs(os.path.join(path, 'build')) with open(avm_save_path, "w", encoding='utf-8') as f: avm = result["avm"].lstrip('b\'') temp = avm.rstrip('\'') f.write(temp) abi_save_path = os.path.join(path, 'build', file_name[0] + "_abi.json") with open(abi_save_path, "w", encoding='utf-8') as f2: r = re.sub('\\\\n', '', str(result["abi"])) abi = str(r.lstrip('b\'')) temp = abi.rstrip('\'') f2.write(temp.replace(' ', '')) print("Compiled, Thank you") invoke_config_path = os.path.join(path, DEFAULT_CONFIG) if os.path.exists(invoke_config_path): PunicaCompiler.update_invoke_config( abi_save_path, invoke_config_path) else: PunicaCompiler.generate_invoke_config( abi_save_path, invoke_config_path) else: print("compile failed") print(result)
def generate_signed_deploy_transaction(hex_avm_code: str, project_path: str = '', wallet_file_name: str = '', config: str = ''): wallet_file, deploy_information, password_information = handle_deploy_config( project_path, config) if wallet_file_name != '': wallet_manager = read_wallet(project_path, wallet_file_name) else: wallet_manager = read_wallet(project_path, wallet_file) need_storage = deploy_information.get('needStorage', True) name = deploy_information.get('name', os.path.split(project_path)[1]) version = deploy_information.get('version', '0.0.1') author = deploy_information.get('author', '') email = deploy_information.get('email', '') desc = deploy_information.get('desc', '') b58_payer_address = deploy_information.get('payer', '') if b58_payer_address == '': b58_payer_address = wallet_manager.get_default_account( ).get_address() if b58_payer_address == '': raise PunicaException( PunicaError.other_error('payer address should not be None')) gas_limit = deploy_information.get('gasLimit', 21000000) gas_price = deploy_information.get('gasPrice', 500) ontology = OntologySdk() tx = ontology.neo_vm().make_deploy_transaction(hex_avm_code, need_storage, name, version, author, email, desc, b58_payer_address, gas_limit, gas_price) password = password_information.get(b58_payer_address, '') if password == '': password = getpass.getpass( '\tPlease input payer account password: '******' not found')) ontology.sign_transaction(tx, payer_acct) return tx
def list_boxes(self): response = requests.get(self.__box_repos_url).content.decode() repos = json.loads(response) if isinstance(repos, dict): message = repos.get('message', '') if 'API rate limit exceeded' in message: raise PunicaException(PunicaError.other_error(message)) echo('\nThe easiest way to get started:\n') for index, repo in enumerate(repos): name = repo.get('name', '') echo(f' {index}. {name}') echo('')
def get_function(params: dict, function_name: str, abi_info: AbiInfo): if function_name == '': raise PunicaException(PunicaError.other_error('function_name should not be nil')) params = Invoke.params_normalize(params) abi_function = abi_info.get_function(function_name) if len(abi_function.parameters) == 0: pass elif len(abi_function.parameters) == 1: abi_function.set_params_value((params,)) elif len(abi_function.parameters) == len(params): abi_function.set_params_value(tuple(params)) return abi_function
def list_boxes(): repos_url = 'https://api.github.com/users/punica-box/repos' response = requests.get(repos_url).content.decode() repos = json.loads(response) if isinstance(repos, dict): message = repos.get('message', '') if 'API rate limit exceeded' in message: raise PunicaException(PunicaError.other_error(message)) name_list = [] for repo in repos: name = repo.get('name', '') name_list.append(name) return name_list
def git_clone(repo_url: str, repo_to_path: str = ''): if repo_to_path == '': repo_to_path = os.getcwd() print('Downloading...') try: git.Repo.clone_from(url=repo_url, to_path=repo_to_path, depth=1) except git.GitCommandError as e: network_error = 'Could not read from remote repository' file_exist_error = 'already exists and is not an empty directory' if network_error in str(e.args[2]): raise PunicaException(PunicaError.network_error) elif file_exist_error in str(e.args[2]): raise PunicaException(PunicaError.file_exist_error) else: raise PunicaException(PunicaError.other_error(e.args[2]))
def parse_param(param): if isinstance(param, bool): return param elif isinstance(param, int): return param elif isinstance(param, str): return Invoke.handle_param_str2(param) elif isinstance(param, list): list_temp = list() for i in param: list_temp.append(Invoke.parse_param(i)) return list_temp elif isinstance(param, dict): dict_temp = dict() for k, v in param.items(): dict_temp[k] = Invoke.parse_param(v) return dict_temp else: raise PunicaException(PunicaError.other_error('not support data type'))
def read_avm(avm_dir_path: str, avm_file_name: str = '') -> (str, str): if not os.path.isdir(avm_dir_path): raise PunicaException(PunicaError.directory_error) if avm_file_name != '': avm_file_path = os.path.join(avm_dir_path, avm_file_name) if not os.path.exists(avm_file_path): raise PunicaException(PunicaError.other_error(avm_file_path + ' not exist')) with open(avm_file_path, 'r') as f: hex_avm = f.read() else: dir_list = os.listdir(avm_dir_path) hex_avm = '' for file in dir_list: split_path = os.path.splitext(file) if (split_path[0] == avm_file_name or avm_file_name == '') and split_path[1] == '.avm': avm_file_name = ''.join(split_path) avm_path = os.path.join(avm_dir_path, file) with open(avm_path, 'r') as f: hex_avm = f.read() break return hex_avm, avm_file_name
def download_repo(repo_url: str, repo_to_path: str = ''): if repo_to_path == '': repo_to_path = getcwd() spinner = Halo(spinner='dots') def calcu_progress_scale(cur_count: int, max_count: int): return round(cur_count / max_count * 100, 2) def show_spinner(stage_info: str, cur_count: int, max_count: int, message: str = ''): if spinner.spinner_id is None: spinner.start() scale = calcu_progress_scale(cur_count, max_count) if len(message) == 0: spinner.text = f'{stage_info}: {scale}% ({cur_count}/{max_count})' else: spinner.text = f'{stage_info}: {scale}%, {message}' if scale == 100: spinner.succeed() return def update(self, op_code: RemoteProgress, cur_count: int, max_count: int = None, message: str = ''): if op_code == RemoteProgress.COUNTING: show_spinner('Counting objects', cur_count, max_count) return if op_code == RemoteProgress.COMPRESSING: show_spinner('Compressing objects', cur_count, max_count) return if op_code == RemoteProgress.RECEIVING: show_spinner('Receiving objects', cur_count, max_count, message) return if op_code == RemoteProgress.RESOLVING: show_spinner('Resolving deltas', cur_count, max_count) return if op_code == RemoteProgress.WRITING: show_spinner('Writing objects', cur_count, max_count) return if op_code == RemoteProgress.FINDING_SOURCES: show_spinner('Finding sources', cur_count, max_count) return if op_code == RemoteProgress.CHECKING_OUT: show_spinner('Checking out files', cur_count, max_count) return RemoteProgress.update = update try: Repo.clone_from(url=repo_url, to_path=repo_to_path, depth=1, progress=RemoteProgress()) if spinner.spinner_id is not None and len(spinner.text) != 0: spinner.fail() return False return True except GitCommandError as e: if spinner.spinner_id is not None and len(spinner.text) != 0: spinner.fail() if e.status == 126: echo('Please check your network.') elif e.status == 128: echo('Please check your Git tool.') else: raise PunicaException(PunicaError.other_error(e.args[2])) return False
def invoke_all_function_in_list(wallet_file_name: str = '', project_dir_path: str = '', network: str = '', exec_func_str: str = ''): if project_dir_path == '': project_dir_path = os.getcwd() if not os.path.isdir(project_dir_path): raise PunicaException(PunicaError.dir_path_error) ontology = OntologySdk() wallet_dir_path = os.path.join(project_dir_path, 'wallet') ontology.wallet_manager = read_wallet(wallet_dir_path, wallet_file_name) rpc_address = handle_network_config(project_dir_path, network) ontology.rpc.set_address(rpc_address) invoke_config, password_config = handle_invoke_config(project_dir_path) try: abi_file_name = invoke_config['abi'] except KeyError: raise PunicaException(PunicaError.config_file_error) try: default_b58_payer_address = invoke_config['defaultPayer'] except KeyError: raise PunicaException(PunicaError.config_file_error) print('Running invocation: {}'.format(abi_file_name)) abi_dir_path = os.path.join(project_dir_path, 'contracts', 'build') dict_abi = read_abi(abi_dir_path, abi_file_name) try: hex_contract_address = dict_abi['hash'] except KeyError: raise PunicaException(PunicaError.abi_file_error) if not isinstance(hex_contract_address, str) or len(hex_contract_address) != 40: raise PunicaException(PunicaError.abi_file_error) contract = ontology.rpc.get_smart_contract(hex_contract_address) if contract == 'unknow contracts': print('Contract 0x{} hasn\'t been deployed in current network: {}'.format(hex_contract_address, network)) raise PunicaException(PunicaError.abi_file_error) contract_address = bytearray(binascii.a2b_hex(hex_contract_address)) contract_address.reverse() abi_info = Invoke.generate_abi_info(dict_abi) gas_price = invoke_config.get('gasPrice', 500) gas_limit = invoke_config.get('gasLimit', 21000000) invoke_function_dict = invoke_config.get('Functions', dict()) all_exec_func = list() if exec_func_str != '': all_exec_func = exec_func_str.split(',') for exec_func in all_exec_func: if exec_func not in invoke_function_dict.keys(): raise PunicaError.other_error('there is not the function :', exec_func + ' in the abi file') print('Unlock default payer account...') if password_config[default_b58_payer_address] != '': default_payer_acct = ontology.wallet_manager.get_account(default_b58_payer_address, password_config[default_b58_payer_address]) else: default_payer_acct = Invoke.unlock_account(default_b58_payer_address, wallet_manager) for function_key in invoke_function_dict: if len(all_exec_func) != 0 and function_key not in all_exec_func: continue print('Invoking {}...'.format(function_key)) abi_function = abi_info.get_function(function_key) function_information = invoke_function_dict[function_key] try: params = function_information['params'] print("params: ", params) params = Invoke.params_normalize(params) if len(abi_function.parameters) == 0: pass elif len(abi_function.parameters) == 1: abi_function.set_params_value((params,)) elif len(abi_function.parameters) == len(params): abi_function.set_params_value(tuple(params)) else: abi_function = None print('\tInvoke failed, params mismatching with the abi file') if abi_function is not None: if function_information['preExec']: tx = Invoke.generate_unsigned_invoke_transaction(contract_address, abi_function, bytearray(), gas_price, gas_limit) result = ontology.rpc.send_raw_transaction_pre_exec(tx) print('\tInvoke successful...') print('\t\t... Invoke result: {}'.format(result)) else: b58_payer_address = function_information.get('payer', default_b58_payer_address) if b58_payer_address == default_b58_payer_address: payer_acct = default_payer_acct else: if password_config[b58_payer_address] != '': payer_acct = ontology.wallet_manager.get_account(b58_payer_address, password_config[b58_payer_address]) else: payer_acct = Invoke.unlock_account(b58_payer_address, wallet_manager) tx = Invoke.generate_unsigned_invoke_transaction(contract_address, abi_function, payer_acct.get_address().to_array(), gas_price, gas_limit) ontology.add_sign_transaction(tx, payer_acct) dict_signers = function_information.get('signers', dict()) signer_list = list() if len(dict_signers) != 0: print('Unlock signers account...') for b58_signer_address in dict_signers['signer']: if b58_signer_address == b58_payer_address: pass else: if password_config[b58_signer_address] != '': signer = ontology.wallet_manager.get_account(b58_signer_address, password_config[b58_signer_address]) else: signer = Invoke.unlock_account(b58_signer_address, wallet_manager) signer_list.append(signer) if dict_signers['m'] == 1: for signer in signer_list: ontology.add_sign_transaction(tx, signer) elif dict_signers['m'] > 1: list_public_key = list() for pubkey in dict_signers['publicKeys']: list_public_key.append(bytearray.fromhex(pubkey)) for signer in signer_list: ontology.add_multi_sign_transaction(tx, dict_signers['m'], list_public_key, signer) ontology.rpc.set_address(rpc_address) try: tx_hash = ontology.rpc.send_raw_transaction(tx) if tx_hash == '': print('\tInvoke failed...') else: print('\tInvoke successful...') print('\t\t... txHash: 0x{}'.format(tx_hash)) except SDKException as e: print('\tInvoke failed, {}'.format(e.args[1].replace('Other Error, ', ''))) except (KeyError, RuntimeError) as e: print('\tInvoke failed,', e.args)
def invoke_all_function_in_list(wallet_file_name: str = '', project_dir_path: str = '', network: str = '', exec_func_str: str = '', config_name: str = '', pre_exec: str = ''): if project_dir_path == '': project_dir_path = os.getcwd() if not os.path.isdir(project_dir_path): raise PunicaException(PunicaError.dir_path_error) try: wallet_file, invoke_config, password_config = handle_invoke_config(project_dir_path, config_name) sleep_time = invoke_config.get('sleepTime', 6) except PunicaException as e: print(e.args) return ontology = OntologySdk() rpc_address = handle_network_config(project_dir_path, network) ontology.rpc.set_address(rpc_address) if wallet_file_name != '': ontology.wallet_manager = read_wallet(project_dir_path, wallet_file_name) else: ontology.wallet_manager = read_wallet(project_dir_path, wallet_file) try: abi_file_name = invoke_config['abi'] except KeyError: raise PunicaException(PunicaError.config_file_error) try: default_b58_payer_address = invoke_config['defaultPayer'] except KeyError: raise PunicaException(PunicaError.other_error("defaultPayer is null")) print('Running invocation: {}'.format(abi_file_name)) abi_dir_path = os.path.join(project_dir_path, 'contracts', 'build') dict_abi = read_abi(abi_dir_path, abi_file_name) try: hex_contract_address = dict_abi['hash'] except KeyError: raise PunicaException(PunicaError.abi_file_error) if not isinstance(hex_contract_address, str) or len(hex_contract_address) != 40: raise PunicaException(PunicaError.abi_file_error) contract = ontology.rpc.get_smart_contract(hex_contract_address) if contract == 'unknow contracts': print('Contract 0x{} hasn\'t been deployed in current network: {}'.format(hex_contract_address, network)) raise PunicaException(PunicaError.abi_file_error) contract_address = bytearray(binascii.a2b_hex(hex_contract_address)) contract_address.reverse() abi_info = Invoke.generate_abi_info(dict_abi) gas_price = invoke_config.get('gasPrice', 500) gas_limit = invoke_config.get('gasLimit', 21000000) invoke_function_list = invoke_config.get('functions', list()) invoke_function_name_list = list() for invoke_function in invoke_function_list: invoke_function_name_list.append(invoke_function['operation']) all_exec_func_list = list() if exec_func_str != '': all_exec_func_list = exec_func_str.split(',') if default_b58_payer_address != '': print('Unlock default payer account...') default_payer_acct = Invoke.get_account(ontology, password_config, default_b58_payer_address) if len(all_exec_func_list) == 0: all_exec_func_list = invoke_function_name_list for function_name in all_exec_func_list: if function_name not in invoke_function_name_list: print('there is not the function:', '\"' + function_name + '\"' + ' in the default-config file') continue print('Invoking ', function_name) abi_function = abi_info.get_function(function_name) if abi_function is None: raise PunicaException(PunicaError.other_error('\"' + function_name + '\"' + 'not found in the abi file')) function_information = None for invoke_function in invoke_function_list: if invoke_function['operation'] == function_name: function_information = invoke_function break if function_information is None: print('there is not the function: ', function_name) return try: paramList = function_information['args'] try: # params = Invoke.params_normalize(paramsList) params = Invoke.params_normalize2(paramList) params_list = Invoke.params_build(function_name, params) except PunicaException as e: print(e.args) return # if len(abi_function.parameters) == 0: # pass # elif len(abi_function.parameters) == 1: # abi_function.set_params_value(tuple(params)) # elif len(abi_function.parameters) == len(params): # abi_function.set_params_value(tuple(params)) # else: # abi_function = None # print('\tInvoke failed, params mismatching with the abi file') if abi_function is not None: if (function_information['preExec'] and pre_exec == '') or (pre_exec == 'true'): tx = Invoke.generate_unsigned_invoke_transaction(contract_address, params_list, bytearray(), gas_price, gas_limit) result = ontology.rpc.send_raw_transaction_pre_exec(tx) print('Invoke successful') if isinstance(result, list): print('Invoke result: {}'.format(result)) # print('Invoke result: {}'.format(list(map(lambda r: "0x" + r, result)))) else: if result is None: print('Invoke result: {}'.format('')) else: print('Invoke result: {}'.format(result)) else: b58_payer_address = function_information.get('payer', default_b58_payer_address) if default_b58_payer_address != '' and b58_payer_address == default_b58_payer_address: payer_acct = default_payer_acct else: payer_acct = Invoke.get_account(ontology, password_config, b58_payer_address) if payer_acct is None or payer_acct == '': print('defaultPayer is None in invokeConfig') return tx = Invoke.generate_unsigned_invoke_transaction(contract_address, params_list, payer_acct.get_address().to_bytes(), gas_price, gas_limit) ontology.add_sign_transaction(tx, payer_acct) dict_signers = function_information.get('signature', dict()) signer_list = list() if len(dict_signers) != 0: print('Unlock signers account...') for b58_signer_address in dict_signers['signers']: if b58_signer_address == b58_payer_address: signer_list.append(payer_acct) continue else: signer = Invoke.get_account(ontology, password_config, b58_signer_address) signer_list.append(signer) if dict_signers['m'] == 1: for signer in signer_list: ontology.add_sign_transaction(tx, signer) elif dict_signers['m'] > 1: list_public_key = list() for pubkey in dict_signers['publicKeys']: list_public_key.append(bytearray.fromhex(pubkey)) for signer in signer_list: ontology.add_multi_sign_transaction(tx, dict_signers['m'], list_public_key, signer) ontology.rpc.set_address(rpc_address) try: tx_hash = ontology.rpc.send_raw_transaction(tx) time.sleep(sleep_time) if tx_hash == '': print('Invoke failed...') print('txHash: 0x{}'.format(tx.hash256_explorer())) else: print('Invoke successful') print('txHash: 0x{}'.format(tx_hash)) except SDKException as e: print('txHash: 0x{}'.format(tx.hash256_explorer())) print('\tInvoke failed, {}'.format(e.args[1].replace('Other Error, ', ''))) except (KeyError, RuntimeError) as e: print('\tInvoke failed,', e.args)