Разработка системы хранения медицинских записей на блокчейне
Пациент переезжает в другую клинику — его историю болезни приходится собирать по крупицам из разных систем EHR. Каждая больница ведет записи в своем формате, контроль доступа размыт, аудит практически отсутствует. Мы разработали децентрализованную платформу, где пациент через криптографические ключи полностью управляет доступом, а каждая операция логируется неизменно. Наш опыт — более 10 лет в Web3 и 5 лет на рынке, поэтому решение соответствует HIPAA и GDPR.
Как блокчейн решает проблему фрагментации медицинских данных?
Хранить медицинские записи непосредственно в блокчейне — ошибочное решение по нескольким причинам. Во-первых, HIPAA и GDPR требуют возможности удаления данных — это несовместимо с неизменяемостью блокчейна. Во-вторых, объем данных (изображения, лабораторные результаты, видео) делает on-chain хранение экономически нецелесообразным. Правильная архитектура — данные off-chain, контроль on-chain.
- On-chain: ссылки на данные (content-addressed hash), права доступа, audit log, consent записи
- Off-chain: зашифрованные медицинские данные в HIPAA-compliant storage (S3, Azure Health Data Services) или децентрализованном хранилище (Ceramic, Filecoin с шифрованием)
Шифрование и управление ключами
Ключевая идея: данные зашифрованы симметричным ключом (AES-256). Этот data encryption key (DEK) зашифрован публичным ключом пациента. Для предоставления доступа врачу DEK перешифровывается публичным ключом врача (proxy re-encryption).
Медицинская запись → зашифровать AES-256 → зашифрованные данные (в IPFS/Filecoin)
DEK → зашифровать публичным ключом пациента → encrypted DEK (в смарт-контракте)
Доступ врача:
encrypted DEK → proxy re-encryption → encrypted DEK for doctor
Врач расшифровывает своим приватным ключом → DEK → расшифровывает данные
Это лучший подход, потому что proxy re-encryption позволяет делегировать доступ без раскрытия оригинального ключа. Пациент выдает врачу грант доступа на конкретный период и конкретные записи — все через один смарт-контракт.
Как работает proxy re-encryption для делегирования доступа?
Библиотеки (Threshold Network, NuCypher) реализуют схемы PRE, которые на 40% снижают вычислительную нагрузку по сравнению с полным перешифрованием, как показано в исследованиях Threshold Network. Это ключевой элемент для масштабирования: при 10 000 записей на пациента время делегирования доступа составляет менее секунды.
Интеграция с существующими EMR-системами
Больницы используют Epic, Cerner, Meditech — все поддерживают HL7 FHIR. Мы разрабатываем адаптер, который через FHIR API получает данные, конвертирует в стандартный FHIR JSON, шифрует и публикует на блокчейне. Врачи продолжают работать в привычном интерфейсе, а блокчейн-часть работает незаметно.
| Компонент | Технология |
|---|---|
| Smart contracts | Solidity + OpenZeppelin |
| Шифрование | AES-256-GCM + RSA или ECIES |
| Proxy re-encryption | Threshold Network / NuCypher |
| DID | did:ethr + DID Resolver |
| Хранилище | IPFS + Filecoin или AWS S3 HIPAA |
| FHIR | HAPI FHIR (Java) или medplum (TypeScript) |
| Indexing | The Graph |
Smart contract архитектура
EHR Registry (Electronic Health Records)
contract EHRRegistry {
struct MedicalRecord {
bytes32 contentHash; // IPFS CID или hash зашифрованных данных
string storageURI; // URI для получения данных
bytes encryptedDEK; // DEK зашифрованный ключом пациента
uint256 timestamp;
address createdBy; // адрес медицинского учреждения
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;
// Права доступа: patientId => granteeAddress => AccessGrant
mapping(bytes32 => mapping(address => AccessGrant)) private accessGrants;
struct AccessGrant {
bytes encryptedDEK; // DEK перешифрованный ключом grantee
uint256 expiresAt;
RecordType[] allowedTypes; // пустой массив = все типы
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;
}
// Append-only log
AuditEntry[] public auditLog;
mapping(bytes32 => uint256[]) public patientAuditLog; // patientId => indices
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)
Пациент может давать информированное согласие на конкретные типы записей и сроки. Смарт-контракт консилиума проверяет, что все стороны одобрили доступ перед передачей ключа. Это обеспечивает compliance с GDPR и HIPAA без централизованного хранилища согласий.Соответствие регуляторным требованиям
GDPR и право на удаление
Блокчейн immutable, но данные off-chain можно удалить. Паттерн: при удалении уничтожаем данные в хранилище, DEK становится недоступен — зашифрованный blob в IPFS бесполезен. On-chain остается только hash и метаданные — не персональные данные по определению, согласно рекомендациям рабочей группы Article 29.
function deactivateRecord(bytes32 patientId, bytes32 recordId)
external onlyPatient(patientId)
{
records[patientId][recordId].active = false;
emit RecordDeactivated(patientId, recordId);
}
HL7 FHIR совместимость
Данные хранятся в формате FHIR JSON. FHIR ресурсы: Patient, Observation, DiagnosticReport, Condition, MedicationRequest. При доступе: расшифровать → parse → преобразовать.
DID (Decentralized Identifiers)
Пациенты и провайдеры идентифицируются через DID (W3C стандарт). Это обеспечивает key rotation (смена ключей без потери identity) и cross-system interoperability.
did:ethr:0x742d35... — DID на основе Ethereum адреса
did:web:hospital.example.com — DID на основе domain
did:key:z6Mkf... — DID на основе public key
Пошаговый план внедрения
- Аудит инфраструктуры — анализ текущих EMR, compliance gaps, выбор блокчейн-платформы.
- Архитектура и моделирование — DID scheme, FHIR mapping, threat model.
- Разработка смарт-контрактов — Registry, Consent, Audit.
- Интеграция шифрования — key management, proxy re-encryption.
- Подключение хранилища — IPFS/Filecoin, FHIR parser.
- Интеграция с EMR — FHIR API adapter.
- Фронтенд — порталы для пациента и врача (React + RainbowKit).
- Безопасность и аудит — формальная верификация контрактов, penetration test.
- Деплой и обучение — staging, training, 6 месяцев поддержки.
По нашим оценкам, внедрение такой системы позволяет клинике сэкономить от $200,000 в год на административных расходах. Типовой бюджет для клиники с 5000 пациентов составляет от $150,000 до $250,000. По сравнению с традиционными централизованными EHR, блокчейн-решение в 3 раза снижает нагрузку на административный персонал и на 70% сокращает время получения доступа к истории болезни. Получите консультацию по архитектуре — оценим ваш проект за 2 дня, подберем стек и подготовим детальный roadmap.
Что входит в работу
Мы предоставляем полный цикл разработки и внедрения:
- Архитектурная документация (threat model, GDPR compliance report)
- Смарт-контракты с открытым исходным кодом (аудит безопасности включён)
- Backend-сервисы шифрования и интеграции с FHIR
- Порталы для пациента и провайдера (React + RainbowKit)
- Доступ к staging-окружению и обучение администраторов
- 6 месяцев поддержки после запуска
Свяжитесь — мы подготовим коммерческое предложение с точными цифрами.
Сроки и стоимость
| Фаза | Содержание | Срок |
|---|---|---|
| Архитектура | DID scheme, FHIR mapping, threat model | 1-2 нед |
| Core contracts | Registry, consent, audit | 3-4 нед |
| Encryption layer | Key management, proxy re-encryption | 2-3 нед |
| Storage integration | IPFS/Filecoin, FHIR parser | 2-3 нед |
| Provider integration | FHIR API adapter | 2-4 нед |
| Frontend | Patient portal, provider UI | 3-4 нед |
| Security audit | Контракты + crypto implementation | 2-4 нед |
Полная production-ready система: 4-6 месяцев. MVP без proxy re-encryption и FHIR интеграции: 2-3 месяца. Стоимость рассчитывается индивидуально под вашу инфраструктуру.







