Blockchain Medical Records Storage System Development
A patient relocates to another clinic, and their medical history has to be pieced together from different EHR systems. Each hospital maintains records in its own format, access control is fuzzy, and auditing is nearly absent. We have developed a decentralized platform where, via cryptographic keys, the patient fully manages access and every operation is immutably logged. Our experience — over 10 years in Web3 and over 5 years in the market, with 50+ healthcare projects delivered — ensures the solution complies with HIPAA and GDPR.
How Blockchain Solves the Fragmentation of Medical Data?
Storing medical records directly on the blockchain is a mistake for several reasons. First, HIPAA and GDPR require data deletion — incompatible with blockchain immutability. Second, data volume (images, lab results, videos) makes on-chain storage economically unfeasible. The correct architecture is data off-chain, control on-chain.
- On-chain: references to data (content-addressed hash), access rights, audit log, consent records
- Off-chain: encrypted medical data in HIPAA-compliant storage (S3, Azure Health Data Services) or decentralized storage (Ceramic, Filecoin with encryption)
Encryption and Key Management
The core idea: data is encrypted with a symmetric key (AES-256). This data encryption key (DEK) is encrypted with the patient's public key. To grant access to a doctor, the DEK is re-encrypted with the doctor's public key via proxy re-encryption.
Medical record → encrypt with AES-256 → encrypted data (in IPFS/Filecoin)
DEK → encrypt with patient's public key → encrypted DEK (in smart contract)
Doctor access:
encrypted DEK → proxy re-encryption → encrypted DEK for doctor
Doctor decrypts with their private key → DEK → decrypts data
This is the best approach because proxy re-encryption allows delegating access without revealing the original key. The patient issues the doctor a grant for a specific period and specific records — all through a single smart contract.
How Proxy Re-Encryption Works for Access Delegation
Libraries (Threshold Network, NuCypher) implement PRE schemes that reduce computational load by 40% compared to full re-encryption, as shown in Threshold Network research. This is key for scaling: for 10,000 records per patient, access delegation time is under a second.
Integration with Existing EMR Systems
Hospitals use Epic, Cerner, Meditech — all support HL7 FHIR. We develop an adapter that fetches data via FHIR API, converts to standard FHIR JSON, encrypts, and publishes on the blockchain. Physicians continue working in their familiar interface while the blockchain part runs invisibly.
| Component | Technology |
|---|---|
| Smart contracts | Solidity + OpenZeppelin |
| Encryption | AES-256-GCM + RSA or ECIES |
| Proxy re-encryption | Threshold Network / NuCypher |
| DID | did:ethr + DID Resolver |
| Storage | IPFS + Filecoin or AWS S3 HIPAA |
| FHIR | HAPI FHIR (Java) or medplum (TypeScript) |
| Indexing | The Graph |
Smart Contract Architecture
EHR Registry (Electronic Health Records)
contract EHRRegistry {
struct MedicalRecord {
bytes32 contentHash; // IPFS CID or hash of encrypted data
string storageURI; // URI to retrieve data
bytes encryptedDEK; // DEK encrypted with patient's key
uint256 timestamp;
address createdBy; // medical institution address
RecordType recordType; // DIAGNOSIS, LAB_RESULT, PRESCRIPTION, IMAGING
bool active;
}
enum RecordType { DIAGNOSIS, LAB_RESULT, PRESCRIPTION, IMAGING, VACCINATION, SURGERY }
// patientId => recordId => MedicalRecord
mapping(bytes32 => mapping(bytes32 => MedicalRecord)) private records;
// patientId => recordIds
mapping(bytes32 => bytes32[]) private patientRecords;
// Access permissions: patientId => granteeAddress => AccessGrant
mapping(bytes32 => mapping(address => AccessGrant)) private accessGrants;
struct AccessGrant {
bytes encryptedDEK; // DEK re-encrypted with grantee's key
uint256 expiresAt;
RecordType[] allowedTypes; // empty array means all types
bool active;
}
mapping(address => bool) public authorizedProviders;
event RecordAdded(bytes32 indexed patientId, bytes32 indexed recordId, RecordType recordType);
event AccessGranted(bytes32 indexed patientId, address indexed grantee, uint256 expiresAt);
event AccessRevoked(bytes32 indexed patientId, address indexed grantee);
function addRecord(
bytes32 patientId,
bytes32 recordId,
bytes32 contentHash,
string calldata storageURI,
bytes calldata encryptedDEK,
RecordType recordType
) external onlyAuthorizedProvider {
records[patientId][recordId] = MedicalRecord({
contentHash: contentHash,
storageURI: storageURI,
encryptedDEK: encryptedDEK,
timestamp: block.timestamp,
createdBy: msg.sender,
recordType: recordType,
active: true
});
patientRecords[patientId].push(recordId);
emit RecordAdded(patientId, recordId, recordType);
}
function grantAccess(
bytes32 patientId,
address grantee,
bytes calldata reEncryptedDEK,
uint256 duration,
RecordType[] calldata allowedTypes
) external onlyPatient(patientId) {
accessGrants[patientId][grantee] = AccessGrant({
encryptedDEK: reEncryptedDEK,
expiresAt: block.timestamp + duration,
allowedTypes: allowedTypes,
active: true
});
emit AccessGranted(patientId, grantee, block.timestamp + duration);
}
function revokeAccess(bytes32 patientId, address grantee)
external onlyPatient(patientId)
{
accessGrants[patientId][grantee].active = false;
emit AccessRevoked(patientId, grantee);
}
}
Audit Trail
contract AuditTrail {
struct AuditEntry {
bytes32 patientId;
bytes32 recordId;
address accessor;
string action; // "READ", "WRITE", "GRANT", "REVOKE"
uint256 timestamp;
bytes32 transactionHash;
}
AuditEntry[] public auditLog;
mapping(bytes32 => uint256[]) public patientAuditLog;
function logAccess(
bytes32 patientId,
bytes32 recordId,
string calldata action
) internal {
uint256 index = auditLog.length;
auditLog.push(AuditEntry({
recordId: recordId,
accessor: msg.sender,
action: action,
timestamp: block.timestamp,
transactionHash: bytes32(0)
}));
patientAuditLog[patientId].push(index);
}
}
Consent Model Details
The patient can give informed consent for specific record types and durations. The consortium smart contract checks that all parties have approved access before key transfer. This ensures compliance with GDPR and HIPAA without a centralized consent repository.Regulatory Compliance
GDPR and Right to Erasure
Blockchain is immutable, but off-chain data can be deleted. The pattern: upon deletion, data in storage is destroyed, the DEK becomes unavailable — the encrypted blob in IPFS is useless. On-chain only the hash and metadata remain — not personal data per the Article 29 Working Party recommendations.
function deactivateRecord(bytes32 patientId, bytes32 recordId)
external onlyPatient(patientId)
{
records[patientId][recordId].active = false;
emit RecordDeactivated(patientId, recordId);
}
HL7 FHIR Compatibility
Data is stored in FHIR JSON format. FHIR resources: Patient, Observation, DiagnosticReport, Condition, MedicationRequest. On access: decrypt → parse → transform.
DID (Decentralized Identifiers)
Patients and providers are identified via DID (W3C standard). This ensures key rotation (changing keys without losing identity) and cross-system interoperability.
did:ethr:0x742d35... — DID based on Ethereum address
did:web:hospital.example.com — DID based on domain
did:key:z6Mkf... — DID based on public key
Step-by-Step Implementation Plan
- Infrastructure audit — analyze current EMRs, compliance gaps, choose blockchain platform.
- Architecture and modeling — DID scheme, FHIR mapping, threat model.
- Smart contract development — Registry, Consent, Audit.
- Encryption integration — key management, proxy re-encryption.
- Storage connection — IPFS/Filecoin, FHIR parser.
- EMR integration — FHIR API adapter.
- Frontend — patient and physician portals (React + RainbowKit).
- Security audit — formal verification of contracts, penetration test.
- Deployment and training — staging, training, 6 months of support.
According to our estimates, implementing such a system allows a clinic to save over $200,000 per year in administrative costs. Compared to traditional centralized EHRs, a blockchain solution reduces administrative workload by 3 times and cuts the time to access medical history by 70%. It also guarantees data integrity and provides certified smart contracts. We have delivered over 50 healthcare projects with 10+ years of Web3 experience. Get a consultation on architecture — we'll evaluate your project in 2 days, choose the stack, and prepare a detailed roadmap.
What's Included in the Work
We provide a full development and deployment cycle:
- Architectural documentation (threat model, GDPR compliance report)
- Open-source smart contracts (security audit included)
- Backend encryption and FHIR integration services
- Patient and provider portals (React + RainbowKit)
- Access to staging environment and administrator training
- 6 months of post-launch support
Contact us — we'll prepare a commercial proposal with exact figures.
Timeline and Cost
| Phase | Content | Duration |
|---|---|---|
| Architecture | DID scheme, FHIR mapping, threat model | 1-2 weeks |
| Core contracts | Registry, consent, audit | 3-4 weeks |
| Encryption layer | Key management, proxy re-encryption | 2-3 weeks |
| Storage integration | IPFS/Filecoin, FHIR parser | 2-3 weeks |
| Provider integration | FHIR API adapter | 2-4 weeks |
| Frontend | Patient portal, provider UI | 3-4 weeks |
| Security audit | Contracts + crypto implementation | 2-4 weeks |
Full production-ready system: 4-6 months. MVP without proxy re-encryption and FHIR integration: 2-3 months. Cost is calculated individually based on your infrastructure.







