What it does:
Stores patient health data in an encrypted, privacy-preserving vault on-chain while allowing selective access to authorized parties.
Why it matters:
Protects sensitive medical information, ensures compliance with privacy regulations, and gives patients full control over who can view or use their data.
How it works:
Patients encrypt their health data off-chain (IPFS or similar)
Encrypted data hash is stored on-chain in the vault
Patients grant access to hospitals, researchers, or insurers via smart permissions
Access rights can be updated, revoked, or time-limited
All access requests and grants are logged immutably
Third parties can verify data integrity without seeing raw data
Patients maintain full auditability of all interactions
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @title HealthDataPrivacyVault
* @author Nam
* @notice Secure, patient-controlled storage for encrypted health data
*/
contract HealthDataPrivacyVault {
// -------------------- STRUCTS --------------------
struct DataRecord {
string dataHash; // IPFS / encrypted data hash
uint256 timestamp;
}
struct AccessGrant {
bool allowed;
uint256 expiresAt; // 0 = no expiry
}
// -------------------- STORAGE --------------------
mapping(address => DataRecord[]) private patientData;
mapping(address => mapping(address => AccessGrant)) private accessControl;
// -------------------- EVENTS --------------------
event DataStored(address indexed patient, string dataHash);
event AccessGranted(address indexed patient, address indexed grantee, uint256 expiresAt);
event AccessRevoked(address indexed patient, address indexed grantee);
// -------------------- DATA MANAGEMENT --------------------
/**
* @notice Store encrypted health data
*/
function storeData(string calldata _dataHash) external {
patientData[msg.sender].push(DataRecord({
dataHash: _dataHash,
timestamp: block.timestamp
}));
emit DataStored(msg.sender, _dataHash);
}
/**
* @notice Grant access to a third party
*/
function grantAccess(address _grantee, uint256 _expiresAt) external {
require(_grantee != address(0), "Invalid grantee");
accessControl[msg.sender][_grantee] = AccessGrant({
allowed: true,
expiresAt: _expiresAt
});
emit AccessGranted(msg.sender, _grantee, _expiresAt);
}
/**
* @notice Revoke access
*/
function revokeAccess(address _grantee) external {
accessControl[msg.sender][_grantee] = AccessGrant({
allowed: false,
expiresAt: 0
});
emit AccessRevoked(msg.sender, _grantee);
}
// -------------------- VIEW FUNCTIONS --------------------
/**
* @notice Check if a grantee has access
*/
function hasAccess(address _patient, address _grantee) public view returns (bool) {
AccessGrant memory grant = accessControl[_patient][_grantee];
if (!grant.allowed) return false;
if (grant.expiresAt > 0 && block.timestamp > grant.expiresAt) return false;
return true;
}
/**
* @notice Retrieve patient's data (only for authorized parties)
*/
function getData(address _patient) external view returns (DataRecord[] memory) {
require(hasAccess(_patient, msg.sender) || msg.sender == _patient, "Access denied");
return patientData[_patient];
}
}
Build and Grow By Nam Le Thanh