Untitled
unknown
plain_text
2 years ago
10 kB
9
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].push(newService); bool actorExists = false; for (uint256 i = 0; i < actorAddresses.length; i++) { if (actorAddresses[i] == msg.sender) { actorExists = true; break; } } if (!actorExists) { actorAddresses.push(msg.sender); } } function getService(address _actorID, uint256 index) public view returns (Service memory) { require(index < services[_actorID].length, "Index out of bounds"); return services[_actorID][index]; } function getServicesCount(address _actorID) public view returns (uint256) { return services[_actorID].length; } function getActorAddressesCount() public view returns (uint256) { return actorAddresses.length; } } // 'Banking Transactions', 'Banking Services', 'Write', ['Account Number', 'Transaction History'] 0xAb8483F64d9C6d1EcF9b849Ae677dD3315835cb2 // 'Financial Transactions', 'Financial Services', 'Read', ['Phone Number', 'Account History'] 0x17F6AD8Ef982297579C203069C1DbfFE4348c372 //0xc5075f64488d32a067f76bd1d177b5376e72e8a9e3f0fb2395c1014b928d0181, 0x4B20993Bc481177ec7E8f571ceCaE8A9e22C02db, 'Write', ['Account Number', 'Transaction History'], false //0xc5075f64488d32a067f76bd1d177b5376e72e8a9e3f0fb2395c1014b928d0181, 0x617F2E2fD72FD9D5503197092aC168c91465E7f2, 'Read', ['Account Number', 'Transaction History'], true contract Agreement is SharedStructs { struct Consent { bytes32 purposeHash; address actorID; string operation; string[] personalData; address userId; bool isPositive; } event LogServiceParams( address indexed actorID, string serviceName, string servicePurpose, string operation, string[] personalData ); 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); consents[_actorID][msg.sender].push(newConsent); } function getConsents(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); uint256 numServices = dataUsage.getServicesCount(actorAddress); for (uint256 j = 0; j < numServices; j++) { Service memory service = dataUsage.getService(actorAddress, j); 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(); 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); 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]; //verification contract - 1 if (logEntry.actorId == consent.actorID) { SharedStructs.Service memory service = dataUsage.getService(actorAddress, k); //verification contract - 1, 2 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)) { //break from the inner loop once a matching consent is found. consentFound = true; break; } } } } 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 Dynamic array to store unique and return addresses address[] memory uniqueAddresses = new address[](0); //before the array was fixed size = 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++; } } return uniqueAddresses; // // 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; } } // address[] memory result = new address[](violatingCount); // for (uint256 i = 0; i < violatingCount; i++) { // result[i] = violatingActors[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...