Untitled

mail@pastecode.io avatar
unknown
plain_text
2 years ago
6.5 kB
3
Indexable
Never
//SPDX-License-Identifier: GPL-3.0
pragma solidity ^0.8.0;

import "hardhat/console.sol";
import "./SharedStructs.sol";
import "./DataUsage.sol";
import "./Agreement.sol";
import "./Log.sol";


contract Verification {
    //Instance of the contracts to interact with their respective usage related functions
    DataUsage dataUsage;
    Agreement agreement;
    Log log;
    //creating a new array that will store the address of the violating actors
    address[] result;


    // Constructor initializes the contract with the addresses of DataUsage, Agreement, and Log contracts
    constructor(address _dataUsageAddress, address _agreementAddress, address _logAddress) {
        dataUsage = DataUsage(_dataUsageAddress);
        agreement = Agreement(_agreementAddress);
        log = Log(_logAddress);
    }

    // Function to check the log for any violations
    function checkLog() external returns (address[] memory){
        uint256 numActors = dataUsage.getActorAddressesCount();
        uint256 numLogEntries = log.entryCount();
        address[] memory violatingActors = new address[](numLogEntries);
        uint256 violatingCount = 0;
        //Iterating through log entries
        for (uint256 i = 0; i < numLogEntries; i++) {
            Log.LogEntry memory logEntry = log.getLogEntry(i);
            // Initialize a flag to track if a matching consent is found for the current log entry
            bool consentFound = false;
            //Iterating through actor count
            for (uint16 j = 0; j < numActors; j++) {
                address actorAddress = dataUsage.actorAddresses(j);
                Agreement.Consent[] memory userConsents = agreement.getConsents(actorAddress, logEntry.userId);
                //Iterating through user consent (actoraddress, index)
                for (uint16 k = 0; k < userConsents.length; k++) {
                    Agreement.Consent memory consent = userConsents[k];
                    // Check if the serviceName in Consent and LogEntry are the same
                    if (keccak256(abi.encodePacked(logEntry.serviceName)) == keccak256(abi.encodePacked(consent.serviceName))) {
                        // verification contract - 1 (Check if the actorId in Consent and LogEntry are the same)
                        if (logEntry.actorId == consent.actorID) {
                            SharedStructs.Service memory service = dataUsage.getService(actorAddress, k);
                            // verification contract - 2, 3 (Verification of operations and personal data match)
                            if (keccak256(abi.encodePacked(logEntry.operation)) == keccak256(abi.encodePacked(service.operation)) &&
                            keccak256(abi.encodePacked(logEntry.operation)) == keccak256(abi.encodePacked(consent.operation)) &&
                                isSubset(logEntry.processedData, consent.personalData)) {
                                consentFound = true;
                            }
                        }
                    }
                }
            }
            // If no consent was found for the log entry, add the actorId to the violatingActors array and increment the violatingCount
            if (!consentFound) {
                violatingActors[violatingCount] = logEntry.actorId;
                violatingCount++;
            }
        }
        
        //If no violations, print to console "no violations found" and return an empty array
        if (violatingCount == 0) {
            console.log("No violations found!");
            return new address[](0);
        } else {
            console.log("Violations found!");

            // Creating a temporary array to store unique addresses
            address[] memory uniqueAddresses = new address[](violatingCount);

            // Counting the number of unique addresses
            uint uniqueCount = 0;

            // Iterating through the violatingActors array and counting unique addresses
            for (uint i = 0; i < violatingCount; i++) {
                bool isNewAddress = true;
                // Iterate through the uniqueAddresses array to check if the current violating actor is already in the list.
                for (uint j = 0; j < uniqueCount; j++) {
                    if (uniqueAddresses[j] == violatingActors[i]) {
                        isNewAddress = false;
                        break;
                    }
                }
                // If the violating actor is not found in the uniqueAddresses array, add it to the array and increment the uniqueCount
                if (isNewAddress) {
                    uniqueAddresses[uniqueCount] = violatingActors[i];
                    uniqueCount++;
                }
            }

            // Creating a new array with the size of unique addresses
            result = new address[](uniqueCount);

            // Appending the unique addresses to the result array
            for (uint i = 0; i < uniqueCount; i++) {
                result[i] = uniqueAddresses[i];
            }

            // Log the violating actors' addresses to the console by iterating through the 'result' array
            console.log("The violating actors are:");
            for (uint i = 0; i < result.length; i++) {
                console.log(result[i]);
            }

            return result;
        }
    }
    //verification contract-3, check if the processed personal data is a subset of consented personal data
    function isSubset(string[] memory subset, string[] memory superset) internal pure returns (bool) {
        // Iterate through the 'subset' array elements to verify if they are part of the 'superset' array
        for (uint256 i = 0; i < subset.length; i++) {
            bool found = false;
            // Iterate through the 'superset' array elements to find a match with the current 'subset' element
            for (uint256 j = 0; j < superset.length; j++) {
                // Compare the hash of the 'subset' element with the hash of the 'superset' element
                if (keccak256(abi.encodePacked(subset[i])) == keccak256(abi.encodePacked(superset[j]))) {
                    found = true;
                    break;
                }
            }
            // If no match is found for the current 'subset' element, it is not a part of the 'superset' and return false
            if (!found) {
                return false;
            }
        }
        return true;
    }
}