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))
def show_ecdsa_account(self, name, password): keyfile = "{}/{}".format(client_config.account_keyfile_path, name) if os.path.exists(keyfile) is False: keyfile = "{}/{}.keystore".format( client_config.account_keyfile_path, name) if os.path.exists(keyfile) is True and password is None: raise BcosException( "When loading an account file in keystore format, a password must be provided" ) # the keystore doesn't exists,try pem if os.path.exists(keyfile) is False: keyfile = "{}/{}.pem".format(client_config.account_keyfile_path, name) print("keyfile", keyfile) if os.path.exists(keyfile) is False: raise BcosException("account {} doesn't exists in path:{}".format( name, client_config.account_keyfile_path)) # go to load from file print("show account : {}, keyname:{} ,password {} ".format( name, keyfile, password)) try: stat = StatTool.begin() ac = Signer_ECDSA.load_from_keyfile(keyfile, password) stat.done() print("decrypt use time : %.3f s" % (stat.time_used)) print("address:\t", ac.address) print("privkey:\t", encode_hex(ac.key)) print("pubkey :\t", ac.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))
def print_output_and_input(logs, output, txinput, contract_name, contract_path): """ parse_output_from_abi """ abi_path = os.path.join(contract_path, contract_name + ".abi") if os.path.isfile(abi_path) is False: raise BcosException("parse outpt failed for {} doesn't exist" .format(abi_path)) try: dataParser = DatatypeParser(abi_path) # parse txinput input_result = dataParser.parse_transaction_input(txinput) if input_result is not None: print_info("txinput result", input_result) # get function name fn_name = input_result["name"] output_result = dataParser.parse_receipt_output(fn_name, output) if output_result is None: print_info("INFO", "empty return, output: {}".format(output)) return print_info("output result", output_result) log_result = dataParser.parse_event_logs(logs) print_receipt_logs(log_result) # print_info("log result", log_result) except Exception as e: raise BcosException("parse output failed for reason: {}".format(e))
def init(self): try: self.blockLimit = 500 # check chainID common.check_int_range(client_config.groupid, BcosClient.max_group_id) # check group id common.check_int_range(client_config.fiscoChainId, BcosClient.max_chain_id) # check protocol if client_config.client_protocol.lower( ) not in BcosClient.protocol_list: raise BcosException( "invalid configuration, must be: {}".format(''.join( BcosClient.protocol_list))) # check account keyfile self.keystore_file = "{}/{}".format( client_config.account_keyfile_path, client_config.account_keyfile) if os.path.exists(self.keystore_file) is False: raise BcosException( ("keystore file {} doesn't exist, " "please check client_config.py again " "and make sure this account exist").format( self.keystore_file)) self.fiscoChainId = client_config.fiscoChainId self.groupid = client_config.groupid if client_config.client_protocol == client_config.PROTOCOL_RPC \ and client_config.remote_rpcurl is not None: self.rpc = utils.rpc.HTTPProvider(client_config.remote_rpcurl) self.rpc.logger = self.logger if client_config.client_protocol == client_config.PROTOCOL_CHANNEL: if os.path.exists(client_config.channel_node_cert) is False: raise BcosException("{} not found!".format( client_config.channel_node_cert)) if os.path.exists(client_config.channel_node_key) is False: raise BcosException("{} not found!".format( client_config.channel_node_key)) self.channel_handler = ChannelHandler() self.channel_handler.logger = self.logger self.channel_handler.initTLSContext( client_config.channel_ca, client_config.channel_node_cert, client_config.channel_node_key) self.channel_handler.start_channel(client_config.channel_host, client_config.channel_port) blockNumber = self.getBlockNumber() self.channel_handler.setBlockNumber(blockNumber) self.channel_handler.getBlockNumber(self.groupid) self.logger.info("using protocol " + client_config.client_protocol) return self.getinfo() except Exception as e: raise BcosException("init bcosclient failed, reason: {}".format(e))
def load_default_account(self): if client_config.crypto_type == CRYPTO_TYPE_GM: # 加载国密账号 if self.gm_account is not None: return # 不需要重复加载 try: self.gm_account = GM_Account() self.gm_account_file = "{}/{}".format( client_config.account_keyfile_path, client_config.gm_account_keyfile) if os.path.exists(self.gm_account_file) is False: raise BcosException( ("gm account keyfile file {} doesn't exist, " "please check client_config.py again " "and make sure this account exist").format( self.gm_account_file)) self.gm_account.load_from_file( self.gm_account_file, client_config.gm_account_password) self.keypair = self.gm_account.keypair return except Exception as e: raise BcosException( "load gm account from {} failed, reason: {}".format( self.gm_account_file, e)) # 默认的 ecdsa 账号 try: if self.ecdsa_account is not None: return # 不需要重复加载 # check account keyfile self.keystore_file = "{}/{}".format( client_config.account_keyfile_path, client_config.account_keyfile) if os.path.exists(self.keystore_file) is False: raise BcosException( ("keystore file {} doesn't exist, " "please check client_config.py again " "and make sure this account exist").format( self.keystore_file)) with open(self.keystore_file, "r") as dump_f: keytext = json.load(dump_f) privkey = Account.decrypt(keytext, client_config.account_password) self.ecdsa_account = Account.from_key(privkey) keypair = BcosKeyPair() keypair.private_key = self.ecdsa_account.privateKey keypair.public_key = self.ecdsa_account.publickey keypair.address = self.ecdsa_account.address self.keypair = keypair except Exception as e: raise BcosException( "load account from {} failed, reason: {}".format( self.keystore_file, e))
def parse_input(txinput, contract_name, contract_path): """ parse txinput """ abi_path = os.path.join(contract_path, contract_name + ".abi") if os.path.isfile(abi_path) is False: raise BcosException( "parse txinput failed for {} doesn't exist".format(abi_path)) try: dataParser = DatatypeParser(abi_path) result = dataParser.parse_transaction_input(txinput) return result except Exception as e: raise BcosException("parse txinput failed for reason: {}".format(e))
def __init__(self, contract_addr, contract_path, contract_name): """ init client to send transactions """ bcosclient.BcosClient.__init__(self) self.contract_addr = contract_addr self.contract_path = contract_path (fname, extname) = os.path.splitext(contract_name) if extname.endswith("wasm"): # deal with wasm , not compile in this version, todo list self.contract_abi_path = contract_path + "/" + fname + ".abi" self.contract_bin_path = contract_path + "/" + contract_name self.sol_path = contract_path + "/" + contract_name else: # deal with sol files ,may be force re compile sol file ,so set the sol filename self.contract_abi_path = contract_path + "/" + contract_name + ".abi" self.contract_bin_path = contract_path + "/" + contract_name + ".bin" self.sol_path = contract_path + "/" + contract_name + ".sol" if os.path.exists(self.sol_path) is False: raise BcosException(("contract {} not exists," " please put {}.sol into {}").format( contract_name, contract_name, contract_path)) print("contract_abi_path {}, contract_bin_path {}".format( self.contract_abi_path, self.contract_bin_path)) self.dataparser = None if os.path.exists(self.contract_bin_path): self.dataparser = DatatypeParser(self.contract_abi_path)
def format_abi_args(self, fn_name: str, fn_args, needCover=False): """ format args """ if not self.contract_bin_path.endswith(".wasm"): self.gen_contract_abi(needCover) data_parser = DatatypeParser(self.contract_abi_path) contract_abi = data_parser.contract_abi self.dataparser = data_parser args = None if fn_args is None: return (contract_abi, fn_args) if fn_name in data_parser.func_abi_map_by_name.keys() is None: raise BcosException( "invalid function: {}, the right function list:".format( fn_name, ''.join(data_parser.func_abi_map_by_name.keys()))) if fn_name is not None: fn_abi = data_parser.func_abi_map_by_name[fn_name] inputabi = data_parser.get_function_inputs_abi(fn_name) #inputabi = data_parser.get_function_abi(fn_name) args = format_args_by_function_abi(fn_args, inputabi) #print("args after format:",args) # the constructor with params elif fn_args is not None and contract_abi is not None: abidata = get_constructor_abi(contract_abi) if abidata is not None: inputabi = abidata["inputs"] args = format_args_by_function_abi(fn_args, inputabi) return (contract_abi, args)
def common_request(self, cmd, params, packet_type=ChannelPack.TYPE_RPC): response = None try: next(self.request_counter) stat = StatTool.begin() if client_config.client_protocol == client_config.PROTOCOL_RPC: response = self.rpc.make_request(cmd, params) if client_config.client_protocol == client_config.PROTOCOL_CHANNEL: response = self.channel_handler.make_channel_rpc_request( cmd, params, ChannelPack.TYPE_RPC, packet_type) self.is_error_response(response) memo = "DONE" stat.done() stat.debug("commonrequest:{}:{}".format(cmd, memo)) return response["result"] except Exception as e: # timeout exception exception_str = str(e).lower() if "timeout" in exception_str: raise BcosException( ("{} timeout for without response after 60s, " "please check the status of the node").format(cmd)) else: raise BcosError(-1, None, ( "{} failed," " params: {}, response: {}, error information: {}").format( cmd, params, json.dumps(response), e))
def sign_transaction_hash(self, transaction_hash, chain_id): hashbyte = bytes(transaction_hash) if self.crypto_type == CRYPTO_TYPE_GM: # gm sign public_key = self.gm_account.keypair.public_key private_key = self.gm_account.keypair.private_key sm2_crypt = sm2.CryptSM2(public_key=public_key, private_key=private_key) public_key = self.gm_account.keypair.public_key private_key = self.gm_account.keypair.private_key (r, s) = sm2_crypt.sign(hashbyte) v_raw = public_key v = int(v_raw, 16) elif self.crypto_type == CRYPTO_TYPE_ECDSA: # ecdsa sign signature = self.ecdsa_account._key_obj.sign_msg_hash( transaction_hash) (v_raw, r, s) = signature.vrs v = self.to_eth_v(v_raw, chain_id) else: raise BcosException( "when sign transaction, unknown crypto type {}".format( self.crypto_type)) return (v, r, s)
def check_nodeExist(client, nodeId): """ check node num """ nodeList = list(client.getNodeIDList()) if nodeId not in nodeList: raise BcosException(("remove non-exist node, " "currentNodeList: {}").format(nodeList))
def check_sealer(client, nodeId): """ check sealer """ sealerList = list(client.getSealerList()) nodeNum = len(sealerList) if nodeNum == 1 and nodeId in sealerList: raise BcosException("forbid remove the last node {}".format(nodeId))
def load_default_account(self): try: with open(self.keystore_file, "r") as dump_f: keytext = json.load(dump_f) privkey = Account.decrypt(keytext, client_config.account_password) self.client_account = Account.from_key(privkey) except Exception as e: raise BcosException("load account from {} failed, reason: {}" .format(self.keystore_file, e))
def txinput(self, inputparams): # [contractname] [inputdata(in hex string) 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( contractname, 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( contractname, e))
def sign_transaction_hash(self, transaction_hash, chain_id): if not isinstance(self.signer, Signer_Impl): raise BcosException( "Transaction Signer must by Signer_Imple(GM/ECDSA)type") (v, r, s) = self.signer.sign(transaction_hash, chain_id) return (v, r, s) '''
def from_key_file(the_key_file, password): try: gm_account = GM_Account() if os.path.exists(the_key_file) is False: raise BcosException( ("gm account keyfile file {} doesn't exist, " "please check client_config.py again " "and make sure this account exist").format(the_key_file)) gm_account.load_from_file(the_key_file, password) signer = Signer_GM(gm_account) return signer except Exception as e: raise BcosException( "load gm account from {} failed, reason: {}".format( the_key_file, e))
def check_nodeList(client, nodeId): """ check node list """ nodeList = list(client.getNodeIDList()) if nodeId not in nodeList: raise BcosException(("node {} is not in nodeList: {}, " "please check the existence of " "the node").format(nodeId, nodeList))
def from_key_file(the_key_file, password): # print("load from ",the_key_file) if os.path.exists(the_key_file) is False: raise BcosException( ("key file {} doesn't exist, " "please check client_config.py again " "and make sure this account exist").format(the_key_file)) account = Signer_ECDSA.load_from_keyfile(the_key_file, password) signer = Signer_ECDSA(account) return signer
def send_transaction_getReceipt(self, fn_name, fn_args, gasPrice=30000000, deploy=False): """ send transactions to CNS contract with the givn function name and args """ try: contract_abi, args = self.format_args(fn_name, fn_args, deploy) contract_bin = None if deploy is True and os.path.exists( self.contract_bin_path) is True: with open(self.contract_bin_path) as f: contract_bin = f.read() if contract_bin is not None and len(contract_bin) > 0x40000: raise BcosException( ("contract bin size overflow," " limit: 0x40000(256K), size: {})").format( len(contract_bin), 16)) receipt = super().sendRawTransactionGetReceipt( self.contract_addr, contract_abi, fn_name, args, contract_bin, gasPrice) # check status if "status" not in receipt.keys() or \ "output" not in receipt.keys(): raise BcosError(-1, None, ("send transaction failed" "for empty status and output," "transaction receipt:{}").format(receipt)) status = receipt["status"] if int(status, 16) != 0 or receipt["output"] is None: raise TransactionException( receipt, ("send transaction failed," "status: {}, gasUsed: {}," " (not enough gas?)" " (non-exist contract address?)").format( status, receipt["gasUsed"])) if fn_name is not None and fn_args is not None: output = common.parse_output(receipt["output"], fn_name, contract_abi, args) else: output = None return (receipt, output) except BcosError as e: self.logger.error( "send transaction failed, fn_name: {}, fn_args:{}, error_info:{}" .format(fn_name, fn_args, e)) raise e except CompileError as e: self.logger.error( ("send transaction failed for compile soldity failed," "contract_path {}, error_info:{}").format(self.sol_path, e)) raise e
def check_hash(hash_str): """ check hash """ min_size = 64 max_size = 66 if len(hash_str) < min_size or \ hash_str.startswith("0x") and len(hash_str) < max_size \ or len(hash_str) > max_size: raise BcosException(("invalid hash: {}," "expected len: {} or {}, real len: {}").format( min_size, max_size, hash_str, len(hash_str))) check_word(hash_str)
def call(self, to_address, contract_abi, fn_name, args=None): cmd = "call" if to_address != "": common.check_and_format_address(to_address) self.load_default_account() functiondata = encode_transaction_data(fn_name, contract_abi, None, args) callmap = dict() callmap["data"] = functiondata callmap["from"] = self.default_from_account_signer.get_keypair( ).address callmap["to"] = to_address callmap["value"] = 0 # send transaction to the given group params = [client_config.groupid, callmap] # 发送 response = self.common_request(cmd, params) #print("response : ",response) # check status if "status" in response.keys(): status = int(response["status"], 16) error_message = transaction_status_code.TransactionStatusCode.get_error_message( status) if error_message is not None: raise BcosException( "call error, error message: {}".format(error_message)) if "output" in response.keys(): outputdata = response["output"] # 取得方法的abi,签名,参数 和返回类型,进行call返回值的解析 fn_abi, fn_selector, fn_arguments = get_function_info( fn_name, contract_abi, None, args, None, ) # print("fn_selector",fn_selector) # print("fn_arguments",fn_arguments) #fn_output_types = get_fn_abi_types_single(fn_abi, "outputs") fn_output_types = get_abi_output_types(fn_abi) try: #decoderesult = decode_single(fn_output_types, decode_hex(outputdata)) #print("fn_output_types",fn_output_types) decoderesult = decode_abi(fn_output_types, decode_hex(outputdata)) return decoderesult except BaseException as e: return response return response
def set_account_by_keystorefile(self, account_keyfile): try: self.keystore_file = "{}/{}".format( client_config.account_keyfile_path, account_keyfile) if os.path.exists(self.keystore_file) is False: raise BcosException( ("keystore file {} doesn't exist, " "please check client_config.py again " "and make sure this account exist").format( self.keystore_file)) with open(self.keystore_file, "r") as dump_f: keytext = json.load(dump_f) privkey = keytext["privateKey"] self.ecdsa_account = Account.from_key(privkey) keypair = BcosKeyPair() keypair.private_key = self.ecdsa_account.privateKey keypair.public_key = self.ecdsa_account.publickey keypair.address = self.ecdsa_account.address self.keypair = keypair except Exception as e: raise BcosException( "load account from {} failed, reason: {}".format( self.keystore_file, e))
def load_default_account(self): try: self.client_account = Account.from_key( 0xfb06406e4bd0f81ade6bd7da2015f634d52651e0e2dac8caeca1a8044b17ec48 ) # with open(self.keystore_file, "r") as dump_f: # keytext = json.load(dump_f) # privkey = Account.decrypt(keytext, client_config.account_password) # self.client_account = Account.from_key(privkey) except Exception as e: raise BcosException( "load account from {} failed, reason: {}".format( self.keystore_file, e))
def format_args(self, fn_name, fn_args, needCover=False): """ format args """ self.gen_contract_abi(needCover) data_parser = DatatypeParser(self.contract_abi_path) contract_abi = data_parser.contract_abi if fn_args is None: return (contract_abi, fn_args) if fn_name in data_parser.func_abi_map_by_name.keys() is None: raise BcosException( "invalid function: {}, the right function list:".format( fn_name, ''.join(data_parser.func_abi_map_by_name.keys()))) inputabi = data_parser.func_abi_map_by_name[fn_name]["inputs"] args = TransactionCommon.format_args_by_abi(fn_args, inputabi) return (contract_abi, args)
def __init__(self, contract_addr, contract_path, contract_name): """ init client to send transactions """ bcosclient.BcosClient.__init__(self) self.contract_addr = contract_addr self.contract_path = contract_path self.contract_abi_path = contract_path + "/" + contract_name + ".abi" self.contract_bin_path = contract_path + "/" + contract_name + ".bin" self.sol_path = contract_path + "/" + contract_name + ".sol" if os.path.exists(self.sol_path) is False: raise BcosException( ("contract {} not exists," " please put {}.sol into {}").format(contract_name, contract_name, contract_path))
def format_args_by_abi(inputparams, inputabi): try: paramformatted = [] index = -1 if len(inputparams) != len(inputabi): raise ArgumentsError( ("Invalid Arguments {}, expected params size: {}," " inputted params size: {}".format( inputparams, len(inputabi), len(inputparams)))) for input_item in inputabi: index += 1 param = inputparams[index] if param is None: continue if isinstance(param, Iterable) is False: paramformatted.append(param) continue if '\'' in param: param = param.replace('\'', "") if "int" in input_item["type"] or "int256" in input_item[ "type"]: print("&&&&&&", input_item["type"]) paramformatted.append(int(param, 10)) # paramformatted.append(param) continue if "address" in input_item["type"]: try: paramformatted.append(to_checksum_address(param)) except ArgumentsError as e: raise ArgumentsError(( "ERROR >> covert {} to to_checksum_address failed," " exception: {}").format(param, e)) continue if "bytes" in input_item["type"]: try: paramformatted.append(bytes(param, "utf-8")) except Exception as e: raise ArgumentsError( "ERROR >> parse {} to bytes failed, error info: {}" .format(param, e)) continue paramformatted.append(param) return paramformatted except Exception as e: raise BcosException(("inputparams illegal params: {}," "error info: {}").format(inputparams, e))
def register_cns(self, name, version, address, abi): """ register cns contract: (name, version)->address precompile api: insert(string,string,string,string) """ common.check_and_format_address(address) version = re.sub(r"\s+", "", version) common.print_info("INFO", "CNS version (strip space): {}".format(version)) # invalid version if len(version) > self._max_version_len: error_info = self.get_error_msg(self._version_exceeds) self.logger.error("register cns failed, error info: {}".format(error_info)) raise BcosException(error_info) # call insert function of CNS # function definition: insert(string,string,string,string) fn_name = "insert" fn_args = [name, version, address, json.dumps(abi)] return self.client.send_transaction_getReceipt(fn_name, fn_args, self.gasPrice)
def send_transaction_getReceipt(self, fn_name, fn_args, gasPrice=30000000, isdeploy=False, from_account_signer=None): """ send transactions to CNS contract with the givn function name and args """ try: contract_abi, args = self.format_abi_args(fn_name, fn_args, isdeploy) contract_bin = None if isdeploy is True and os.path.exists( self.contract_bin_path) is True: with open(self.contract_bin_path, "rb") as f: contract_bin = f.read() f.close() # print(contract_bin) if self.contract_bin_path.endswith("wasm"): contract_bin = encode_hex(contract_bin) else: contract_bin = bytes.decode(contract_bin, "utf-8") if contract_bin is not None and len(contract_bin) > 0x40000: raise BcosException( ("contract bin size overflow," " limit: 0x40000(256K), size: {})").format( len(contract_bin), 16)) receipt = super().sendRawTransactionGetReceipt( self.contract_addr, contract_abi, fn_name, args, contract_bin, gasPrice, from_account_signer=from_account_signer) # check status if "status" not in receipt.keys() or \ "output" not in receipt.keys(): raise BcosError(-1, None, ("send transaction failed" "for empty status and output," "transaction receipt:{}").format(receipt)) status = receipt["status"] status_code = int(status, 16) error_message = transaction_status_code.TransactionStatusCode.get_error_message( status_code) if error_message is not None: raise BcosException( "call error, error message: {}".format(error_message)) if receipt["output"] is None: raise TransactionException(receipt, ("send transaction failed," "status: {}, gasUsed: {}").format( status, receipt["gasUsed"])) if fn_name is not None and fn_args is not None and self.dataparser is not None: output = self.dataparser.parse_receipt_output( fn_name, receipt["output"]) else: output = None return (receipt, output) except BcosError as e: self.logger.error( "send transaction failed, fn_name: {}, fn_args:{}, error_info:{}" .format(fn_name, fn_args, e)) raise e except CompileError as e: self.logger.error( ("send transaction failed for compile soldity failed," "contract_path {}, error_info:{}").format(self.sol_path, e)) raise e
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() if cmd == 'showaccount': # must be 2 params common.check_param_num(inputparams, 2, True) name = inputparams[0] password = inputparams[1] 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 == 'newaccount': common.check_param_num(inputparams, 2, True) 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] print("starting : {} {} ".format(name, password)) 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() # -------------------------------------------------------------------------------------------- # 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] trans_client = transaction_common.TransactionCommon( "", contracts_dir, contractname) result = trans_client.send_transaction_getReceipt( None, fn_args, gasPrice, True)[0] print("deploy result for [{}] is:\n {}".format( contractname, json.dumps(result, indent=4))) name = contractname address = result['contractAddress'] blocknum = int(result["blockNumber"], 16) ContractNote.save_contract_address(name, address) print("on block : {},address: {} ".format(blocknum, address)) if needSaveAddress is True: ContractNote.save_address(name, address, blocknum) 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''' ) # -------------------------------------------------------------------------------------------- # 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 >> {} {} , 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, result)) if cmd == "sendtx": receipt = tx_client.send_transaction_getReceipt( fn_name, fn_args)[0] data_parser = DatatypeParser(default_abi_file(contractname)) # 解析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)