What it does:
Controls who can access a patient’s medical records by enforcing on-chain permissions, access scopes, and time-based authorization without exposing actual medical data.
Why it matters:
Prevents unauthorized access, data misuse, and silent breaches by making all medical record access permissioned, traceable, and revocable by the patient.
How it works:
Medical records are represented by hashes or off-chain references (e.g. IPFS)
Patients are the sole owners of access permissions
Healthcare providers request access to specific records
Patients grant access with scope and expiration
Access can be revoked instantly at any time
All access permissions are transparently auditable on-chain
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
/**
* @title MedicalRecordAccessControl
* @author Nam
* @notice On-chain access control for medical record references
*/
contract MedicalRecordAccessControl {
// -------------------- RECORD STRUCT --------------------
struct MedicalRecord {
string recordHash; // IPFS hash or encrypted data reference
bool exists;
}
struct AccessPermission {
bool allowed;
uint256 expiry;
}
// -------------------- STORAGE --------------------
// patient => recordId => MedicalRecord
mapping(address => mapping(uint256 => MedicalRecord)) public records;
// patient => recordId => provider => AccessPermission
mapping(address => mapping(uint256 => mapping(address => AccessPermission))) public permissions;
// -------------------- EVENTS --------------------
event RecordAdded(address indexed patient, uint256 indexed recordId);
event AccessGranted(
address indexed patient,
uint256 indexed recordId,
address indexed provider,
uint256 expiry
);
event AccessRevoked(
address indexed patient,
uint256 indexed recordId,
address indexed provider
);
// -------------------- MODIFIERS --------------------
modifier onlyPatient(address _patient) {
require(msg.sender == _patient, "Not patient");
_;
}
// -------------------- RECORD MANAGEMENT --------------------
/**
* @notice Add a medical record reference
*/
function addRecord(
uint256 _recordId,
string calldata _recordHash
)
external
onlyPatient(msg.sender)
{
require(!records[msg.sender][_recordId].exists, "Record already exists");
records[msg.sender][_recordId] = MedicalRecord({
recordHash: _recordHash,
exists: true
});
emit RecordAdded(msg.sender, _recordId);
}
// -------------------- ACCESS CONTROL --------------------
/**
* @notice Grant access to a healthcare provider
*/
function grantAccess(
uint256 _recordId,
address _provider,
uint256 _duration
)
external
onlyPatient(msg.sender)
{
require(records[msg.sender][_recordId].exists, "Record not found");
require(_provider != address(0), "Invalid provider");
require(_duration > 0, "Invalid duration");
permissions[msg.sender][_recordId][_provider] = AccessPermission({
allowed: true,
expiry: block.timestamp + _duration
});
emit AccessGranted(
msg.sender,
_recordId,
_provider,
block.timestamp + _duration
);
}
/**
* @notice Revoke provider access
*/
function revokeAccess(
uint256 _recordId,
address _provider
)
external
onlyPatient(msg.sender)
{
AccessPermission storage permission =
permissions[msg.sender][_recordId][_provider];
require(permission.allowed, "Access not granted");
permission.allowed = false;
permission.expiry = 0;
emit AccessRevoked(msg.sender, _recordId, _provider);
}
// -------------------- VIEW FUNCTIONS --------------------
/**
* @notice Check if provider has access to a medical record
*/
function hasAccess(
address _patient,
uint256 _recordId,
address _provider
)
external
view
returns (bool)
{
AccessPermission memory permission =
permissions[_patient][_recordId][_provider];
return permission.allowed && block.timestamp <= permission.expiry;
}
/**
* @notice Get medical record reference (only metadata, not raw data)
*/
function getRecordHash(
address _patient,
uint256 _recordId
)
external
view
returns (string memory)
{
require(
permissions[_patient][_recordId][msg.sender].allowed &&
block.timestamp <= permissions[_patient][_recordId][msg.sender].expiry,
"Access denied"
);
return records[_patient][_recordId].recordHash;
}
}
Build and Grow By Nam Le Thanh