Every day, a pharmacy receives hundreds of packages with DataMatrix codes. But who guarantees that the serial number on the box is original, not copied from a counterfeit? Without a shared registry, verification turns into a chain of phone calls and paper acts. We solve this problem with blockchain verification of pharmaceuticals.
We design systems where the manufacturer, distributor, and pharmacy work with a single immutable ledger. Instead of a centralized registry — a consortium where each participant sees only their own data, and authenticity is confirmed cryptographically. Blockchain verification is 10 times faster than manual procedures and reduces operational costs by up to 25%. For an average pharma manufacturer, savings on compliance audits reach 15–20% annually. In monetary terms, this is hundreds of thousands of rubles per year for a medium-sized enterprise: reduced costs for manual reconciliation, fines for recall violations, and losses from counterfeits. Over a year, this savings amounts to a significant sum — on the order of several hundred thousand rubles.
According to the World Health Organization, the share of counterfeit drugs in some regions reaches up to 30%. The EU Directive (FMD) requires a unique serial number on each package. Real implementations like MediLedger (Pfizer, Genentech) confirm: blockchain is a working tool for pharmaceutical verification.
Example architecture for a consortium of 5 participants
Each participant (manufacturer, distributor, pharmacy, regulator, auditor) has their own private channel in Hyperledger Fabric. Smart contracts in Go handle registration, transfer, and recall operations. Data is serialized according to GS1-128. For consumer verification, a separate public smart contract on Polygon with ZK-proofs is used.Data Requirements: GS1 Serialization
The GS1 DataMatrix standard encodes four attributes: GTIN, batch number, expiration date, and serial number. The unique on-chain key is the combination of GTIN and serial number. For a consortium of 10+ participants, Hyperledger Fabric processes 500+ transactions per second — 5 times faster than public networks.
Why Blockchain is Necessary for Drug Verification?
A centralized database of one participant does not inspire trust among others. Blockchain provides a shared registry that no single party can alter. This is critical for batch recalls and auditing. Hyperledger Fabric private data collections ensure that competitors see only hashes, not supply details.
Privacy: Zero-Knowledge or Private Channels
Competing pharma companies do not disclose sales volumes. Solutions:
- Hyperledger Fabric private data collections — data visible only to channel participants, on the public ledger only the hash.
- ZK-proofs — a pharmacy proves legitimacy without disclosing the supplier.
contract DrugVerifier {
IVerifier public zkVerifier;
bytes32 public legitimacyRoot;
function verifyDrug(
bytes calldata proof,
uint256[2] calldata publicInputs
) external view returns (bool) {
require(publicInputs[1] == uint256(legitimacyRoot), "Wrong root");
return zkVerifier.verifyProof(proof, publicInputs);
}
}
Chain of Custody: Two-Way Transfer
Each movement is a transfer custody event signed by both parties.
contract DrugTraceability {
enum Status { MANUFACTURED, IN_TRANSIT, RECEIVED, DISPENSED, RECALLED }
struct DrugUnit {
bytes32 serialHash;
address currentHolder;
Status status;
uint256 manufacturedAt;
uint256 expiryTimestamp;
bool recalled;
}
mapping(bytes32 => DrugUnit) public drugs;
function manufacture(bytes32 serialHash, uint256 expiryTimestamp, bytes32 lotMerkleRoot) external onlyManufacturer {
require(drugs[serialHash].manufacturedAt == 0, "Already registered");
drugs[serialHash] = DrugUnit(serialHash, msg.sender, Status.MANUFACTURED, block.timestamp, expiryTimestamp, false);
emit Manufactured(serialHash, msg.sender, block.timestamp);
}
function initiateTransfer(bytes32 serialHash, address recipient) external {
require(drugs[serialHash].currentHolder == msg.sender, "Not holder");
pendingTransfer[serialHash] = recipient;
}
function confirmTransfer(bytes32 serialHash) external {
require(pendingTransfer[serialHash] == msg.sender, "Not recipient");
drugs[serialHash].currentHolder = msg.sender;
delete pendingTransfer[serialHash];
}
function recall(bytes32 serialHash, string calldata reason) external onlyRegulator {
drugs[serialHash].recalled = true;
emit Recalled(serialHash, reason, block.timestamp);
}
}
How Private Verification with ZK-Proofs Works?
The pharmacy receives from the distributor a proof that the serial number is legitimate, checks it on-chain — and does not disclose the number itself. This prevents reuse of the proof and complies with privacy-by-design.
Integration with the Physical World
Tamper-Evident Packaging + NFC/QR
- QR with DataMatrix — basic level, vulnerable to copying.
- NFC with challenge-response (NXP NTAG 424 DNA) — chip with private key, impossible to clone without physical access. Public key registered on-chain.
- Holographic labels + blockchain — for markets without NFC infrastructure.
Off-Chain Data (IPFS)
Full batch documents (CoA, QC protocols) are stored in IPFS, on-chain — the hash. The verifier obtains documents and checks the hash.
Blockchain Selection for Pharma
| Parameter | Public (Ethereum/Polygon) | Permissioned (Hyperledger Fabric) |
|---|---|---|
| Data availability | Public, everyone sees | Private channels |
| Participants | Any wallets | KYC'd consortium participants |
| Transaction cost | Gas (optimize) | Virtually free |
| Regulatory compliance | Harder (public) | Easier |
| Decentralization | High | Consortium |
| Speed | L2: ~2 sec | ~1 sec |
Recommendation: B2B consortium — Hyperledger Fabric (MediLedger model). Consumer-facing — public L2 with ZK.
Hyperledger Fabric: Chaincode in 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)
}
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)
}
Regulatory Interfaces
The regulator (FDA, EMA) gets read access and the right to recall. In Fabric — a separate channel; in public blockchain — through AccessControl with roles MANUFACTURER_ROLE and REGULATOR_ROLE.
Development Process
- Regulatory Analysis (1–2 weeks): Determine applicable standards, prepare trace matrix.
- Architectural Design (1–2 weeks): Blockchain selection, privacy scheme, GS1 schema, NFC/QR integration.
- Smart Contract Development (4–6 weeks): Registration, transfer, recall; edge-case testing.
- Backend Integration (4–8 weeks): API for ERP, WMS; batch import of serial numbers.
- Hardware Integration (2–4 weeks): SDK for scanners, NFC; offline mode.
- Audit and Validation (4–6 weeks): Smart contract audit; IQ/OQ/PQ per GAMP5.
What's Included
- Architectural documents and blockchain platform selection.
- Smart contracts (Solidity/Go) with audit.
- API for ERP and WMS integration.
- Mobile app for NFC/QR scanning.
- Documentation for regulatory validation (21 CFR Part 11).
- Client team training and pilot support.
Timeline Estimates
| Phase | Duration |
|---|---|
| MVP (1 manufacturer + 1 pharmacy) | 3–4 months |
| Production system for consortium | 9–15 months |
Timelines depend on participant count and integration complexity with legacy systems. Cost is calculated individually.
Our engineers are certified in Hyperledger and have 12+ years of blockchain development experience, with 40+ projects in pharma. We guarantee compliance with FMD and DSCSA standards. Contact us for a project assessment — we will prepare a proposal within 1 week. Order an audit of your current verification process — we will propose blockchain optimization with a pilot within 2 weeks.







