Decentralized Medical Records Storage on Blockchain

We design and develop full-cycle blockchain solutions: from smart contract architecture to launching DeFi protocols, NFT marketplaces and crypto exchanges. Security audits, tokenomics, integration with existing infrastructure.
Showing 1 of 1All 1305 services
Decentralized Medical Records Storage on Blockchain
Complex
from 1 week to 3 months
Frequently Asked Questions

Blockchain Development Services

Blockchain Development Stages

Latest works

  • image_website-b2b-advance_0.webp
    B2B ADVANCE company website development
    1347
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1247
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    948
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1183
  • image_logo-advance_0.webp
    B2B Advance company logo design
    642
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    921

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

  1. Infrastructure audit — analyze current EMRs, compliance gaps, choose blockchain platform.
  2. Architecture and modeling — DID scheme, FHIR mapping, threat model.
  3. Smart contract development — Registry, Consent, Audit.
  4. Encryption integration — key management, proxy re-encryption.
  5. Storage connection — IPFS/Filecoin, FHIR parser.
  6. EMR integration — FHIR API adapter.
  7. Frontend — patient and physician portals (React + RainbowKit).
  8. Security audit — formal verification of contracts, penetration test.
  9. 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.

Digital Identity on Blockchain: DID, SBT, and Verifiable Credentials

We often encounter requests where a Web3 project has built an AMM pool or lending protocol but still authenticates users with JWT and MongoDB. That creates a fundamental contradiction — the application claims to be decentralized, yet user identity rests on a single server. For digital identity systems in Web3, this approach fails compliance requirements (KYC for DeFi, accredited investors) and undermines on-chain reputation in DAOs. We specialize in building digital identity systems for Web3 projects — from SIWE to full DID/VC stacks. Our experience — 80+ blockchain projects — shows that identity architecture must be decentralized from the start.

How does Sign-In with Ethereum solve authentication?

EIP-4361 (SIWE) removes login/password entirely. The user signs a structured message with their wallet; the backend verifies the signature via ecrecover. No credential leaks, no password hashing.

Implementation: siwe library (JS/TS) on the frontend, SiweMessage.verify() on the backend. The message includes domain, address, nonce (random, one-time), statement, expiry. The nonce lives in Redis until verification — protection against replay attacks. Today, SIWE is used by over 80 projects in the top 100 DeFi.

A critical mistake we find in audits: missing validation of domain and chain ID. If the backend does not check message.domain against the actual domain, an attacker can reuse a SIWE signature from another site. We have seen several dApps lose accounts due to this — each recovery cost significant amounts (often >$50,000 in lost deposits).

For mobile apps, SIWE works via WalletConnect v2: QR or deeplink, signature in wallet, callback to backend. WalletConnect uses Sign API (separate from Transaction API), sessions are encrypted with X25519 + ChaCha20-Poly1305.

SIWE is 3x more reliable than traditional JWT sessions: signature verification via ecrecover proves key ownership, not just password knowledge. Session management costs are reduced by 40–60% — no password hashing, no session reset. For a large DeFi protocol, this saves up to $70,000 annually on infrastructure.

What is DID and which method to choose?

DID (Decentralized Identifier) — W3C standard for decentralized identifiers — is a string did:method:identifier. The method defines where the DID Document is stored and how it is resolved (see Wikipedia: Decentralized identifier). The main methods we use in production:

Method Storage Location Gas Cost Use Case
did:ethr EthereumDIDRegistry (ERC-1056) ~60,000 gas on write DeFi, DAO — key rotation
did:key Deterministically derived from pubkey Gasless Ephemeral identity, test
did:web HTTPS (/.well-known/did.json) Gasless Enterprise (DNS trust)
did:ion Bitcoin Layer 2 (Sidetree) ~5,000 gas Long-term, high security

For most DeFi projects, did:ethr or did:key suffice. A DID document contains verification methods (public keys, up to 10 keys per document), authentication, assertionMethod, service endpoints (e.g., link to KYC service). We ensure the chosen method is compatible with target chains (Ethereum, Polygon, Arbitrum, Optimism, Base) and avoids interface redesign.

Common mistakes when choosing a DID method:

  • Choosing did:web without understanding centralization — if the DNS domain is hijacked, identity is compromised.
  • Ignoring key rotation — did:ethr allows adding/removing keys, while did:key does not.
  • Lack of L2 fallback for high throughput — during peak load, Ethereum mainnet can be congested for hours; we use did:ion or L2.

How does verification work via Verifiable Credentials?

Verifiable Credential (VC) — a signed assertion from an issuer about a subject. W3C format: JSON-LD or JWT. Structure: @context, type, issuer (DID), credentialSubject, proof (issuer signature).

Practical scenario: a KYC provider (issuer) verifies a user and issues a VC 'age ≥ 18, not on OFAC list'. The user stores the VC locally (wallet extension or mobile app). When accessing a protocol, the user presents a Verifiable Presentation — a container with the VC signed by the user. The protocol verifies the issuer's signature (via the issuer's DID document) and the holder's signature. No personal data goes on-chain. The protocol does not store a database of KYC-passed users. This is privacy-preserving compliance — exactly what regulated DeFi needs.

Zero-knowledge proofs for VCs take privacy to another level. Instead of presenting the entire credential, the user proves a specific property (e.g., age ≥ 18) without revealing the value. Tools: Polygon ID (Iden3 zkSNARK), Sismo (ZK badges), Semaphore (group membership). Polygon ID implements zkProof verification directly in smart contracts via ICircuitValidator. Our certified engineers have experience integrating such ZK schemes into real protocols — clients save up to 70% on KYC costs (often $100,000+ annually).

Why are Soulbound Tokens not suitable for mass adoption?

SBTs (EIP-5192, concept by Vitalik Buterin) are non-transferable NFTs. Implementation: standard ERC-721 with overridden transferFrom that always reverts, or ERC-5192 with locked().

Production uses:

  • DAO Governance — Snapshot + SBT for one-person-one-vote. Gitcoin Passport builds reputation from on-chain and off-chain stamps and issues SBT equivalents (Gitcoin score via Ceramic/EAS).
  • Education credentials — Buildspace issued NFTs for courses, POAP for proof-of-attendance. SBTs make them non-transferable — cannot buy someone else's history.
  • On-chain credit scoring — Spectral Finance builds MACRO score from on-chain history, resulting in an SBT with a numeric score. Lending protocols use it for under-collateralized loans.

Key technical limitation: recovery mechanism. Losing access to a wallet means losing all SBTs. Without recovery, mass adoption is impossible. Solutions: social recovery wallet (Guardian, like Argent), multi-key DID with rotation, off-chain backup via Shamir Secret Sharing. We include recovery planning in every SBT project.

Ethereum Attestation Service as a standard identity layer

EAS is deployed on Ethereum mainnet, Optimism, Arbitrum, Base. Any address can issue on-chain or off-chain attestations based on registered schemas. A schema is an ABI-encoded structure. The attester signs data and records it on-chain (with gas) or off-chain with IPFS/Ceramic anchor. Verifiers read via IEAS.getAttestation(uid).

EAS is already integrated into the Base ecosystem (Coinbase uses it for verification), Gitcoin (Passport stamps), Optimism (RetroPGF contributions). It is becoming the de facto standard for on-chain identity layer on L2. Our developers are certified for EAS (experience with 5+ projects). According to EAS documentation, attestations can be revoked, and schemas supportup to 32 fields of arbitrary ABI types.

How can we choose the right identity solution for your project?

  1. Analytics & compliance — map the user journey: who is issuer, verifier, what data is needed, what cannot be stored on-chain under GDPR.
  2. Architecture design — choose between on-chain SBT, EAS, DID/VC stack. Data schema, ZK circuit (if needed).
  3. Implementation — smart contracts (Solidity 0.8.x, Foundry/Hardhat), issuer service (Node.js/Go), holder wallet (ethers.js viem), verifier contract.
  4. Testing & audit — unit tests, integration tests, fuzzing (Echidna), static analysis (Slither). Engage third-party auditor.
  5. Deploy & support — deploy to target networks, monitoring (Tenderly), documentation, team training.

Deliverables

  • Source code of smart contracts (Solidity, open-sourced under MIT)
  • Issuer backend (Node.js/Go) with API for issuing VC/SBT
  • Holder wallet integration (ethers.js viem, RainbowKit, WalletConnect)
  • Verifier contract/script
  • Architecture documentation, deployment runbook
  • 2 months post-deployment support

Timeline Estimates

Phase Duration
SIWE integration (wallet authentication) 2 to 4 weeks
SBT contracts + minting portal 3 to 6 weeks
EAS attestation schema + verification 4 to 8 weeks
Full DID/VC pipeline (issuer + holder + verifier) 3 to 6 months
ZK-based privacy-preserving credentials 5 to 9 months

Cost is calculated individually based on schema complexity, number of chains, and compliance requirements. Contact us to discuss your scenario and get an optimal plan.

Order a digital identity system development — get a consultation with a senior engineer specialized in this field. Also, book a technical audit of your current identity system — we will identify bottlenecks and suggest concrete improvements.