Exemple #1
0
    def worker_lookup_validation(self, params):
        """
        Validate params dictionary for existence of
        fields and mandatory fields

        Parameters:
        params    Parameter dictionary to validate

        Returns:
        True and empty string on success and
        False and string with error message on failure.
        """
        if len(params) == 0:
            return False, "Empty params in the request"

        key_list = []
        for key in params.keys():
            if key not in self.__lookup_param_key_map.keys():
                return False, "Invalid parameter {}".format(key)
            else:
                key_list.append(key)

        if "workerType" in params.keys() and \
                type(params["workerType"]) != int:
            return False, "Invalid data format for workerType"

        if "organizationId" in params.keys() and \
                not is_valid_hex_str(params["organizationId"]):
            return False, "Invalid data format for organizationId"

        if "applicationTypeId" in params.keys() and \
                not is_valid_hex_str(params["applicationTypeId"]):
            return False, "Invalid data format for applicationTypeId"

        return True, ""
    def registry_update(self, org_id, uri, sc_addr, app_type_ids):
        if (self.__contract_instance is not None):
            if (is_valid_hex_str(binascii.hexlify(org_id).decode("utf8"))
                    is False):
                logging.error("Invalid Org id {}".format(org_id))
                return construct_message("failed", "Invalid Org id")
            if (sc_addr is not None and is_valid_hex_str(
                    binascii.hexlify(sc_addr).decode("utf8")) is False):
                logging.error(
                    "Invalid smart contract address {}".format(sc_addr))
                return construct_message(
                    "failed", "Invalid smart contract address")
            if (not uri):
                logging.error("Empty uri {}".format(uri))
                return construct_message("failed", "Empty uri")
            for aid in app_type_ids:
                if (is_valid_hex_str(binascii.hexlify(aid).decode("utf8"))
                        is False):
                    logging.error("Invalid application id {}".format(aid))
                    return construct_message(
                        "failed", "Invalid application id")

            txn_hash = self.__contract_instance.functions.registryUpdate(
                org_id, uri, sc_addr,
                app_type_ids).buildTransaction(
                    self.__eth_client.get_transaction_params()
            )
            tx = self.__eth_client.execute_transaction(txn_hash)
            return tx
        else:
            logging.error(
                "direct registry contract instance is not initialized")
            return construct_message(
                "failed",
                "direct registry contract instance is not initialized")
Exemple #3
0
 def worker_lookup(self, worker_type, org_id, application_id):
     """
     Lookup a worker identified worker_type, org_id and application_id
     all fields are optional and if present condition should match for all
     fields. If none passed it should return all workers.
     """
     if (self.__contract_instance is not None):
         if not isinstance(worker_type, WorkerType):
             logging.info("Invalid workerType {}".format(worker_type))
             return construct_message(
                 "failed", "Invalid workerType {}".format(worker_type))
         if not is_valid_hex_str(binascii.hexlify(org_id).decode("utf8")):
             logging.info("Invalid organization id {}".format(org_id))
             return construct_message(
                 "failed", "Invalid organization id {}".format(org_id))
         if not is_valid_hex_str(
                 binascii.hexlify(application_id).decode("utf8")):
             logging.info(
                 "Invalid application id {}".format(application_id))
             return construct_message(
                 "failed",
                 "Invalid application id {}".format(application_id))
         lookupResult = self.__contract_instance.functions.workerLookUp(
             worker_type.value, org_id, application_id).call()
         return lookupResult
     else:
         logging.error(
             "worker registry contract instance is not initialized")
         return construct_message(
             "failed",
             "worker registry contract instance is not initialized")
Exemple #4
0
    def work_order_receipt_update_retrieve(self,
                                           work_order_id,
                                           updater_id,
                                           update_index,
                                           id=None):
        """
        Retrieving a Work Order Receipt Update
        """
        if work_order_id is None or not is_valid_hex_str(work_order_id):
            logging.error("Work order id is empty or Invalid")
            return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER,
                                        "Worker id is empty or Invalid")

        if updater_id is None or not is_valid_hex_str(updater_id):
            logging.error("Updater id is empty or Invalid")
            return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER,
                                        "Worker id is empty or Invalid")

        json_rpc_request = {
            "jsonrpc": "2.0",
            "method": "WorkOrderReceiptUpdateRetrieve",
            "id": id,
            "params": {
                "workOrderId": work_order_id,
                "updaterId": updater_id,
                "updateIndex": update_index
            }
        }
        response = self.__uri_client._postmsg(json.dumps(json_rpc_request))
        return response
Exemple #5
0
 def worker_lookup_next(self, worker_type, org_id, application_id,
                        lookup_tag):
     if (self.__contract_instance is not None):
         if not isinstance(worker_type, WorkerType):
             logging.info("Invalid workerType {}".format(worker_type))
             return construct_message(
                 "failed", "Invalid workerType {}".format(worker_type))
         if not is_valid_hex_str(binascii.hexlify(org_id).decode("utf")):
             logging.info("Invalid organization id {}".format(org_id))
             return construct_message(
                 "failed", "Invalid organization id {}".format(org_id))
         if not is_valid_hex_str(
                 binascii.hexlify(application_id).decode("utf8")):
             logging.info("Invalid application id {}".format(org_id))
             return construct_message(
                 "failed", "Invalid application id {}".format(org_id))
         lookupResult = self.__contract_instance.functions.workerLookUpNext(
             worker_type.value, org_id, application_id, lookup_tag).call()
         return lookupResult
     else:
         logging.error(
             "worker registry contract instance is not initialized")
         return construct_message(
             "failed", "worker registry contract instance \
             is not initialized")
    def registry_add(self, org_id, uri, sc_addr, app_type_ids):
        if (self.__contract_instance is not None):
            if (is_valid_hex_str(binascii.hexlify(org_id).decode("utf8"))
                    is False):
                logging.info("Invalid Org id {}".format(org_id))
                return construct_message("failed", "Invalid Org id")
            if (sc_addr is not None and is_valid_hex_str(
                    binascii.hexlify(sc_addr).decode("utf8")) is False):
                logging.info("Invalid smart contract address {}")
                return construct_message("failed", "Invalid smart contract address")
            if (not uri):
                logging.info("Empty uri {}".format(uri))
                return construct_message("failed", "Empty uri")
            for aid in app_type_ids:
                if (is_valid_hex_str(binascii.hexlify(aid).decode("utf8"))
                        is False):
                    logging.info("Invalid application id {}".format(aid))
                    return construct_message("failed", "Invalid application id")

            txn_hash = self.__contract_instance.functions.registryAdd(org_id, uri, org_id,
            app_type_ids).buildTransaction(
                {
                    "chainId": self.__eth_client.get_channel_id(),
                    "gas": self.__eth_client.get_gas_limit(),
                    "gasPrice": self.__eth_client.get_gas_price(),
                    "nonce": self.__eth_client.get_txn_nonce()
                })
            tx = self.__eth_client.execute_transaction(txn_hash)
            return tx
        else:
            logging.error("direct registry contract instance is not initialized")
            return construct_message("failed", "direct registry contract instance is \
                not initialized")
    def worker_lookup(self, worker_type, org_id, application_id, id=None):
        """
        Lookup a worker identified by worker_type, org_id, and application_id.
        All fields are optional and, if present, condition should match for
        all fields. If none are passed it should return all workers.

        If the list is too large to fit into a single response (the maximum
        number of entries in a single response is implementation specific),
        the smart contract should return the first batch of the results
        and provide a lookupTag that can be used by the caller to
        retrieve the next batch by calling worker_lookup_next.

        Parameters:
        worker_type    Optional characteristic of workers for which you may
                       wish to search
        org_id         Optional organization ID that can be used to search
                       for one or more workers that belong to this
                       organization
        application_id Optional application type ID that is supported by
                       the worker
        id             Optional JSON RPC request ID

        Returns:
        Tuple containing workers count, lookup tag, and list of
        worker IDs:
        total_count Total number of entries matching a specified
                    lookup criteria. If this number is larger than the
                    size of the IDs array, the caller should use
                    lookupTag to call worker_lookup_next to retrieve
                    the rest of the IDs
        lookup_tag  Optional parameter. If it is returned, it means
                    that there are more matching worker IDs, which can then
                    be retrieved by calling function worker_lookup_next
                    with this tag as an input parameter
        ids         Array of the worker IDs that match the input parameters
        On error returns None.
        """

        if (self.__contract_instance is not None):
            if not isinstance(worker_type, WorkerType):
                logging.error("Invalid workerType {}".format(worker_type))
                return None
            if not is_valid_hex_str(org_id):
                logging.error("Invalid organization id {}".format(org_id))
                return None
            if not is_valid_hex_str(application_id):
                logging.error(
                    "Invalid application id {}".format(application_id))
                return None
            w_count, lookup_tag, w_ids = \
                self.__contract_instance.functions.workerLookUp(
                    worker_type.value, org_id, application_id).call()

            return w_count, lookup_tag, _convert_byte32_arr_to_hex_arr(
                w_ids)
        else:
            logging.error(
                "worker registry contract instance is not initialized")
            return None
Exemple #8
0
    def work_order_receipt_lookup_next(self,
                                       last_lookup_tag,
                                       worker_service_id=None,
                                       worker_id=None,
                                       requester_id=None,
                                       receipt_status=None,
                                       id=None):
        """
        Work Order Receipt Lookup Next
        """
        json_rpc_request = {
            "jsonrpc": "2.0",
            "method": "WorkOrderReceiptLookUpNext",
            "id": id,
            "params": {
                "lastLookUpTag": last_lookup_tag
            }
        }

        if worker_service_id is not None:
            if not is_valid_hex_str(worker_service_id):
                logging.error("Worker service id is Invalid")
                return create_jrpc_response(id,
                                            JsonRpcErrorCode.INVALID_PARAMETER,
                                            "Worker service id is Invalid")
            json_rpc_request["params"]["workerServiceId"] = worker_service_id

        if worker_id is not None:
            if not is_valid_hex_str(worker_id):
                logging.error("Worker id is Invalid")
                return create_jrpc_response(id,
                                            JsonRpcErrorCode.INVALID_PARAMETER,
                                            "Worker id is Invalid")
            json_rpc_request["params"]["workerId"] = worker_id

        if requester_id is not None:
            if not is_valid_hex_str(requester_id):
                logging.error("Requester id is Invalid")
                return create_jrpc_response(id,
                                            JsonRpcErrorCode.INVALID_PARAMETER,
                                            "Requester id is Invalid")
            json_rpc_request["params"]["requesterId"] = requester_id

        if receipt_status is not None:
            if not isinstance(receipt_status, ReceiptCreateStatus):
                logging.error("Invalid receipt status")
                return create_jrpc_response(id,
                                            JsonRpcErrorCode.INVALID_PARAMETER,
                                            "Invalid receipt status")
            json_rpc_request["params"]["receiptStatus"] = receipt_status

        if last_lookup_tag is None or not is_valid_hex_str(last_lookup_tag):
            logging.error("Last lookup tag is empty or Invalid")
            return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER,
                                        "Last lookup tag is empty or Invalid")

        response = self.__uri_client._postmsg(json.dumps(json_rpc_request))
        return response
    def worker_register(self, worker_id, worker_type, organization_id,
                        application_type_ids, details):
        """
        Registering a New Worker
        Inputs
        1. worker_id is a worker id, e.g. an Ethereum address or
        a value derived from the worker's DID.
        2. worker_type defines the type of Worker. Currently defined types are:
            1. indicates "TEE-SGX": an Intel SGX Trusted Execution Environment
            2. indicates "MPC": Multi-Party Compute
            3. indicates "ZK": Zero-Knowledge
        3. organization_id is an optional parameter representing the
        organization that hosts the Worker, e.g. a bank in the consortium or
        anonymous entity.
        4. application_type_ids is an optional parameter that defines
        application types supported by the Worker.
        5. details is detailed information about the worker in JSON format as
        defined in
        https://entethalliance.github.io/trusted-computing/spec.html
        #common-data-for-all-worker-types
        """

        if (self.__contract_instance is not None):
            if not is_valid_hex_str(
                    binascii.hexlify(worker_id).decode("utf8")):
                logging.error("Invalid worker id {}".format(worker_id))
                return None
            if not isinstance(worker_type, WorkerType):
                logging.error("Invalid workerType {}".format(worker_type))
                return None
            if not is_valid_hex_str(
                    binascii.hexlify(organization_id).decode("utf8")):
                logging.error(
                    "Invalid organization id {}".format(orgnization_id))
                return None
            for app_id in app_type_ids:
                if not is_valid_hex_str(
                        binascii.hexlify(app_id).decode("utf8")):
                    logging.error("Invalid application id {}".format(app_id))
                    return None
            if details is not None:
                worker = WorkerDetails()
                is_valid = worker.validate_worker_details(details)
                if is_valid is not None:
                    logging.error(
                        "Worker details not valid : {}".format(is_valid))
                    return None

            txn_dict = self.__contract_instance.functions.workerRegister(
                worker_type, organization_id, application_type_ids, details)\
                .buildTransaction(
                self.__eth_client.get_transaction_params())
            txn_receipt = self.__eth_client.execute_transaction(txn_dict)
            return txn_receipt
        else:
            logging.error(
                "worker registry contract instance is not initialized")
            return None
Exemple #10
0
    def work_order_receipt_create(self, work_order_id, worker_id,
                                  worker_service_id, requester_id,
                                  receipt_create_status,
                                  work_order_request_hash):
        """
        Create work order receipt in the Fabric block chain.

        Parameters:
        work_order_id           ID of the Work Order
        worker_id               Worker id that should execute the Work Order
        worker_service_id       ID of the Worker Service that
                                hosts the Worker
        requester_id            ID of the requester
        receipt_create_status   Initial receipt status defined
                                in EEA spec 7.1.1
        work_order_request_hash Hash value of the work order request as
                                defined in EEA spec 6.7

        Returns:
        0 on success and -1 on error.
        """
        if (self.__fabric_wrapper is not None):
            if not is_valid_hex_str(
                    binascii.hexlify(work_order_id).decode("utf8")):
                logging.info("Invalid work order id {}".format(work_order_id))
                return -1
            if not is_valid_hex_str(
                    binascii.hexlify(worker_id).decode("utf8")):
                logging.info("Invalid worker id {}".format(worker_id))
                return -1
            if not is_valid_hex_str(
                    binascii.hexlify(requester_id).decode("utf8")):
                logging.info("Invalid requester id {}".format(requester_id))
                return -1
            if not is_valid_hex_str(
                    binascii.hexlify(worker_service_id).decode("utf8")):
                logging.info("Invalid service id {}".format(worker_service_id))
                return -1
            if work_order_request_hash is None:
                logging.info("work order request hash is None")
                return -1
            params = []
            params.append(work_order_id)
            params.append(worker_id)
            params.append(worker_service_id)
            params.append(requester_id)
            params.append(receipt_create_status)
            params.append(work_order_request_hash)
            txn_status = self.__fabric_wrapper.invoke_chaincode(
                self.CHAIN_CODE, 'workOrderReceiptCreate', params)
            if txn_status is True:
                return 0
            else:
                return -1
        else:
            logging.error("Fabric wrapper instance is not initialized")
            return -1
Exemple #11
0
    def work_order_receipt_lookup_next(self, worker_service_id, worker_id,
                                       requester_id, receipt_status,
                                       last_lookup_tag):
        """
        Retrieve subsequent work order receipts after calling
        work_order_receipt_lookup().

        Parameters:
        worker_service_id Worker Service ID
        worker_id         Worker ID value derived from the worker's DID
        requester_id      Requester ID
        last_lookup_tag   One of the output parameters for function
                          work_order_receipt_lookup()
        id                Optional JSON RPC request ID

        Returns:
        On success, return a tuple containing total count, look up tag, and
        list of work order IDs:
        total_count       Total number of receipts matching the lookup
                          criteria
        lookup_tag        Optional parameter. If it is returned, it means
                          that there are more matching receipts that can be
                          retrieved by calling this function again and with
                          this tag as an input parameter.
        ids               Array of the Work Order receipt IDs that match the
                          input criteria from the corresponding call to
                          work_order_receipt_lookup().
        Return -1 on error.
        """
        if (self.__fabric_wrapper is not None):
            if not is_valid_hex_str(
                    binascii.hexlify(worker_id).decode("utf8")):
                logging.info("Invalid worker id {}".format(worker_id))
                return -1
            if not is_valid_hex_str(
                    binascii.hexlify(worker_service_id).decode("utf8")):
                logging.info("Invalid service id {}".format(worker_service_id))
                return -1
            if not is_valid_hex_str(
                    binascii.hexlify(requester_id).decode("utf8")):
                logging.info("Invalid requester id {}".format(requester_id))
                return -1
            params = []
            params.append(worker_service_id)
            params.append(worker_id)
            params.append(requester_id)
            params.append(receipt_status)
            params.append(last_lookup_tag)
            receipt_result = self.__fabric_wrapper.invoke_chaincode(
                self.CHAIN_CODE, 'workOrderReceiptLookUpNext', params)
            if receipt_result is not None:
                return receipt_result
            else:
                return -1
        else:
            logging.error("Fabric wrapper instance is not initialized")
            return -1
    def validate_parameters(self, params):
        """
        Validate params dictionary for existence of
        fields and mandatory fields

        Parameters:
        params    Parameter dictionary to validate

        Returns:
        True and empty string on success and
        False and string with error message on failure.
        """
        if len(params) == 0:
            return False, "Empty params in the request"

        key_list = []
        for key in params.keys():
            if key not in self.__param_key_map.keys():
                return False, "Invalid parameter {}".format(key)
            else:
                key_list.append(key)
        for k, v in self.__param_key_map.items():
            if v is True and k not in key_list:
                return False, "Missing parameter {}".format(k)

        if type(params["responseTimeoutMSecs"]) != int:
            return False, "Invalid data format for responseTimeoutMSecs"

        if params["payloadFormat"] != "JSON-RPC":
            return False, "Invalid payload format"

        if not is_valid_hex_str(params["workerId"]):
            return False, "Invalid data format for Worker id"
        if not is_valid_hex_str(params["workOrderId"]):
            return False, "Invalid data format for work order id"
        if not is_valid_hex_str(params["workloadId"]):
            return False, "Invalid data format for work load id"
        if not is_valid_hex_str(params["requesterId"]):
            return False, "Invalid data format for requester id"
        if "workerEncryptionKey" in params and \
                not is_valid_hex_str(params["workerEncryptionKey"]):
            return False, "Invalid data format for worker encryption key"
        if "encryptedSessionKey" in params and \
                not is_valid_hex_str(params["encryptedSessionKey"]):
            return False, "Invalid data format for encrypted session key"
        if "sessionKeyIv" in params and \
                not is_valid_hex_str(params["sessionKeyIv"]):
            return False, "Invalid data format for session key iv"
        if "encryptedRequestHash" in params and \
                not is_valid_hex_str(params["encryptedRequestHash"]):
            return False, "Invalid data format for encrypted request hash"
        if not is_valid_hex_str(params["requesterNonce"]):
            return False, "Invalid data format for requesterNonce"
        if "requesterSignature" in params:
            try:
                decoded_str = base64.b64decode(params["requesterSignature"],
                                               validate=True)
            except Exception:
                return False, "Invalid data format for requesterSignature"
        return True, ""
Exemple #13
0
    def test_is_valid_hex_str(self):
        """Tests to verify is_valid_hex_str(hex_str) function
        """
        str = 'ase234cds'  # random input case
        self.assertFalse(is_valid_hex_str(str))

        str = 'aae234cdb'  # random input case
        self.assertTrue(is_valid_hex_str(str))

        str = ''  # empty input case
        self.assertFalse(is_valid_hex_str(str))

        str = '0x'  # empty input case
        self.assertFalse(is_valid_hex_str(str))

        str = '0xae234cd'  # prepended by 0x
        self.assertTrue(is_valid_hex_str(str))

        str = '0XAECD1234'  # prepended by 0X
        self.assertTrue(is_valid_hex_str(str))

        str = '0x#aecd234'  # invalid character interpolated
        self.assertFalse(is_valid_hex_str(str))

        str = 'aecd0x234'  # 0x misplaced
        self.assertFalse(is_valid_hex_str(str))

        str = None  # None
        self.assertFalse(is_valid_hex_str(str))
Exemple #14
0
 def work_order_receipt_lookup_next(self, worker_service_id,
                                    worker_id, requester_id,
                                    receipt_status, last_lookup_tag):
     """
     Work Order Receipt Lookup Next
     Inputs:
     worker_service_id, worker_id, and requester_id are input parameters and
     last_lookup_tag is one of the output parameters for function
     work_order_receipt_lookup() defined in section Work Order Receipt
     Lookup.
     id is used for json rpc request
     Outputs:
     1. total_count is the total number of receipts matching the lookup
     criteria.
     2. lookup_tag is an optional parameter. If it is returned, it means
     that there are more matching receipts that can be retrieved by calling
     this function again and with this tag as an input parameter.
     3. ids is an array of the Work Order receipt ids that match the input
     criteria from the corresponding call to work_order_receipt_lookup().
     Returns
         tuple containing total count, look up tag and
         list of work order ids on success
         return -1 on error
     """
     if (self.__fabric_wrapper is not None):
         if not is_valid_hex_str(
                 binascii.hexlify(worker_id).decode("utf8")):
             logging.info("Invalid worker id {}".format(worker_id))
             return -1
         if not is_valid_hex_str(
                 binascii.hexlify(worker_service_id).decode("utf8")):
             logging.info("Invalid service id {}".format(worker_service_id))
             return -1
         if not is_valid_hex_str(
                 binascii.hexlify(requester_id).decode("utf8")):
             logging.info("Invalid requester id {}".format(requester_id))
             return -1
         params = []
         params.append(worker_service_id)
         params.append(worker_id)
         params.append(requester_id)
         params.append(receipt_status)
         params.append(last_lookup_tag)
         receipt_result = self.__fabric_wrapper.invoke_chaincode(
             self.CHAIN_CODE,
             'workOrderReceiptLookUpNext',
             params)
         if receipt_result is not None:
             return receipt_result
         else:
             return -1
     else:
         logging.error(
             "Fabric wrapper instance is not initialized")
         return -1
    def encryption_key_set(self,
                           worker_id,
                           encryption_key,
                           encryption_key_nonce,
                           tag,
                           signature_nonce,
                           signature,
                           id=None):
        if not is_valid_hex_str(worker_id):
            logging.error("Invalid Worker id")
            return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER,
                                        "Invalid Worker id")
        if not is_valid_hex_str(encryption_key):
            logging.error("Invalid encryption key")
            return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER,
                                        "Invalid encryption key")
        if encryption_key_nonce is not None and not is_valid_hex_str(
                encryption_key_nonce):
            logging.error("Invalid encryption nonce")
            return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER,
                                        "Invalid encryption nonce")
        if tag is not None and not is_valid_hex_str(tag):
            logging.error("Invalid tag")
            return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER,
                                        "Invalid tag")
        if signature_nonce is not None and not is_valid_hex_str(
                signature_nonce):
            logging.error("Invalid signature nonce")
            return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER,
                                        "Invalid signature nonce")
        if signature is not None:
            try:
                base64.b64decode(signature)
            except Exception as e:
                logging.error("Invalid signature")
                return create_jrpc_response(id,
                                            JsonRpcErrorCode.INVALID_PARAMETER,
                                            "Invalid signature")

        json_rpc_request = {
            "jsonrpc": "2.0",
            "method": "EncryptionKeySet",
            "id": id,
            "params": {
                "workerId": worker_id,
                "encryptionKey": encryption_key,
                "encryptionKeyNonce": encryption_key_nonce,
                "tag": tag,
                "signatureNonce": signature_nonce,
                "signature": signature
            }
        }
        response = self.__uri_client._postmsg(json.dumps(json_rpc_request))
        return response
Exemple #16
0
    def work_order_receipt_lookup(self, worker_service_id, worker_id,
                                  requester_id, receipt_status):
        """
        Lookup a work order receipt.

        Parameters:
        worker_service_id Worker Service ID whose receipts will be
                          retrieved
        worker_id         Worker Id whose receipts are requested
        requester_id      ID of the entity requesting receipts
        receipt_status    Defines the status of the receipts retrieve
        id                Optional JSON RPC request ID

        Returns:
        Tuple containing total count, last_lookup_tag, and
        list of work order IDs, on success:
        total_count     Total number of receipts matching the lookup criteria.
                        If this number is bigger than the size of the ids
                        array, the caller should use a lookup_tag to call
                        work_order_receipt_lookup_next() to retrieve the rest
                        of the receipt IDs.
        last_lookup_tag Optional lookup_tag when the receipts exceed the ids
                        array size
        ids             Array of work order receipt ids that match the input

        On error, returns -1.
        """
        if (self.__fabric_wrapper is not None):
            if not is_valid_hex_str(
                    binascii.hexlify(worker_id).decode("utf8")):
                logging.info("Invalid worker id {}".format(worker_id))
                return -1
            if not is_valid_hex_str(
                    binascii.hexlify(worker_service_id).decode("utf8")):
                logging.info("Invalid service id {}".format(worker_service_id))
                return -1
            if not is_valid_hex_str(
                    binascii.hexlify(requester_id).decode("utf8")):
                logging.info("Invalid requester id {}".format(requester_id))
                return -1
            params = []
            params.append(worker_service_id)
            params.append(worker_id)
            params.append(requester_id)
            params.append(receipt_status)
            receipt_result = self.__fabric_wrapper.invoke_chaincode(
                self.CHAIN_CODE, 'workOrderReceiptLookUp', params)
            if receipt_result is not None:
                return receipt_result
            else:
                return -1
        else:
            logging.error("Fabric wrapper instance is not initialized")
            return -1
Exemple #17
0
    def worker_lookup(self, worker_type, org_id, application_id, id=None):
        """
        Initiating Worker lookup
        This function retrieves a list of Worker ids that match the input
        parameters.
        The Worker must match all input parameters (AND mode) to be included
        in the list.
        If the list is too large to fit into a single response (the maximum
        number of entries in a single response is implementation specific),
        the smart contract should return the first batch of the results
        and provide a lookupTag that can be used by the caller to
        retrieve the next batch by calling worker_lookup_next.

        All input parameters are optional and can be provided in any
        combination to select Workers.

        Inputs
        1. worker_type is a characteristic of Workers for which you may wish
        to search
        2. organization_id is an id of an organization that can be used to
        search for one or more Workers that belong to this organization
        3. application_type_id is an application type that is supported by
        the Worker

        Returns
        1. total_count is a total number of entries matching a specified
        lookup criteria. If this number is bigger than size of ids array,
        the caller should use lookupTag to call workerLookUpNext to
        retrieve the rest of the ids.
        2. lookup_tag is an optional parameter. If it is returned, it means
        that there are more matching Worker ids that can be retrieved by
        calling function workerLookUpNext with this tag as an input parameter.
        3. ids is an array of the Worker ids that match the input parameters.
        """

        if (self.__contract_instance is not None):
            if not isinstance(worker_type, WorkerType):
                logging.error("Invalid workerType {}".format(worker_type))
                return None
            if not is_valid_hex_str(org_id):
                logging.error("Invalid organization id {}".format(org_id))
                return None
            if not is_valid_hex_str(application_id):
                logging.error(
                    "Invalid application id {}".format(application_id))
                return None
            lookup_result = self.__contract_instance.functions.workerLookUp(
                worker_type.value, org_id, application_id).call()

            return _convert_lookup_result_to_json(lookup_result)
        else:
            logging.error(
                "worker registry contract instance is not initialized")
            return None
Exemple #18
0
    def registry_update(self, org_id, uri, sc_addr, app_type_ids):
        """
        Update a registry.

        Parameters:
        org_id       bytes[] identifies organization that hosts the
                     registry, e.g. a bank in the consortium or an
                     anonymous entity
        uri          string that defines a URI for this registry that
                     supports the Off-Chain Worker Registry
                     JSON RPC API
        sc_addr      bytes[] defines a Fabric chain code name that
                     runs the Worker Registry Smart Contract API
                     smart contract for this registry
        app_type_ids []bytes[] is an optional parameter that defines
                     application types supported by the worker
                     managed by the registry

        Returns:
        Transaction receipt on success or None on error.
        """
        if (self.__fabric_wrapper is not None):
            if (is_valid_hex_str(binascii.hexlify(org_id).decode("utf8")) is
                    False):
                logging.error("Invalid Org id {}".format(org_id))
                return None
            if (sc_addr is not None and is_valid_hex_str(
                    binascii.hexlify(sc_addr).decode("utf8")) is False):
                logging.error(
                    "Invalid smart contract address {}".format(sc_addr))
                return None
            if (not uri):
                logging.error("Empty uri {}".format(uri))
                return None
            app_ids = []
            for aid in app_type_ids:
                if (is_valid_hex_str(binascii.hexlify(aid).decode("utf8")) is
                        False):
                    logging.error("Invalid application id {}".format(aid))
                    return None
                else:
                    app_ids.append(byte_array_to_hex_str(aid))

            params = []
            params.append(byte_array_to_hex_str(org_id))
            params.append(uri)
            params.append(byte_array_to_hex_str(sc_addr))
            params.append(','.join(app_ids))
            txn_status = self.__fabric_wrapper.invoke_chaincode(
                self.CHAIN_CODE, 'registryUpdate', params)
            return txn_status
        else:
            logging.error("Fabric wrapper instance is not initialized")
            return None
Exemple #19
0
    def registry_update(self, org_id, uri, sc_addr, app_type_ids):
        """
        Update a registry.

        Parameters:
        org_id               bytes[] identifies organization that hosts the
                             registry, e.g. a bank in the consortium or
                             an anonymous entity
        uri                  string defines a URI for this registry that
                             supports the Off-Chain Worker Registry
                             JSON RPC API
        sc_addr              bytes[] defines an Ethereum address that
                             runs a Worker Registry Smart Contract API
                             smart contract for this registry
        app_type_ids         []bytes[] is an optional parameter that defines
                             application types supported by the worker
                             managed by the registry

        Returns:
        Transaction receipt on success or None on error.
        """
        if (self.__contract_instance is not None):
            if (is_valid_hex_str(binascii.hexlify(org_id).decode("utf8"))
                    is False):
                logging.error("Invalid Org id {}".format(org_id))
                return None
            if (sc_addr is not None and is_valid_hex_str(
                    binascii.hexlify(sc_addr).decode("utf8")) is False):
                logging.error(
                    "Invalid smart contract address {}".format(sc_addr))
                return None
            if (not uri):
                logging.error("Empty uri {}".format(uri))
                return None
            for aid in app_type_ids:
                if (is_valid_hex_str(binascii.hexlify(aid).decode("utf8"))
                        is False):
                    logging.error("Invalid application id {}".format(aid))
                    return None

            txn_dict = \
                self.__contract_instance.functions.registryUpdate(
                    org_id, uri, sc_addr,
                    app_type_ids).buildTransaction(
                        self.__eth_client.get_transaction_params()
                        )
            txn_receipt = self.__eth_client.execute_transaction(
                txn_dict)
            return txn_receipt
        else:
            logging.error(
                "direct registry contract instance is not initialized")
            return None
    def work_order_submit(self,
                          work_order_id,
                          worker_id,
                          requester_id,
                          work_order_request,
                          id=None):
        """
        Submit work order request
        work_order_id is a unique id to identify the work order request
        worker_id is the identifier for the worker
        requester_id is a unique id to identify the requester
        work_order_request is a json string(Complete definition at
        work_order.py interface file)
        Returns
            An error code, 0 - success, otherwise an error.
        """
        if (self.__contract_instance is not None):
            if not is_valid_hex_str(
                    binascii.hexlify(work_order_id).decode("utf8")):
                logging.error("Invalid work order id {}".format(work_order_id))
                return ERROR

            if not is_valid_hex_str(
                    binascii.hexlify(worker_id).decode("utf8")):
                logging.error("Invalid worker id {}".format(worker_id))
                return ERROR

            if not is_valid_hex_str(
                    binascii.hexlify(requester_id).decode("utf8")):
                logging.error("Invalid requester id {}".format(requester_id))
                return ERROR

            if not _is_valid_work_order_json(work_order_id, worker_id,
                                             requester_id, work_order_request):
                logging.error(
                    "Invalid request string {}".format(work_order_request))
                return ERROR

            txn_dict = self.__contract_instance.functions.workOrderSubmit(
                work_order_id, worker_id, requester_id,
                work_order_request).buildTransaction(
                    self.__eth_client.get_transaction_params())
            try:
                txn_receipt = self.__eth_client.execute_transaction(txn_dict)
                return SUCCESS
            except Execption as e:
                logging.error(
                    "execption occured when trying to execute workOrderSubmit \
                     transaction on chain" + str(e))
                return ERROR
        else:
            logging.error("work order contract instance is not initialized")
            return ERROR
Exemple #21
0
    def work_order_receipt_update(self,
                                  work_order_id,
                                  updater_id,
                                  update_type,
                                  update_data,
                                  update_signature=None,
                                  signature_rules=None):
        """
        Update a Work Order Receipt.

        Parameters:
        work_order_id    Work Order ID that was sent in the
                         corresponding work_order_submit request
        updater_id       ID of the updating entity. It is optional if it
                         is the same as the transaction sender address
        update_type      Type of the Work Order update that defines
                         how the update should be handled
        update_data      Update-specific data that depends on the
                         updater type defined in EEA spec 7.1.2
        update_signature Optional signature of concatenated
                         work_order_id, update_type, and update_data
        signature_rules  Defines hashing and signing algorithms,
                         that are separated by forward slash '/'

        Returns:
        0 on success, -1 on error.
        """
        if (self.__fabric_wrapper is not None):
            if not is_valid_hex_str(
                    binascii.hexlify(work_order_id).decode("utf8")):
                logging.info("Invalid work order id {}".format(work_order_id))
                return -1
            if not is_valid_hex_str(
                    binascii.hexlify(updater_id).decode("utf8")):
                logging.info("Invalid updater id {}".format(updater_id))
                return -1
            params = []
            params.append(work_order_id)
            params.append(updater_id)
            params.append(update_type)
            params.append(update_data)
            if update_signature is not None:
                params.append(update_signature)
                params.append(signature_rules)
            receipt_status = self.__fabric_wrapper.invoke_chaincode(
                self.CHAIN_CODE, 'workOrderReceiptUpdate', params)
            if receipt_status is True:
                return 0
            else:
                return -1
        else:
            logging.error("Fabric wrapper instance is not initialized")
            return -1
Exemple #22
0
    def work_order_receipt_create(self,
                                  work_order_id,
                                  worker_id,
                                  worker_service_id,
                                  requester_id,
                                  receipt_create_status,
                                  work_order_request_hash,
                                  id=None):
        """
        Creating a Work Order Receipt json rpc request and submit tcs listener
        """
        if work_order_id is None or not is_valid_hex_str(work_order_id):
            logging.error("Work order id is empty or Invalid")
            return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER,
                                        "Worker id is empty or Invalid")

        if worker_id is None or not is_valid_hex_str(worker_id):
            logging.error("Worker id is empty or Invalid")
            return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER,
                                        "Worker id is empty or Invalid")

        if not isinstance(worker_type, ReceiptCreateStatus):
            logging.error("Invalid receipt create status")
            return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER,
                                        "Invalid receipt create status")

        if worker_service_id is None or not is_valid_hex_str(
                worker_service_id):
            logging.error("Worker service id is empty or Invalid")
            return create_jrpc_response(
                id, JsonRpcErrorCode.INVALID_PARAMETER,
                "Worker service id is empty or Invalid")

        if requester_id is None or not is_valid_hex_str(requester_id):
            logging.error("requester id is empty or Invalid")
            return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER,
                                        "requester id is empty or Invalid")

        json_rpc_request = {
            "jsonrpc": "2.0",
            "method": "WorkOrderReceiptCreate",
            "id": id,
            "params": {
                "workOrderId": work_order_id,
                "workerId": worker_id,
                "workerServiceId": worker_service_id,
                "requesterId": requester_id,
                "receiptCreateStatus": receipt_create_status,
                "workOrderRequestHash": work_order_request_hash
            }
        }
        response = self.__uri_client._postmsg(json.dumps(json_rpc_request))
        return response
Exemple #23
0
    def work_order_receipt_update(self,
                                  work_order_id,
                                  updater_id,
                                  update_type,
                                  update_data,
                                  update_signature,
                                  signature_rules,
                                  id=None):
        """
        Update a Work Order Receipt json rpc request and submit tcs listener
        """
        if work_order_id is None or not is_valid_hex_str(work_order_id):
            logging.error("Work order id is empty or Invalid")
            return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER,
                                        "Worker id is empty or Invalid")

        if updater_id is None or not is_valid_hex_str(updater_id):
            logging.error("Updater id is empty or Invalid")
            return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER,
                                        "Worker id is empty or Invalid")

        if not isinstance(update_type, ReceiptCreateStatus):
            logging.error("Invalid Update type")
            return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER,
                                        "Invalid update type")

        if update_data is None or not is_valid_hex_str(update_data):
            logging.error("Update data is empty or Invalid")
            return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER,
                                        "Update data is empty or Invalid")

        if update_signature is None or not is_valid_hex_str(update_signature):
            logging.error("update signature is empty or Invalid")
            return create_jrpc_response(
                id, JsonRpcErrorCode.INVALID_PARAMETER,
                "update signature is empty or Invalid")

        json_rpc_request = {
            "jsonrpc": "2.0",
            "method": "WorkOrderReceiptUpdate",
            "id": id,
            "params": {
                "workOrderId": work_order_id,
                "updaterId": updater_id,
                "updateType": update_type,
                "updateData": update_data,
                "updateSignature": update_signature,
                "signatureRules": signature_rules
            }
        }
        response = self.__uri_client._postmsg(json.dumps(json_rpc_request))
        return response
Exemple #24
0
 def work_order_receipt_lookup(self, worker_service_id,
                               worker_id, requester_id, receipt_status):
     """
     Function to lookup receipts
     Inputs:
     worker_service_id is a Worker Service id whose receipts will be
     retrieved.
     worker_id is the Worker Id whose receipts are requested.
     requester_id is the id of the entity requesting receipts.
     receipt_status defines the status of the receipts retrieved.
     id is used for json rpc request
     Outputs:
     total_count is the total number of receipts matching the lookup
     criteria. If this number is bigger than the size of the ids array,
     the caller should use a lookup_tag to call
     work_order_receipt_lookup_next() to retrieve the rest of the
     receipt ids.
     ids is an array of the Work Order receipt ids that match the input
     parameters
     On error returns -1
     """
     if (self.__fabric_wrapper is not None):
         if not is_valid_hex_str(
                 binascii.hexlify(worker_id).decode("utf8")):
             logging.info("Invalid worker id {}".format(worker_id))
             return -1
         if not is_valid_hex_str(
                 binascii.hexlify(worker_service_id).decode("utf8")):
             logging.info("Invalid service id {}".format(worker_service_id))
             return -1
         if not is_valid_hex_str(
                 binascii.hexlify(requester_id).decode("utf8")):
             logging.info("Invalid requester id {}".format(requester_id))
             return -1
         params = []
         params.append(worker_service_id)
         params.append(worker_id)
         params.append(requester_id)
         params.append(receipt_status)
         receipt_result = self.__fabric_wrapper.invoke_chaincode(
             self.CHAIN_CODE,
             'workOrderReceiptLookUp',
             params)
         if receipt_result is not None:
             return receipt_result
         else:
             return -1
     else:
         logging.error(
             "Fabric wrapper instance is not initialized")
         return -1
    def worker_lookup_next(self, worker_type, org_id, application_id,
                           lookup_tag):
        """
        Retrieve additional worker lookup results after calling worker_lookup.

        Parameters:
        worker_type         Characteristic of Workers for which you may wish
                            to search
        org_id              Organization ID to which a Worker belongs
        application_id      Optional application type ID that is
                            supported by the worker
        lookup_tag          is returned by a previous call to either this
                            function or to worker_lookup
        id                  Optional Optional JSON RPC request ID


        Returns:
        Tuple containing the following:
        total_count    Total number of entries matching this lookup
                       criteria.  If this number is larger than the number
                       of IDs returned so far, the caller should use
                       lookupTag to call worker_lookup_next to retrieve
                       the rest of the IDs
        new_lookup_tag Optional parameter. If it is returned, it
                       means that there are more matching worker IDs that
                       can be retrieved by calling this function again with
                       this tag as an input parameter
        ids            Array of the worker IDs that match the input parameters

        On error returns None.
        """

        if (self.__contract_instance is not None):
            if not isinstance(worker_type, WorkerType):
                logging.error("Invalid workerType {}".format(worker_type))
                return None
            if not is_valid_hex_str(org_id):
                logging.error("Invalid organization id {}".format(org_id))
                return None
            if not is_valid_hex_str(application_id):
                logging.error("Invalid application id {}".format(org_id))
                return None
            lookup_result = self.__contract_instance.functions\
                .workerLookUpNext(
                    worker_type.value,
                    org_id, application_id, lookup_tag).call()
            return lookup_result
        else:
            logging.error(
                "worker registry contract instance is not initialized")
            return None
    def validate_data_format(self, data):
        """
        Validate data format of the params data field (inData or outData).

        Parameters:
        data    Data (inData or OutData)

        Returns:
        True and empty string on success and
        False and string with error message on failure.
        """
        # In/out data is array of dict/json objects
        for data_item in data:
            if type(data_item) is not dict:
                return False, "Invalid data format for in/out data"
            in_data_keys = []
            for key in data_item.keys():
                if key not in self.__data_key_map.keys():
                    return False, "Invalid in data parameter {}".format(key)
                else:
                    in_data_keys.append(key)
            for k, v in self.__data_key_map.items():
                if v is True and k not in in_data_keys:
                    return False, "Missing in data parameter {}".format(k)

            if "dataHash" in data_item:
                data_hash = data_item["dataHash"]
                if not is_valid_hex_str(data_hash):
                    return False, \
                        "Invalid data format for data hash of in data"
            if "encryptedDataEncryptionKey" in data_item:
                enc_key = data_item["encryptedDataEncryptionKey"]
                if enc_key != "-" and \
                        enc_key != "" and \
                        enc_key != "null" and \
                        not is_valid_hex_str(enc_key):
                    return False, \
                        "Invalid data format for Encryption key of in data"
            if "iv" in data_item and data_item["iv"] != "" and \
                    data_item["iv"] != "0" and \
                    not is_valid_hex_str(data_item["iv"]):
                return False, \
                    "Invalid data format for initialization vector of in data"
            try:
                base64.b64decode(data_item["data"])
            except Exception as e:
                return False, \
                    "Invalid data format for in data"

        return True, ""
Exemple #27
0
 def work_order_receipt_update(self, work_order_id,
                               updater_id, update_type, update_data,
                               update_signature=None,
                               signature_rules=None):
     """
     Updating a Work Order Receipt
     Params
         work_order_id is a Work Order id that was
         sent in the corresponding work_order_submit request.
         updater_id is an id of the updating entity. It is optional
         update_type is from 0 to 255, the update sets the receipt
         status to update_type value
         update_data are update specific data that depends on
         updater type defined in EEA spec 7.1.2
         update_signature is an optional signature of
         work_order_id, update_type, and update_data.
         signature_rules defines hashing and signing algorithms,
         that are separated by forward slash '/'
     Returns
     -1 on error, 0 on Success.
     """
     if (self.__fabric_wrapper is not None):
         if not is_valid_hex_str(
                 binascii.hexlify(work_order_id).decode("utf8")):
             logging.info("Invalid work order id {}".format(work_order_id))
             return -1
         if not is_valid_hex_str(
                 binascii.hexlify(updater_id).decode("utf8")):
             logging.info("Invalid updater id {}".format(updater_id))
             return -1
         params = []
         params.append(work_order_id)
         params.append(updater_id)
         params.append(update_type)
         params.append(update_data)
         if update_signature is not None:
             params.append(update_signature)
             params.append(signature_rules)
         receipt_status = self.__fabric_wrapper.invoke_chaincode(
             self.CHAIN_CODE,
             'workOrderReceiptUpdate',
             params)
         if receipt_status is True:
             return 0
         else:
             return -1
     else:
         logging.error(
             "Fabric wrapper instance is not initialized")
         return -1
Exemple #28
0
 def worker_register(self,
                     worker_id,
                     worker_type,
                     org_id,
                     application_type_ids,
                     details,
                     id=None):
     """ Adds worker details to registry """
     if worker_id is None or not is_valid_hex_str(worker_id):
         logging.error("Worker id is empty or Invalid")
         return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER,
                                     "Worker id is empty or Invalid")
     if not isinstance(worker_type, WorkerType):
         logging.error("Invalid worker type")
         return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER,
                                     "Invalid worker type")
     if org_id is not None and not is_valid_hex_str(org_id):
         logging.error("Invalid organization id")
         return create_jrpc_response(id, JsonRpcErrorCode.INVALID_PARAMETER,
                                     "Invalid organization id")
     if application_type_ids is not None:
         for app_id in application_type_ids:
             if not is_valid_hex_str(app_id):
                 logging.error("Invalid application type id")
                 return create_jrpc_response(
                     id, JsonRpcErrorCode.INVALID_PARAMETER,
                     "Invalid application type id")
                 break
     if details is not None:
         is_valid = validate_details(details)
         if is_valid is not None:
             logging.error(is_valid)
             return create_jrpc_response(id,
                                         JsonRpcErrorCode.INVALID_PARAMETER,
                                         is_valid)
     json_rpc_request = {
         "jsonrpc": "2.0",
         "method": "WorkerRegister",
         "id": id,
         "params": {
             "workerId": worker_id,
             "workerType": worker_type.value,
             "organizationId": org_id,
             "applicationTypeId": application_type_ids,
             "details": json.loads(details)
         }
     }
     response = self.__uri_client._postmsg(json.dumps(json_rpc_request))
     return response
Exemple #29
0
    def worker_register(self, worker_id, worker_type, org_id, application_ids,
                        details):
        """
        Register new worker with details of worker
        """
        if (self.__contract_instance is not None):
            if not is_valid_hex_str(
                    binascii.hexlify(worker_id).decode("utf8")):
                logging.info("Invalid worker id {}".format(worker_id))
                return construct_message(
                    "failed", "Invalid worker id {}".format(worker_id))
            if not isinstance(worker_type, WorkerType):
                logging.info("Invalid workerType {}".format(worker_type))
                return construct_message(
                    "failed", "Invalid workerType {}".format(worker_type))
            if not is_valid_hex_str(binascii.hexlify(org_id).decode("utf8")):
                logging.info("Invalid organization id {}".format(org_id))
                return construct_message(
                    "failed", "Invalid organization id {}".format(org_id))
            for aid in application_ids:
                if not is_valid_hex_str(binascii.hexlify(aid).decode("utf8")):
                    logging.info("Invalid application id {}".format(aid))
                    return construct_message(
                        "failed", "Invalid application id {}".format(aid))
            if details is not None:
                is_valid = validate_details(details)
                if is_valid is not None:
                    return construct_message("failed", is_valid)

            txn_hash = self.__contract_instance.functions.workerRegister(
                worker_id, worker_type.value, org_id, application_ids,
                details).buildTransaction({
                    "chainId":
                    self.__eth_client.get_channel_id(),
                    "gas":
                    self.__eth_client.get_gas_limit(),
                    "gasPrice":
                    self.__eth_client.get_gas_price(),
                    "nonce":
                    self.__eth_client.get_txn_nonce()
                })
            tx = self.__eth_client.execute_transaction(txn_hash)
            return tx
        else:
            logging.error(
                "worker registry contract instance is not initialized")
            return construct_message(
                "failed",
                "worker registry contract instance is not initialized")
Exemple #30
0
    def work_order_receipt_retrieve(self, work_order_id):
        """
        Retrieve a Work Order Receipt.

        Parameters:
        work_order_id ID of the Work Order to be retrieved
        id        Optional JSON RPC request ID

        Returns:
        worker_service_id, requester_id, work_order_id, receipt_create_status,
        and work_order_request_hash, as defined in work_order_receipt_create().
        Return -1 on error.
        """
        if (self.__fabric_wrapper is not None):
            if not is_valid_hex_str(
                    binascii.hexlify(work_order_id).decode("utf8")):
                logging.info("Invalid work order id {}".format(work_order_id))
                return -1
            params = []
            params.append(work_order_id)
            retrieve_result = self.__fabric_wrapper.invoke_chaincode(
                self.CHAIN_CODE, 'workOrderReceiptRetrieve', params)
            if retrieve_result is not None:
                return retrieve_result
            else:
                return -1
        else:
            logging.error("Fabric wrapper instance is not initialized")
            return -1