def call(self, inputparams): if len(inputparams) == 0: sols = list_files(contracts_dir + "/*.sol") for sol in sols: print(sol + ".sol") return common.check_param_num(inputparams, 3) paramsname = ["contractname", "address", "func"] params = fill_params(inputparams, paramsname) contractname = params["contractname"] address = params["address"] if address == "last" or address == "latest": address = ContractNote.get_last(contractname) if address is None: sys.exit("can not get last address for [{}],break;".format( contractname)) tx_client = transaction_common.TransactionCommon( address, contracts_dir, contractname) fn_name = params["func"] fn_args = inputparams[3:] print("INFO>> client info: {}".format(tx_client.getinfo())) print("INFO >> call {} , address: {}, func: {}, args:{}".format( contractname, address, fn_name, fn_args)) try: result = tx_client.call_and_decode(fn_name, fn_args) common.print_tx_result(result) except Exception as e: common.print_error_msg("call", e)
def print_receipt_logs_and_txoutput(client, receipt, contractname, parser=None): print("INFO >> receipt logs : ") # 解析receipt里的log if parser is None and len(contractname) > 0: parser = DatatypeParser(default_abi_file(contractname)) logresult = parser.parse_event_logs(receipt["logs"]) i = 0 # print(json.dumps(logresult,indent=4)) for log in logresult: if "eventname" in log: i = i + 1 print("{}): log name: {} , data: {} , topic: {}".format( i, log["eventname"], log["eventdata"], log["topic"])) inputdetail = print_parse_transaction(receipt, "", parser) # 解析该交易在receipt里输出的output,即交易调用的方法的return值 outputresults = parser.parse_receipt_output(inputdetail["name"], receipt["output"]) common.print_tx_result(outputresults)
def main(argv): try: usagemsg = usage(client_config) cmd, inputparams = parse_commands(argv) precompile = Precompile(cmd, inputparams, contracts_dir + "/precompile") # check cmd valid = check_cmd(cmd, validcmds) if valid is False: printusage(usagemsg, precompile) return # try to callback cns precompile precompile.call_cns() # try to callback consensus precompile precompile.call_consensus() # try to callback config precompile precompile.call_sysconfig_precompile() # try to callback permission precompile precompile.call_permission_precompile() # try to callback crud precompile precompile.call_crud_precompile() # try to callback rpc functions rpcConsole = RPCConsole(cmd, inputparams, contracts_dir) rpcConsole.executeRpcCommand() def show_gm_account(name, password): account = GM_Account() keyfile = "{}/{}.json".format(client_config.account_keyfile_path, name) account.load_from_file(keyfile, password) print("load account from file: ", keyfile) print(account.getdetail()) def show_ecdsa_account(name, password): keyfile = "{}/{}.keystore".format( client_config.account_keyfile_path, name) # the account doesn't exists if os.path.exists(keyfile) is False: raise BcosException("account {} doesn't exists".format(name)) print("show account : {}, keyfile:{} ,password {} ".format( name, keyfile, password)) try: with open(keyfile, "r") as dump_f: keytext = json.load(dump_f) stat = StatTool.begin() privkey = Account.decrypt(keytext, password) stat.done() print("decrypt use time : %.3f s" % (stat.time_used)) ac2 = Account.from_key(privkey) print("address:\t", ac2.address) print("privkey:\t", encode_hex(ac2.key)) print("pubkey :\t", ac2.publickey) print("\naccount store in file: [{}]".format(keyfile)) print("\n**** please remember your password !!! *****") except Exception as e: raise BcosException(("load account info for [{}] failed," " error info: {}!").format(name, e)) if cmd == "showaccount": # must be 2 params common.check_param_num(inputparams, 2, True) name = inputparams[0] password = inputparams[1] if client_config.crypto_type == CRYPTO_TYPE_GM: show_gm_account(name, password) else: show_ecdsa_account(name, password) def create_gm_account(name, password, forcewrite): keyfile = "{}/{}.json".format(client_config.account_keyfile_path, name) if not os.path.exists(keyfile): # 如果默认文件不存在,直接写 forcewrite = True else: forcewrite = common.backup_file(keyfile) # 如果备份失败,不要覆盖写 account = GM_Account() account.create() if forcewrite: account.save_to_file(keyfile, password) print("account created:") print(account.getdetail()) if forcewrite: print("account save to :", keyfile) def create_ecdsa_account(name, password, forcewrite): ac = Account.create(password) print("new address :\t", ac.address) print("new privkey :\t", encode_hex(ac.key)) print("new pubkey :\t", ac.publickey) stat = StatTool.begin() kf = Account.encrypt(ac.privateKey, password) stat.done() print("encrypt use time : %.3f s" % (stat.time_used)) keyfile = "{}/{}.keystore".format( client_config.account_keyfile_path, name) print("save to file : [{}]".format(keyfile)) forcewrite = False if not os.access(keyfile, os.F_OK): # 默认的账号文件不存在,就强行存一个 forcewrite = True else: # old file exist,move to backup file first if len(inputparams) == 3 and inputparams[2] == "save": forcewrite = True else: forcewrite = common.backup_file( keyfile) # 如果备份文件不成功,就不要覆盖写了 if forcewrite: with open(keyfile, "w") as dump_f: json.dump(kf, dump_f) dump_f.close() print(">>-------------------------------------------------------") print( "INFO >> read [{}] again after new account,address & keys in file:" .format(keyfile)) with open(keyfile, "r") as dump_f: keytext = json.load(dump_f) stat = StatTool.begin() privkey = Account.decrypt(keytext, password) stat.done() print("decrypt use time : %.3f s" % (stat.time_used)) ac2 = Account.from_key(privkey) print("address:\t", ac2.address) print("privkey:\t", encode_hex(ac2.key)) print("pubkey :\t", ac2.publickey) print("\naccount store in file: [{}]".format(keyfile)) print("\n**** please remember your password !!! *****") dump_f.close() if cmd == "newaccount": common.check_param_num(inputparams, 2, False) name = inputparams[0] max_account_len = 240 if len(name) > max_account_len: common.print_info( "WARNING", "account name should no more than {}".format( max_account_len), ) sys.exit(1) password = inputparams[1] forcewrite = False if len(inputparams) == 3 and inputparams[2] == "save": forcewrite = True print("starting : {} {} , if save:{}".format( name, password, forcewrite)) if client_config.crypto_type == CRYPTO_TYPE_GM: create_gm_account(name, password, forcewrite) else: create_ecdsa_account(name, password, forcewrite) if cmd == "deploylast": contracts = ContractNote.get_last_contracts() for name in contracts: print("{} -> {}".format(name, contracts[name])) if cmd == "deploylog": historys = ContractNote.get_history_list() for address in historys: print("{} -> {} ".format(address, historys[address])) # -------------------------------------------------------------------------------------------- # console cmd entity # -------------------------------------------------------------------------------------------- if cmd == "deploy": """deploy abi bin file""" # must be at least 2 params common.check_param_num(inputparams, 1) contractname = inputparams[0].strip() gasPrice = 30000000 # need save address whether or not needSaveAddress = False args_len = len(inputparams) if inputparams[-1] == "save": needSaveAddress = True args_len = len(inputparams) - 1 # get the args fn_args = inputparams[1:args_len] tx_client = transaction_common.TransactionCommon( "", contracts_dir, contractname) result = tx_client.send_transaction_getReceipt( None, fn_args, gasPrice, True)[0] print("INFO >> client info: {}".format(tx_client.getinfo())) print("deploy result for [{}] is:\n {}".format( contractname, json.dumps(result, indent=4))) name = contractname address = result["contractAddress"] blocknum = int(result["blockNumber"], 16) txhash = result["transactionHash"] ContractNote.save_contract_address(name, address) print("on block : {},address: {} ".format(blocknum, address)) if needSaveAddress is True: ContractNote.save_address_to_contract_note(name, address) print("address save to file: ", client_config.contract_info_file) else: print("""\nNOTE : if want to save new address as last address for (call/sendtx)\nadd 'save' to cmdline and run again""" ) ContractNote.save_history(name, address, blocknum, txhash) # -------------------------------------------------------------------------------------------- # console cmd entity # -------------------------------------------------------------------------------------------- if cmd == "call" or cmd == "sendtx": common.check_param_num(inputparams, 3) paramsname = ["contractname", "address", "func"] params = fill_params(inputparams, paramsname) contractname = params["contractname"] address = params["address"] if address == "last": address = ContractNote.get_last(contractname) if address is None: sys.exit("can not get last address for [{}],break;".format( contractname)) tx_client = transaction_common.TransactionCommon( address, contracts_dir, contractname) fn_name = params["func"] fn_args = inputparams[3:] print("INFO>> client info: {}".format(tx_client.getinfo())) print("INFO >> {} {} , address: {}, func: {}, args:{}".format( cmd, contractname, address, fn_name, fn_args)) if cmd == "call": result = tx_client.call_and_decode(fn_name, fn_args) print("INFO >> {} result:".format(cmd)) common.print_tx_result(result) if cmd == "sendtx": receipt = tx_client.send_transaction_getReceipt( fn_name, fn_args)[0] data_parser = DatatypeParser(default_abi_file(contractname)) print("\n\nINFO >> from address: {} ".format( tx_client.keypair.address)) # 解析receipt里的log 和 相关的tx ,output print_receipt_logs_and_txoutput(tx_client, receipt, "", data_parser) # -------------------------------------------------------------------------------------------- # console cmd entity # -------------------------------------------------------------------------------------------- if cmd == "list": RPCConsole.print_rpc_usage() print( "--------------------------------------------------------------------" ) # -------------------------------------------------------------------------------------------- # console cmd entity # -------------------------------------------------------------------------------------------- if cmd == "txinput": contractname = inputparams[0] inputdata = inputparams[1] abi_path = default_abi_file(contractname) if os.path.isfile(abi_path) is False: raise BcosException( "execute {} failed for {} doesn't exist".format( cmd, abi_path)) try: dataParser = DatatypeParser(abi_path) # print(dataParser.func_abi_map_by_selector) result = dataParser.parse_transaction_input(inputdata) print("\nabifile : ", default_abi_file(contractname)) print("parse result: {}".format(result)) except Exception as e: raise BcosException("execute {} failed for reason: {}".format( cmd, e)) # -------------------------------------------------------------------------------------------- # console cmd entity # -------------------------------------------------------------------------------------------- if cmd == "checkaddr": address = inputparams[0] result = to_checksum_address(address) print("{} -->\n{}".format(address, result)) # -------------------------------------------------------------------------------------------- # console cmd entity # -------------------------------------------------------------------------------------------- if cmd == "usage": printusage(usagemsg, precompile) except TransactionException as e: common.print_error_msg(cmd, e) except PrecompileError as e: common.print_error_msg(cmd, e) except BcosError as e: common.print_error_msg(cmd, e) except CompileError as e: common.print_error_msg(cmd, e) except ArgumentsError as e: common.print_error_msg(cmd, e) except BcosException as e: common.print_error_msg(cmd, e) except ValueError as e: common.print_error_msg(cmd, e) except InsufficientDataBytes as e: common.print_error_msg(cmd, e) except Exception as e: print("exception happened!") import traceback print(traceback.format_exc()) exit(-1)