Ontwikkel een Solidity Smart Contract voor Gedecentraliseerde Toegang tot Medische Gegevens
description
Met deze prompt kun je een geavanceerd Solidity smart contract ontwikkelen dat voldoet aan de complexe eisen van medische gegevensbeheer, inclusief privacy en wettelijke naleving. Het helpt je om een veilig systeem te ontwerpen dat toestemming en toegang effectief beheert, waardoor je risico's op datalekken en misbruik minimaliseert. Dit is beter dan algemene smart contract prompts omdat het zich richt op kritieke gezondheidszorgkwesties met specifieke beveiligings- en privacyvereisten.
prompt
Help mij een Solidity smart contract te ontwerpen en te schrijven voor een gedecentraliseerd systeem voor toegang tot medische gegevens. Het contract moet functies bevatten zoals: Patiëntregistratie: <voer patiëntidentificatiegegevens in>, Toestemmingsbeheer: <beschrijf hoe toestemming wordt gegeven en ingetrokken>, Gegevensverificatie: <beschrijf methoden voor het verifiëren van de authent ...
try_prompt
generate_helper
disclaimerOnPageApi
tags
ai_answers
provider: openai
model: gpt-4.1-nano
Het ontwikkelen van een Solidity smart contract voor een gedecentraliseerd medisch gegevenssysteem is complex en vereist aandacht voor privacy, veiligheid en regelgeving. Hieronder vind je een ontwerp en uitleg over de functies, beveiligingsmaatregelen en manieren om privacy te waarborgen, inclusief voorbeelden en mogelijke aanvalsvectoren.
---
### 1. Basisstructuur van het contract
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
contract MedischeGegevens {
// Struct voor patiëntgegevens
struct Patient {
address patientAddress;
mapping(address => bool) permissions; // Toestemming voor andere partijen
bytes32 encryptedDataHash; // Hash van encrypted gegevens (bv. IPFS hash)
bool exists;
}
// Mappings voor patiënten en gebruikersrollen
mapping(address => Patient) private patiënten;
mapping(address => Role) private rollen;
// Rollen voor toegangsniveaus
enum Role { Patient, Doctor, Specialist, Insurer, None }
// Events
event PatientRegistered(address patient);
event ConsentGiven(address patient, address provider);
event ConsentRevoked(address patient, address provider);
event DataUpdated(address patient, bytes32 dataHash);
event RoleAssigned(address user, Role role);
// Modifier voor toegangscontrole
modifier onlyRole(address user, Role role) {
require(rollen[user] == role, "Onvoldoende toegangsrechten");
_;
}
// Register patiënt
function registerPatient(address _patient) external {
require(!patiënten[_patient].exists, "Patiënt reeds geregistreerd");
patiënten[_patient] = Patient({
patientAddress: _patient,
exists: true,
encryptedDataHash: "",
permissions: {}
});
rollen[_patient] = Role.Patient;
emit PatientRegistered(_patient);
}
// Toewijzen rollen
function assignRole(address _user, Role _role) external {
// Toestemming voor roltoewijzing moet via extra verificatie
rollen[_user] = _role;
emit RoleAssigned(_user, _role);
}
// Patiënt geeft toestemming aan andere partijen
function giveConsent(address _provider) external onlyRole(msg.sender, Role.Patient) {
patiënten[msg.sender].permissions[_provider] = true;
emit ConsentGiven(msg.sender, _provider);
}
// Patiënt intrekt toestemming
function revokeConsent(address _provider) external onlyRole(msg.sender, Role.Patient) {
patiënten[msg.sender].permissions[_provider] = false;
emit ConsentRevoked(msg.sender, _provider);
}
// Gegevens uploaden (encrypted hash)
function updateEncryptedData(bytes32 _dataHash) external onlyRole(msg.sender, Role.Patient) {
patiënten[msg.sender].encryptedDataHash = _dataHash;
emit DataUpdated(msg.sender, _dataHash);
}
// Gegevens lezen (met verificatie van toestemming en rol)
function getEncryptedData(address _patient) external view returns (bytes32) {
Role callerRole = rollen[msg.sender];
require(patiënten[_patient].exists, "Patiënt niet gevonden");
require(
msg.sender == _patient || // Patiënt zelf
(callerRole == Role.Doctor) || // Arts
(callerRole == Role.Specialist) && patiënten[_patient].permissions[msg.sender] || // Specialist met toestemming
(callerRole == Role.Insurer), // Verzekeraar
"Geen toegang tot gegevens"
);
return patiënten[_patient].encryptedDataHash;
}
// Verificatie via ECDSA handtekeningen (voorbeeld)
function verifySignature(bytes32 messageHash, bytes memory signature) public pure returns (address) {
// Implementatie van ECDSA-verificatie
return ecrecover(messageHash, uint8(signature[64]) + 27, bytes32(signature[0:32]), bytes32(signature[32:64]));
}
}
```
---
### 2. Privacy waarborgen en regelgeving (GDPR)
- **Encryptie:** Gevoelige data wordt niet direct op de blockchain opgeslagen. In plaats daarvan wordt alleen een hash van de encrypted data opgeslagen (`encryptedDataHash`). De daadwerkelijke gegevens worden off-chain opgeslagen (bijvoorbeeld IPFS) en alleen via de hash wordt de integriteit gecontroleerd.
- **Toestemmingsbeheer:** Patiënten kunnen expliciet toestemming geven of intrekken via functies `giveConsent()` en `revokeConsent()`.
- **Identiteit en recht op gegevenswijziging:** Patiënten hebben controle over hun gegevens en kunnen op elk moment hun toestemming aanpassen.
- **Verwijdering van gegevens:** Dit kan worden gerealiseerd door off-chain gegevens te verwijderen en de hash op de blockchain te vervangen of te verwijderen.
- **Verificatie van gegevens:** Gebruik van ECDSA handtekeningen voor validatie van authenticiteit en integriteit van off-chain gegevens.
- **Gegevensminimalisatie:** Alleen de noodzakelijke gegevens worden op de blockchain opgeslagen, en gevoelige data wordt versleuteld en off-chain bewaard.
---
### 3. Voorbeelden van veilige implementatie
- **Gebruik van off-chain opslag:** Beperk de hoeveelheid gevoelige data op-chain en gebruik bijvoorbeeld IPFS of andere gedecentraliseerde opslagmethodes.
- **Digitale handtekeningen:** Handtekeningen ondertekenen off-chain gegevens, en deze worden geverifieerd via `verifySignature()`.
- **Role-based access control:** Toegang wordt geregeld op basis van rollen en expliciete toestemmingen.
- **Auditing:** Log alle toegang en wijzigingen via events voor transparantie en audit-trail.
---
### 4. Mogelijke aanvalsvectoren en mitigaties
| Aanvalsvector | Beschrijving | Mitigatie |
|------------------------------|------------------------------------------------------------|----------------------------------------------------------------|
| Replaying van transacties | Ongeautoriseerde hergebruik van toestemming of data | Use nonce of tijdstempels, en controle op hergebruik |
| Privékey-compromittering | Aanvallers die toegang krijgen tot de private keys | Gebruik hardware wallets, multisig, en veilige key-management |
| Ongeautoriseerde toegang | Rollen en toestemmingen worden misbruikt | Strenge rolcontrole, audits, en multi-factor authenticatie |
| Onjuiste gegevensverificatie | Verkeerde of vervalste off-chain gegevens | Digitale handtekeningen en hash-verificatie |
| Re-entrancy en exploits | Vulnerabiliteiten in functies die gegevens wijzigen | Gebruik van `ReentrancyGuard`, checks-effects-interactions |
---
### 5. Samenvatting
- Gebruik een combinatie van on-chain toegangscontrole en off-chain encryptie voor privacy.
- Maak gebruik van digitale handtekeningen voor gegevensvalidatie.
- Beperk op blockchain opgeslagen gegevens tot hashes en metadata.
- Bied patiënten expliciete controle over hun gegevens en toestemming.
- Voer regelmatige audits uit en blijf alert op nieuwe beveiligingsrisico's.
---
Heeft u verdere vragen of specifieke onderdelen die u verder uitgewerkt wilt zien?
provider: deepseek
model: deepseek-chat
Hallo! Ik help je graag met het ontwerpen van een veilig en GDPR-conform smart contract voor medische gegevens. Hieronder vind je een gedetailleerde implementatie met uitleg.
## Basis Contract Structuur
```solidity
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.19;
import "@openzeppelin/contracts/utils/cryptography/ECDSA.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract MedicalRecords is Ownable {
using ECDSA for bytes32;
// Gebruikersrollen
enum Role { Patient, Doctor, Specialist, Insurer }
// Toegangsniveaus
enum AccessLevel { None, Read, Write, Limited }
// Gebruikersstructuur
struct User {
address wallet;
Role role;
bool isActive;
uint256 registrationDate;
}
// Toestemmingsstructuur
struct Consent {
address patient;
address authorizedUser;
bool hasConsent;
uint256 expiryDate;
AccessLevel level;
}
// Medisch record
struct MedicalRecord {
bytes32 encryptedDataHash; // Versleutelde gegevens off-chain
address createdBy;
uint256 timestamp;
string dataType; // Bijv: "diagnose", "lab_resultaat"
}
// Mappings voor gegevensopslag
mapping(address => User) public users;
mapping(address => MedicalRecord[]) public patientRecords;
mapping(bytes32 => Consent) public consents;
mapping(address => address[]) public patientAuthorizations;
// Gebeurtenissen voor transparantie
event PatientRegistered(address indexed patient);
event ConsentGiven(address indexed patient, address indexed authorized);
event ConsentRevoked(address indexed patient, address indexed authorized);
event RecordAdded(address indexed patient, bytes32 recordHash);
constructor() Ownable(msg.sender) {}
}
```
## Patiëntregistratie Functie
```solidity
function registerPatient(address _patientWallet) external onlyOwner {
require(!users[_patientWallet].isActive, "Patient al geregistreerd");
users[_patientWallet] = User({
wallet: _patientWallet,
role: Role.Patient,
isActive: true,
registrationDate: block.timestamp
});
emit PatientRegistered(_patientWallet);
}
```
## Toestemmingsbeheer
```solidity
function giveConsent(
address _authorizedUser,
AccessLevel _level,
uint256 _durationInDays,
bytes memory _signature
) external {
// Verificatie met ECDSA handtekening
bytes32 messageHash = keccak256(abi.encodePacked(
msg.sender,
_authorizedUser,
_level,
_durationInDays,
block.chainid
));
address signer = messageHash.toEthSignedMessageHash().recover(_signature);
require(signer == msg.sender, "Ongeldige handtekening");
bytes32 consentId = keccak256(abi.encodePacked(msg.sender, _authorizedUser));
consents[consentId] = Consent({
patient: msg.sender,
authorizedUser: _authorizedUser,
hasConsent: true,
expiryDate: block.timestamp + (_durationInDays * 1 days),
level: _level
});
patientAuthorizations[msg.sender].push(_authorizedUser);
emit ConsentGiven(msg.sender, _authorizedUser);
}
function revokeConsent(address _authorizedUser) external {
bytes32 consentId = keccak256(abi.encodePacked(msg.sender, _authorizedUser));
require(consents[consentId].hasConsent, "Geen toestemming gevonden");
consents[consentId].hasConsent = false;
emit ConsentRevoked(msg.sender, _authorizedUser);
}
```
## Gegevens Toegang en Verificatie
```solidity
function addMedicalRecord(
bytes32 _encryptedDataHash,
string calldata _dataType,
address _patientAddress
) external {
require(users[msg.sender].isActive, "Gebruiker niet actief");
require(_hasWriteAccess(msg.sender, _patientAddress), "Geen schrijftoegang");
MedicalRecord memory newRecord = MedicalRecord({
encryptedDataHash: _encryptedDataHash,
createdBy: msg.sender,
timestamp: block.timestamp,
dataType: _dataType
});
patientRecords[_patientAddress].push(newRecord);
emit RecordAdded(_patientAddress, _encryptedDataHash);
}
function getMedicalRecords(
address _patientAddress,
uint256 _index
) external view returns (MedicalRecord memory) {
require(_hasReadAccess(msg.sender, _patientAddress), "Geen leestoegang");
require(_index < patientRecords[_patientAddress].length, "Ongeldige index");
return patientRecords[_patientAddress][_index];
}
function _hasReadAccess(address _requester, address _patient) internal view returns (bool) {
if (_requester == _patient) return true;
bytes32 consentId = keccak256(abi.encodePacked(_patient, _requester));
Consent memory consent = consents[consentId];
return consent.hasConsent &&
consent.expiryDate > block.timestamp &&
(consent.level == AccessLevel.Read ||
consent.level == AccessLevel.Write ||
consent.level == AccessLevel.Limited);
}
function _hasWriteAccess(address _requester, address _patient) internal view returns (bool) {
bytes32 consentId = keccak256(abi.encodePacked(_patient, _requester));
Consent memory consent = consents[consentId];
return consent.hasConsent &&
consent.expiryDate > block.timestamp &&
consent.level == AccessLevel.Write;
}
```
## GDPR Compliance Maatregelen
### 1. Data Minimalisatie
```solidity
// Bewaar alleen hashes, geen gevoelige data on-chain
function storeOnlyHash(bytes32 _encryptedHash) external {
require(users[msg.sender].role == Role.Patient, "Alleen patiënten");
// Off-chain encryptie gebeurt vooraf
}
```
### 2. Recht op Vergetelheid
```solidity
function deletePatientData() external {
require(users[msg.sender].role == Role.Patient, "Alleen patiënten");
// Verwijder alle toestemmingen
for (uint i = 0; i < patientAuthorizations[msg.sender].length; i++) {
bytes32 consentId = keccak256(abi.encodePacked(
msg.sender,
patientAuthorizations[msg.sender][i]
));
delete consents[consentId];
}
delete patientAuthorizations[msg.sender];
users[msg.sender].isActive = false;
}
```
## Beveiligingsmaatregelen en Aanvalsvectoren
### Veilige Implementatie Voorbeelden:
**1. Re-entrancy Protection:**
```solidity
// Gebruik Checks-Effects-Interactions pattern
bool private locked;
modifier noReentrant() {
require(!locked, "No re-entrancy");
locked = true;
_;
locked = false;
}
```
**2. Access Control:**
```solidity
modifier onlyRole(Role _requiredRole) {
require(users[msg.sender].role == _requiredRole, "Onvoldoende rechten");
require(users[msg.sender].isActive, "Gebruiker niet actief");
_;
}
```
### Te Vermijden Aanvalsvectoren:
**1. Front-running:**
- Gebruik commit-reveal schema's voor gevoelige transacties
- Implementeer tijdslot beperkingen
**2. Integer Overflow/Underflow:**
```solidity
// Gebruik SafeMath van OpenZeppelin
using SafeMath for uint256;
```
**3. Onvoorspelbare Randomness:**
```solidity
// Vermijd block.timestamp voor kritieke zaken
// Gebruik oracles voor echte random number generation
```
## Privacy Waarborgen
### Off-chain Encryptie Strategie:
```javascript
// Voorbeeld off-chain encryptie (Node.js)
const crypto = require('crypto');
function encryptMedicalData(data, publicKey) {
const symmetricKey = crypto.randomBytes(32);
const iv = crypto.randomBytes(16);
const cipher = crypto.createCipheriv('aes-256-gcm', symmetricKey, iv);
const encrypted = Buffer.concat([
cipher.update(data, 'utf8'),
cipher.final()
]);
// Encrypt symmetric key with patient's public key
const encryptedKey = crypto.publicEncrypt(publicKey, symmetricKey);
return {
encryptedData: encrypted.toString('hex'),
encryptedKey: encryptedKey.toString('hex'),
iv: iv.toString('hex'),
authTag: cipher.getAuthTag().toString('hex')
};
}
```
## Aanbevelingen voor GDPR Compliance:
1. **Data Protection by Design**: Implementeer privacy vanaf het begin
2. **Purpose Limitation**: Definieer duidelijk het doel van dataverzameling
3. **Storage Limitation**: Bewaar data alleen zo lang als nodig
4. **Transparantie**: Gebruik events voor audit trails
5. **Rechten van Betrokkenen**: Implementeer delete/export functies
## Belangrijke Overwegingen:
- **Sleutelbeheer**: Gebruik hardware wallets voor patiëntsleutels
- **Backup strategie**: Implementeer emergency recovery procedures
- **Juridisch advies**: Raadpleeg altijd juridische experts voor GDPR
- **Testnet gebruik**: Test uitgebreid op testnets voor productie
Dit contract biedt een solide basis, maar vereist aanvullende off-chain componenten voor een compleet systeem. Laat weten als je specifieke onderdelen verder wilt uitwerken!
error: Generation failed [deepseek] prompt_id=4365 locale=de err=DeepSeek connection/timeout