Untitled
unknown
plain_text
2 years ago
9.0 kB
6
Indexable
//SPDX-License-Identifier: GPL-3.0 pragma solidity ^0.8.0; import "hardhat/console.sol"; contract SharedStructs { struct Service { address actorID; string serviceName; string servicePurpose; string operation; string[] personalData; } } contract DataUsage is SharedStructs { mapping(address => Service) public services; address[] public actorAddresses; function addService(string memory _serviceName, string memory _servicePurpose, string memory _operation, string[] memory _personalData) public { Service memory newService = Service(msg.sender, _serviceName, _servicePurpose, _operation, _personalData); services[msg.sender] = newService; actorAddresses.push(msg.sender); } function getService(address _actorID) public view returns (Service memory) { return services[_actorID]; } function getActorAddressesCount() public view returns (uint256) { return actorAddresses.length; } } contract Agreement is SharedStructs { // 'Banking Transactions', 'Banking Services', 'Write', ['Account Number', 'Transaction History'] 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2 // 'Financial Transactions', 'Financial Services', 'Read', ['Phone Number', 'Account History'] 0x17F6AD8Ef982297579C203069C1DbfFE4348c372 //0xc5075f64488d32a067f76bd1d177b5376e72e8a9e3f0fb2395c1014b928d0181, 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2, 'Write', ['Account Number', 'Transaction History'], false //0xc5075f64488d32a067f76bd1d177b5376e72e8a9e3f0fb2395c1014b928d0181, 0x17F6AD8Ef982297579C203069C1DbfFE4348c372, 'Read', ['Account Number', 'Transaction History'], true //0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2, 0x17F6AD8Ef982297579C203069C1DbfFE4348c372, 'Read', ['Account Number', 'Transaction History'], 'Financial Services' //0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2, 0x17F6AD8Ef982297579C203069C1DbfFE4348c372, 'Write', ['Account Number', 'Transaction History'], 'Banking Services' struct Consent { bytes32 purposeHash; address actorID; string operation; string[] personalData; address userId; bool isPositive; } //0xc5075f64488d32a067f76bd1d177b5376e72e8a9e3f0fb2395c1014b928d0181, 0x5B38Da6a701c568545dCfcB03FcB875f56beddC4, Write, ['Account Number', 'Transaction History'], 202, false event LogServiceParams( address indexed actorID, string serviceName, string servicePurpose, string operation, string[] personalData ); //to store user consents for data processing purposes, where each consent is associated with a specific actor mapping(address => mapping(address => Consent)) public consents; function giveConsent(bytes32 _purposeHash, address _actorID, string memory _operation, string[] memory _personalData, bool _isPositive) public { Consent memory newConsent = Consent(_purposeHash, _actorID, _operation, _personalData, msg.sender, _isPositive); //The function stores the newConsent struct in the consents nested mapping using the _actorID as the key for the outer mapping and the _userId as the key for the inner mapping. consents[_actorID][msg.sender] = newConsent; } function getConsent(address actorID, address userId) public view returns (Consent memory) { return consents[actorID][userId]; } function callGetService(address dataUsageContractAddress) public { DataUsage dataUsage = DataUsage(dataUsageContractAddress); uint256 numActors = dataUsage.getActorAddressesCount(); for (uint256 i = 0; i < numActors; i++) { address actorAddress = dataUsage.actorAddresses(i); Service memory service = dataUsage.getService(actorAddress); emit LogServiceParams( service.actorID, service.serviceName, service.servicePurpose, service.operation, service.personalData ); } } } contract Log { struct LogEntry { address actorId; address userId; string operation; string[] processedData; string serviceName; } mapping(uint256 => LogEntry) public logEntries; uint256 public entryCount; function addLogEntry(address _actorId, address _userId, string memory _operation, string[] memory _processedData, string memory _serviceName) public { LogEntry memory newEntry = LogEntry(_actorId, _userId, _operation, _processedData, _serviceName); logEntries[entryCount] = newEntry; entryCount++; } function getLogEntry(uint256 index) public view returns (LogEntry memory) { return logEntries[index]; } } contract Verification { DataUsage dataUsage; Agreement agreement; Log log; constructor(address _dataUsageAddress, address _agreementAddress, address _logAddress) { dataUsage = DataUsage(_dataUsageAddress); agreement = Agreement(_agreementAddress); log = Log(_logAddress); } function checkLog() public view returns (address[] memory){ uint256 numActors = dataUsage.getActorAddressesCount(); uint256 numLogEntries = log.entryCount(); //To store the violating actors address[] memory violatingActors = new address[](numLogEntries); //violator count uint256 violatingCount = 0; for (uint256 i = 0; i < numLogEntries; i++) { Log.LogEntry memory logEntry = log.getLogEntry(i); bool consentFound = false; //matching consented operation for (uint16 j = 0; j < numActors; j++) { address actorAddress = dataUsage.actorAddresses(j); Agreement.Consent memory consent = agreement.getConsent(actorAddress, logEntry.userId); if (logEntry.actorId == consent.actorID) { SharedStructs.Service memory service = dataUsage.getService(actorAddress); //Converting string to bytes, as string memory can't be directly compared 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; break; } } } if (!consentFound) { violatingActors[violatingCount] = logEntry.actorId; violatingCount++; } } //creating a new array that will store the address of the violating actors address[] memory result; //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; // Iteratating through the violatingActors array and counting unique addresses for (uint i = 0; i < violatingCount; i++) { bool isNewAddress = true; for (uint j = 0; j < uniqueCount; j++) { if (uniqueAddresses[j] == violatingActors[i]) { isNewAddress = false; break; } } 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]; } console.log("The violating actors are:"); for (uint i = 0; i < result.length; i++) { console.log(result[i]); } return result; } } function isSubset(string[] memory subset, string[] memory superset) private pure returns (bool) { for (uint256 i = 0; i < subset.length; i++) { bool found = false; for (uint256 j = 0; j < superset.length; j++) { if (keccak256(abi.encodePacked(subset[i])) == keccak256(abi.encodePacked(superset[j]))) { found = true; break; } } if (!found) { return false; } } return true; } }
Editor is loading...