基于智能合约的医患关系合约实现技术咨询
Alright, let's figure out how to build this doctor-patient smart contract exactly as you described. I'll walk you through the core logic, code structure, and explain each part so you can tweak it to fit your needs.
Core Design Breakdown
First, let's map out the key flows you need:
- Patients submit their personal info (name, age, condition) and trigger a request for doctor assignment (your
createDoctor()function) - Authorized doctors can assign a specific attending physician to the patient
- The assigned physician can update the patient's condition later
Here's a complete Solidity implementation that covers all these steps, with built-in access control to keep things secure:
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract DoctorPatientContract { // Struct to store all patient-related data struct Patient { string name; uint age; string initialCondition; address assignedDoctor; string updatedCondition; bool isDoctorAssigned; } // Track patients by their wallet address mapping(address => Patient) public patients; // Track which addresses are authorized to act as doctors mapping(address => bool) public isAuthorizedDoctor; // Contract owner (for managing doctor authorization) address public contractOwner; // Events to track contract activity (great for frontend integration) event PatientRequestSent(address indexed patientAddress, string name, uint age, string condition); event PhysicianAssigned(address indexed patientAddress, address indexed attendingDoctor); event PatientConditionUpdated(address indexed patientAddress, string newCondition); constructor() { contractOwner = msg.sender; } // ------------------------------ // Patient-side functions // ------------------------------ // This is your `createDoctor()` function - renaming for clarity, but you can keep the original name function createDoctor(string memory _name, uint _age, string memory _condition) public { // Prevent duplicate submissions from the same patient require(bytes(patients[msg.sender].name).length == 0, "You've already submitted your info!"); // Store the patient's data patients[msg.sender] = Patient({ name: _name, age: _age, initialCondition: _condition, assignedDoctor: address(0), updatedCondition: "", isDoctorAssigned: false }); // Emit event for external systems to track emit PatientRequestSent(msg.sender, _name, _age, _condition); } // ------------------------------ // Admin/Doctor-side functions // ------------------------------ // Only the contract owner can authorize new doctors function authorizeDoctor(address _doctorAddress) public onlyOwner { isAuthorizedDoctor[_doctorAddress] = true; } // Authorized doctors can assign an attending physician to a patient function assignAttendingPhysician(address _patientAddress, address _attendingDoctor) public onlyAuthorized { Patient storage targetPatient = patients[_patientAddress]; // Validate the patient exists and hasn't been assigned yet require(bytes(targetPatient.name).length != 0, "This patient hasn't submitted any info!"); require(!targetPatient.isDoctorAssigned, "This patient already has a doctor!"); // Ensure the attending physician is an authorized doctor require(isAuthorizedDoctor[_attendingDoctor], "The address you're assigning isn't an authorized doctor!"); // Update the patient's assignment targetPatient.assignedDoctor = _attendingDoctor; targetPatient.isDoctorAssigned = true; emit PhysicianAssigned(_patientAddress, _attendingDoctor); } // Only the assigned attending physician can update the patient's condition function updatePatientCondition(address _patientAddress, string memory _newCondition) public { Patient storage targetPatient = patients[_patientAddress]; // Validate the caller is the assigned doctor require(targetPatient.assignedDoctor == msg.sender, "Only the assigned doctor can update this patient's condition!"); require(targetPatient.isDoctorAssigned, "This patient hasn't been assigned a doctor yet!"); // Update the condition targetPatient.updatedCondition = _newCondition; emit PatientConditionUpdated(_patientAddress, _newCondition); } // ------------------------------ // Access control modifiers // ------------------------------ modifier onlyOwner() { require(msg.sender == contractOwner, "Only the contract owner can call this function!"); _; } modifier onlyAuthorized() { require(isAuthorizedDoctor[msg.sender], "Only authorized doctors can call this function!"); _; } }
Key Logic Explanations
- Data Storage: We use a
Patientstruct to bundle all relevant patient data, and map it to the patient's wallet address for easy lookup. - Access Control: The
onlyOwnerandonlyAuthorizedmodifiers ensure that only the right people can perform sensitive actions (like authorizing doctors or assigning physicians). - Event Emission: Events let external systems (like a frontend dashboard) track when patients submit requests, doctors are assigned, or conditions are updated.
- Validation Checks: Every function includes checks to prevent invalid actions (like duplicate patient submissions or unauthorized condition updates).
Customization Tips
- If you don't need a separate "authorized doctor" role (e.g., patients can directly choose their doctor), you can remove the
isAuthorizedDoctormapping and adjust theassignAttendingPhysicianfunction to let patients assign their own doctor. - For large or complex condition descriptions, consider storing the actual text on IPFS and only saving the IPFS hash in the contract to save gas costs.
- Add functions to let patients or doctors retrieve full patient records easily (the existing
patientsmapping is public, but you could add a helper function to return all fields in one call).
内容的提问来源于stack exchange,提问作者lokesh
相关产品推荐
相关产品推荐

