Ejemplo n.º 1
0
class UpdateStateResponse(ContractResponse):
    def __init__(self, request, response, **kwargs):
        super().__init__(request, response, **kwargs)

        self.state_changed = True
        self.request_number = request.request_number
        self.operation = 'update'

        self.signature = response['Signature']

        # we have another mismatch between the field names in the enclave
        # and the field names expected in the transaction; this needs to
        # be fixed at some point
        for dependency in response['Dependencies']:
            contract_id = dependency['ContractID']
            state_hash = dependency['StateHash']
            self.dependencies.append({
                'contract_id': contract_id,
                'state_hash': state_hash
            })

        # save the information we will need for the transaction
        state_hash_b64 = response['StateHash']
        self.new_state_hash = crypto.base64_to_byte_array(state_hash_b64)
        self.old_state_hash = ContractState.compute_state_hash(
            request.contract_state.raw_state)

        message = self.serialize_for_signing()
        if not self.verify_enclave_signature(message, request.enclave_keys):
            raise Exception('failed to verify enclave signature')

        self.raw_state = self.enclave_service.get_block(state_hash_b64)
        self.new_state_object = ContractState(self.contract_id, self.raw_state)
        self.new_state_object.pull_state_from_eservice(self.enclave_service)

        # compute ids of blocks in the change set (used for replication)
        self.new_state_object.compute_new_block_ids(
            request.contract_state.component_block_ids)
        self.replication_params = request.replication_params

    # -------------------------------------------------------
    def serialize_for_signing(self):
        """serialize the response for enclave signature verification"""

        message = super().serialize_for_signing()

        message += self.old_state_hash
        message += self.new_state_hash

        for dependency in self.dependencies:
            message += crypto.string_to_byte_array(dependency['contract_id'])
            message += crypto.string_to_byte_array(dependency['state_hash'])

        return message
Ejemplo n.º 2
0
class InitializeStateResponse(ContractResponse):
    def __init__(self, request, response, **kwargs):
        super().__init__(request, response, **kwargs)

        self.state_changed = True
        self.request_number = request.request_number
        self.operation = 'initialize'

        self.metadata_hash = crypto.base64_to_byte_array(
            response['MetadataHash'])
        self.signature = response['Signature']

        # save the information we will need for the transaction
        state_hash_b64 = response['StateHash']
        self.new_state_hash = crypto.base64_to_byte_array(state_hash_b64)

        message = self.serialize_for_signing()
        if not self.verify_enclave_signature(message, request.enclave_keys):
            raise InvocationException('failed to verify enclave signature')

        self.raw_state = self.enclave_service.get_block(state_hash_b64)
        self.new_state_object = ContractState(self.contract_id, self.raw_state)
        self.new_state_object.pull_state_from_eservice(self.enclave_service)

        # compute ids of blocks in the change set (used for replication)
        self.new_state_object.compute_new_block_ids(
            request.contract_state.component_block_ids)
        self.replication_params = request.replication_params

    # -------------------------------------------------------
    def serialize_for_signing(self):
        """serialize the response for enclave signature verification"""

        message = super().serialize_for_signing()
        message += crypto.string_to_byte_array(self.creator_id)
        message += self.metadata_hash
        message += self.new_state_hash

        return message