Розробка системи верифікації лікарських препаратів на блокчейні

Проєктуємо та розробляємо блокчейн-рішення повного циклу: від архітектури смарт-контрактів до запуску DeFi-протоколів, NFT-маркетплейсів та криптобірж. Аудит безпеки, токеноміка, інтеграція з наявною інфраструктурою.
Показано 1 з 1Усі 1306 послуг
Розробка системи верифікації лікарських препаратів на блокчейні
Складний
~1-2 тижні
Часті запитання

Напрямки блокчейн-розробки

Етапи блокчейн-розробки

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1284
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1196
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    901
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1119
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    586
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    853

Розробка системи верифікації лекарських препаратів на блокчейні

Фальсифіковані лікарства — це не абстрактна проблема. ВОЗ оцінює частку поддільних препаратів на ринках країн, що розвиваються, у 10-30%. В Євросоюзі Директива 2011/62/EU (Falsified Medicines Directive) зобов'язує виробників розміщувати унікальний серійний номер та код верифікації на кожній упаковці. Блокчейн дає конкретне преимущество над централізованими реєстрами: виробник, дистрибютор та аптека не довіряють один одному — їм потрібен загальний immutable ledger без єдиного адміністратора.

Реальні впровадження: MediLedger (найбільший фармацевтичний консорціум у США, Pfizer, Genentech, AmerisourceBergen), Track and Trace EU система, пілоти на Hyperledger Fabric в Індії та Китаї. Архітектурні уроки з цих систем дозволяють не вигадувати велосипед.

Вимоги до даних та нормативний контекст

Серіалізація даних на упаковці

Стандарт GS1 DataMatrix на фарм упаковці кодує чотири атрибути (DSCSA в США, FMD в EU):

  • GTIN (Global Trade Item Number) — ідентифікатор продукту
  • Lot number — номер партії
  • Expiry date — термін придатності
  • Serial number — унікальний для кожної упаковки
GS1 Application Identifiers:
(01)04150753537323   — GTIN
(17)270131           — Expiry (YYMMDD)
(10)LOT-A4581        — Lot number
(21)000123456789     — Serial number

DataMatrix scannable string:
]d201041507535373232702310100101-A45812100123456789

Серійний номер + GTIN = унікальний ключ для on-chain запису. Всі інші дані — атрибути цього ключа.

Приватність даних: zero-knowledge або приватні канали

Критична архітектурна проблема. Конкуруючі фармацевтичні компанії не хочуть розкривати обсяги продаж, логістичні партнери не розкривають маршрути. On-chain дані публічні за замовчуванням. Рішення:

Hyperledger Fabric приватні колекції даних. Консорціумний blockchain з приватними каналами: дані конкретної транзакції видимі тільки учасникам каналу, у публічному ledger зберігається тільки хеш. Це стандартне рішення для корпоративних консорціумів (MediLedger використовує цей підхід).

ZK proofs для верифікації. Аптека доводить, що препарат з легітимного ланцюга поставок без розкриття конкретного дистрибютора:

// Verifier контракт: перевіряє ZK proof легітимності
contract DrugVerifier {
    IVerifier public zkVerifier; // Groth16 або PLONK verifier
    
    // Merkle root всіх легітимних серійних номерів (оновлюється регулятором)
    bytes32 public legitimacyRoot;
    
    // Аптека: доповісти що S/N у легітимному дереві без розкриття S/N
    function verifyDrug(
        bytes calldata proof,
        uint256[2] calldata publicInputs // [nullifier, merkle_root]
    ) external view returns (bool) {
        // publicInputs[0] — nullifier (не повторити верифікацію тієї ж упаковки)
        // publicInputs[1] — повинен збігатися з legitimacyRoot
        require(publicInputs[1] == uint256(legitimacyRoot), "Wrong root");
        return zkVerifier.verifyProof(proof, publicInputs);
    }
}

Chain of Custody: трансфер власності

Кожне переміщення упаковки — подія transfer custody. Виробник → дистрибютор → аптека → пацієнт. Кожен крок повинен бути верифікований обома сторонами (передаючою та приймаючою).

contract DrugTraceability {
    enum Status { MANUFACTURED, IN_TRANSIT, RECEIVED, DISPENSED, RECALLED }
    
    struct DrugUnit {
        bytes32 serialHash;     // keccak256(GTIN + serial) — не зберігаємо в открито
        address currentHolder;
        Status status;
        uint256 manufacturedAt;
        uint256 expiryTimestamp;
        bool recalled;
    }
    
    mapping(bytes32 => DrugUnit) public drugs; // serialHash => DrugUnit
    mapping(bytes32 => address[]) public custodyHistory;
    
    // Виробник реєструє упаковку
    function manufacture(
        bytes32 serialHash,
        uint256 expiryTimestamp,
        bytes32 lotMerkleRoot  // Merkle root для верифікації lot атрибутів
    ) external onlyManufacturer {
        require(drugs[serialHash].manufacturedAt == 0, "Already registered");
        drugs[serialHash] = DrugUnit({
            serialHash: serialHash,
            currentHolder: msg.sender,
            status: Status.MANUFACTURED,
            manufacturedAt: block.timestamp,
            expiryTimestamp: expiryTimestamp,
            recalled: false
        });
        custodyHistory[serialHash].push(msg.sender);
        emit Manufactured(serialHash, msg.sender, block.timestamp);
    }
    
    // Двусторонній трансфер: ініціює відправник, підтверджує одержувач
    mapping(bytes32 => address) public pendingTransfer; // serialHash => запропонований одержувач
    
    function initiateTransfer(bytes32 serialHash, address recipient) external {
        require(drugs[serialHash].currentHolder == msg.sender, "Not holder");
        pendingTransfer[serialHash] = recipient;
        emit TransferInitiated(serialHash, msg.sender, recipient);
    }
    
    function confirmTransfer(bytes32 serialHash) external {
        require(pendingTransfer[serialHash] == msg.sender, "Not recipient");
        drugs[serialHash].currentHolder = msg.sender;
        custodyHistory[serialHash].push(msg.sender);
        delete pendingTransfer[serialHash];
        emit TransferConfirmed(serialHash, msg.sender);
    }
    
    // Відзив препарату
    function recall(bytes32 serialHash, string calldata reason) external onlyRegulator {
        drugs[serialHash].recalled = true;
        emit Recalled(serialHash, reason, block.timestamp);
    }
}

Інтеграція з фізичним світом

Захищена від підробок упаковка + NFC/QR

Блокчейн корисний тільки якщо зв'язок між фізичною упаковкою та on-chain записом надійний. Три рівні захисту:

QR код з DataMatrix — мінімум, відповідає FMD. Вразливість: QR можна скопіювати та наклеїти на поддільний препарат. Допомагає від грубих підробок, але не від складних атак.

NFC з криптографічним challenge-response (наприклад, NXP NTAG 424 DNA). Чип містить приватний ключ у захищеній пам'яті (не видобувній). При скануванні генерує підписаний challenge — неможливо клонувати без фізичного доступу до чипа. Виробник при випуску реєструє публічний ключ чипа on-chain.

// Верифікація NFC чипа (reader side)
async function verifyNFCChip(
  chipPublicKey: string,
  challenge: Buffer,
  signature: Buffer
): Promise<boolean> {
  // Верифікуємо підпис чипа
  const isValidSignature = await verifyECDSA(chipPublicKey, challenge, signature)
  
  // Перевіряємо реєстрацію публічного ключа on-chain
  const isRegistered = await contract.isChipRegistered(chipPublicKey)
  
  // Перевіряємо що чип не у списку recalled
  const isRecalled = await contract.isRecalled(chipPublicKey)
  
  return isValidSignature && isRegistered && !isRecalled
}

Голографічні мітки + блокчейн — гібридний підхід для ринків без NFC інфраструктури.

Off-chain дані та IPFS

Повна документація партії (Certificate of Analysis, результати тестування) не помещається в блокчейн. Стандартний паттерн:

  • On-chain: bytes32 documentsIPFSHash — Merkle root або IPFS CID документів
  • Off-chain: IPFS зберігає документи
  • Верифікатор: отримує документи через IPFS, перевіряє хеш on-chain
struct BatchRecord {
    bytes32 lotNumber;
    address manufacturer;
    uint256 productionDate;
    bytes32 coaIpfsHash;      // Certificate of Analysis
    bytes32 testResultsHash;  // Результати QC тестування
    uint32  quantity;
}

Вибір блокчейну для фармацевтики

Параметр Публічний (Ethereum/Polygon) Permissioned (Hyperledger Fabric)
Доступність даних Публічна, всі бачать Приватні канали
Учасники Будь-які гаманці KYC'd члени консорціуму
Вартість транзакцій Gas (оптимізувати) Практично безплатно
Compliance Складніше (публічність) Легше
Децентралізація Висока Консорціум
Швидкість L2: ~2 sec ~1 sec

Рекомендація: для B2B консорціуму виробників/дистрибюторів — Hyperledger Fabric (модель MediLedger). Для consumer-facing верифікації (пацієнт перевіряє препарат) — публічний blockchain (Polygon або Arbitrum для вартості газу) з privacy-preserving ZK перевіркою.

Hyperledger Fabric: ключові концепції

// Chaincode (смарт-контракт) на Go
package main

import (
    "github.com/hyperledger/fabric-contract-api-go/contractapi"
)

type DrugContract struct {
    contractapi.Contract
}

func (c *DrugContract) RegisterDrug(ctx contractapi.TransactionContextInterface,
    serialHash, gtin, lot, expiry string) error {
    
    // Перевіряємо що викликає авторизований виробник
    mspID, _ := ctx.GetClientIdentity().GetMSPID()
    if !isAuthorizedManufacturer(mspID) {
        return fmt.Errorf("unauthorized: %s", mspID)
    }
    
    // Перевіряємо дублікат
    existing, _ := ctx.GetStub().GetState(serialHash)
    if existing != nil {
        return fmt.Errorf("drug %s already registered", serialHash)
    }
    
    drug := Drug{
        SerialHash: serialHash,
        GTIN:       gtin,
        Lot:        lot,
        Expiry:     expiry,
        Holder:     mspID,
        Status:     "MANUFACTURED",
        Timestamp:  time.Now().Unix(),
    }
    
    drugJSON, _ := json.Marshal(drug)
    return ctx.GetStub().PutState(serialHash, drugJSON)
}

Нормативні інтерфейси

Регулятор (FDA, EMA, локальний орган) повинен мати доступ на читання та право відзиву. В Hyperledger Fabric: окремий канал між виробниками та регулятором. У публічному blockchain: on-chain роль через AccessControl.

// OpenZeppelin AccessControl для ролей
bytes32 public constant MANUFACTURER_ROLE = keccak256("MANUFACTURER_ROLE");
bytes32 public constant DISTRIBUTOR_ROLE = keccak256("DISTRIBUTOR_ROLE");
bytes32 public constant REGULATOR_ROLE = keccak256("REGULATOR_ROLE");

// Тільки регулятор може відозвати
function recall(bytes32 serialHash, string calldata reason) 
    external onlyRole(REGULATOR_ROLE) { ... }

Процес розробки

Нормативний аналіз (1-2 тижні). Визначаємо застосовні стандарти: DSCSA (США), FMD (EU), локальні вимоги. Фармацевтичні системи підпадають під вимоги до валідованого софту (FDA 21 CFR Part 11) — потрібна документація та матриця відстеження вимог.

Архітектурний дизайн (1-2 тижні). Вибір blockchain (permissioned vs public), модель приватності, схема даних GS1, NFC/QR стратегія. Проектуємо схему учасників консорціуму та governance.

Розробка смарт-контрактів (4-6 тижнів). Контракти реєстрації, transfer custody, recall. Розширене тестування: edge cases (упаковка після recall, expired drug transfer, дублікат серійних номерів).

Backend інтеграція (4-8 тижнів). API для інтеграції з ERP системами виробників (SAP, Oracle Pharma), WMS дистрибюторів. Batch import для реєстрації тисяч серійних номерів одночасно.

Hardware інтеграція (2-4 тижні). SDK для сканерів DataMatrix, NFC readers, інтеграція з існуючим складським обладнанням. Offline mode для слабозв'язаних мереж (аптеки у віддалених регіонах).

Аудит та валідація (4-6 тижнів). Аудит смарт-контрактів (обов'язковий — дані про лікарства впливають на здоров'я людей). Документація валідації для regulatory compliance (IQ/OQ/PQ по GAMP5).

Орієнтири за термінами

MVP для пілота з одним виробником та однією аптечною мережею — 3-4 місяці. Production система для консорціуму з повним regulatory compliance — 9-15 місяців. Складність проекту визначається не blockchain частиною, а інтеграцією з legacy ERP системами та regulatory валідацією.