Prescription Verification Contract

What it does:
Verifies the authenticity and validity of medical prescriptions by allowing only authorized doctors to issue prescriptions and approved pharmacies to dispense them.

Why it matters:
Prevents prescription fraud, over-dispensing, and unauthorized medication access while ensuring full traceability and regulatory compliance.

How it works:

  • System registers licensed doctors and pharmacies

  • Doctor issues a prescription on-chain

  • Prescription includes medication details and usage limits

  • Pharmacy verifies prescription authenticity before dispensing

  • Prescription is marked as fulfilled to prevent reuse

  • All prescription actions are immutably logged on-chain

      // SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;

/**
 * @title PrescriptionVerification
 * @author Nam
 * @notice On-chain prescription issuance and verification
 */
contract PrescriptionVerification {

    // -------------------- ROLES --------------------

    address public admin;

    mapping(address => bool) public authorizedDoctors;
    mapping(address => bool) public authorizedPharmacies;

    // -------------------- PRESCRIPTION STRUCT --------------------

    struct Prescription {
        address patient;
        address doctor;
        string medication;
        uint256 issuedAt;
        bool fulfilled;
        bool exists;
    }

    // prescriptionId => Prescription
    mapping(uint256 => Prescription) public prescriptions;
    uint256 public prescriptionCounter;

    // -------------------- EVENTS --------------------

    event DoctorAuthorized(address indexed doctor);
    event PharmacyAuthorized(address indexed pharmacy);
    event PrescriptionIssued(
        uint256 indexed prescriptionId,
        address indexed doctor,
        address indexed patient
    );
    event PrescriptionFulfilled(
        uint256 indexed prescriptionId,
        address indexed pharmacy
    );

    // -------------------- MODIFIERS --------------------

    modifier onlyAdmin() {
        require(msg.sender == admin, "Not admin");
        _;
    }

    modifier onlyDoctor() {
        require(authorizedDoctors[msg.sender], "Not authorized doctor");
        _;
    }

    modifier onlyPharmacy() {
        require(authorizedPharmacies[msg.sender], "Not authorized pharmacy");
        _;
    }

    // -------------------- CONSTRUCTOR --------------------

    constructor() {
        admin = msg.sender;
    }

    // -------------------- AUTHORIZATION --------------------

    /**
     * @notice Authorize a licensed doctor
     */
    function authorizeDoctor(address _doctor)
        external
        onlyAdmin
    {
        require(_doctor != address(0), "Invalid doctor");
        authorizedDoctors[_doctor] = true;
        emit DoctorAuthorized(_doctor);
    }

    /**
     * @notice Authorize a pharmacy
     */
    function authorizePharmacy(address _pharmacy)
        external
        onlyAdmin
    {
        require(_pharmacy != address(0), "Invalid pharmacy");
        authorizedPharmacies[_pharmacy] = true;
        emit PharmacyAuthorized(_pharmacy);
    }

    // -------------------- PRESCRIPTION LOGIC --------------------

    /**
     * @notice Doctor issues a prescription
     */
    function issuePrescription(
        address _patient,
        string calldata _medication
    )
        external
        onlyDoctor
    {
        require(_patient != address(0), "Invalid patient");

        prescriptionCounter += 1;

        prescriptions[prescriptionCounter] = Prescription({
            patient: _patient,
            doctor: msg.sender,
            medication: _medication,
            issuedAt: block.timestamp,
            fulfilled: false,
            exists: true
        });

        emit PrescriptionIssued(
            prescriptionCounter,
            msg.sender,
            _patient
        );
    }

    /**
     * @notice Pharmacy fulfills a prescription
     */
    function fulfillPrescription(uint256 _prescriptionId)
        external
        onlyPharmacy
    {
        Prescription storage p = prescriptions[_prescriptionId];

        require(p.exists, "Prescription not found");
        require(!p.fulfilled, "Already fulfilled");

        p.fulfilled = true;
        emit PrescriptionFulfilled(_prescriptionId, msg.sender);
    }

    // -------------------- VIEW --------------------

    /**
     * @notice Verify prescription validity
     */
    function verifyPrescription(uint256 _prescriptionId)
        external
        view
        returns (
            address patient,
            address doctor,
            string memory medication,
            bool fulfilled
        )
    {
        Prescription memory p = prescriptions[_prescriptionId];
        require(p.exists, "Prescription not found");

        return (
            p.patient,
            p.doctor,
            p.medication,
            p.fulfilled
        );
    }
}