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))
Example #2
0
 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))
Example #3
0
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))
Example #4
0
    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))
Example #5
0
    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))
Example #6
0
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))
Example #7
0
 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)
Example #8
0
    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))
Example #10
0
    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)
Example #11
0
 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))
Example #12
0
 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))
Example #13
0
 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))
Example #14
0
 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))
Example #15
0
    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)
        '''
Example #16
0
    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))
Example #17
0
 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))
Example #18
0
    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
Example #19
0
 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
Example #20
0
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
Example #22
0
 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))
Example #23
0
    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)
Example #25
0
 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))
Example #26
0
    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)
Example #28
0
    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)