Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 10

TRƯỜNG ĐẠI HỌC ĐÔNG Á

KHOA CÔNG NGHỆ THÔNG TIN


----------------------

BÁO CÁO KẾT THÚC MÔN


LẬP TRÌNH ỨNG DỤNG PHÂN TÁN

GIẢNG VIÊN: TS. Đỗ Sính


NHÓM: 9
SVTH: 1. Phan Khắc Điền Trang (Nhóm trưởng)
2. Huỳnh Thị Kim Ngân
3. Dương Bá Thắng
LỚP: ST21A1A

KHÓA: 2021 – 2025

Đà Nẵng, 12/2023
MỤC LỤC
BẢNG PHÂN CÔNG.................................................................................................................................3
TÓM TẮT CHỨC NĂNG...........................................................................................................................4
GIẢI THÍCH CODE....................................................................................................................................5
BẢNG PHÂN CÔNG
Tên thành viên IDSV Phân công Mức độ hoàn
thành

Phan Khắc Điền Trang 93190 Làm báo cáo, 100 %


quay video, lên ý
tưởng, code bài,
giải thích code
Huỳnh Thị Kim Ngân 93176 Làm silde, code 100 %
bài, lên ý tưởng,
giải thích code
Dương Bá Thắng 93152 Code bài, lên ý 100 %
tưởng, hỗ trợ làm
báo cáo, giải thích
code
TÓM TẮT CHỨC NĂNG
- Quản lý Thông Tin Bệnh Nhân:
Hợp đồng có khả năng lưu trữ thông tin của mỗi bệnh nhân, bao gồm tên, ngày
tháng năm sinh, nhóm máu, thông tin liên hệ, và tình trạng sức khỏe.
- Quản Lý Quyền Truy Cập:
Cung cấp cơ chế quản lý quyền truy cập thông tin. Chỉ có chủ sở hữu hợp đồng và
những người được ủy quyền mới có thể thực hiện các thao tác như đăng ký, cập nhật,
xóa bệnh nhân và cấp quyền ủy quyền.
- Sự Kiện (Events):
Sử dụng sự kiện để thông báo về các sự kiện quan trọng như việc đăng ký bệnh
nhân mới, cập nhật thông tin, xóa bệnh nhân, cấp quyền ủy quyền, và thu hồi quyền
ủy quyền. Điều này giúp theo dõi lịch sử hoạt động của hợp đồng.
- Quản Lý Quyền Ủy Quyền:
Hợp đồng có các hàm để cấp và thu hồi quyền ủy quyền. Điều này cho phép chủ
sở hữu quản lý những người được phép thực hiện các thao tác trên hồ sơ bệnh nhân.
- Hàm Đăng Ký và Cập Nhật:
Cung cấp hàm để đăng ký bệnh nhân mới và cập nhật thông tin của bệnh nhân đã
đăng ký. Những hàm này chỉ có sẵn cho những người được ủy quyền.
- Hàm Xóa Bệnh Nhân:
Chỉ có chủ sở hữu hợp đồng mới có thể xóa bệnh nhân khỏi hệ thống.
- Truy Vấn Thông Tin:
Cung cấp hàm để truy vấn số lượng bệnh nhân đã đăng ký trong hệ thống.
- Modifiers (Điều Kiện):
Sử dụng modifiers để áp đặt điều kiện nhất định, như chỉ chủ sở hữu hoặc những
người được ủy quyền mới có thể thực hiện một số thao tác.
- Constructor (Hàm Khởi Tạo):
Hàm khởi tạo được sử dụng để thiết lập chủ sở hữu là người triển khai hợp đồng.
GIẢI THÍCH CODE
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0; // sử dụng phiên bản từ 0.8.0 trở lên.

contract MedicalRecords { // Khai báo một hợp đồng mới có tên là


MedicalRecords.
address public owner; // Biến owner được khai báo là public, có nghĩa là
// nó có thể được truy cập từ bên ngoài hợp đồng. Biến này lưu trữ địa chỉ
// của chủ sở hữu hợp đồng.

// Contact là một cấu trúc (struct) chứa thông tin liên lạc của một người.
// Có năm trường dữ liệu:
struct Contact {
string addressLine1;// Địa chỉ dòng 1.
string addressLine2;// Địa chỉ dòng 2.
string city; // Thành phố.
string phoneNumber;// Số điện thoại.
string email; // Địa chỉ email.
}

// Patient là một cấu trúc (struct) đại diện cho thông tin của một bệnh
nhân.
// Có năm trường dữ liệu:
struct Patient {
string name;// Tên của bệnh nhân.
string dob; // Ngày tháng năm sinh
string bloodType; // Nhóm máu của bệnh nhân.
Contact contactInfo;// Một trường kiểu Contact chứa thông tin liên lạc
của bệnh nhân.
string healthStatus; // Tình trạng sức khỏe
}

mapping(address => Patient) public patients;


// patients là một bảng ánh xạ (mapping) từ địa chỉ (address)
// của một bệnh nhân đến thông tin chi tiết về bệnh nhân (kiểu Patient).
address[] public patientAddresses;
// patientAddresses là một mảng các địa chỉ (address) của bệnh nhân.
// Điều này có thể được sử dụng để duyệt qua tất cả các bệnh nhân.
mapping(address => bool) public authorizedAddresses;
// authorizedAddresses là một bảng ánh xạ từ địa chỉ (address) đến một
// giá trị boolean, xác định xem địa chỉ đó có được ủy quyền hay không.

event PatientRegistered(address indexed patientAddress, string name);


event PatientRemoved(address indexed patientAddress);
event PatientUpdated(address indexed patientAddress, string field, string
newValue);
event AuthorizationGranted(address indexed authorizedAddress);
event AuthorizationRevoked(address indexed authorizedAddress);
// PatientRegistered: Được kích hoạt khi một bệnh nhân mới được đăng ký.
Chứa địa chỉ và tên của bệnh nhân.
// PatientRemoved: Được kích hoạt khi một bệnh nhân bị xóa khỏi hệ thống.
Chứa địa chỉ của bệnh nhân.
// PatientUpdated: Được kích hoạt khi thông tin của bệnh nhân được cập
nhật. Chứa địa chỉ, trường được cập nhật và giá trị mới của trường.
// AuthorizationGranted: Được kích hoạt khi một địa chỉ được cấp quyền
truy cập. Chứa địa chỉ được cấp quyền.
// AuthorizationRevoked: Được kích hoạt khi một địa chỉ mất quyền truy
cập. Chứa địa chỉ mất quyền.

modifier onlyOwner() { // Modifier này đảm bảo rằng chỉ chủ sở hữu của hợp
đồng mới có thể gọi được hàm chứa modifier này.
require(msg.sender == owner, "Only contract owner can call this
function");
// kiểm tra xem người gọi hàm có phải là chủ sở hữu của hợp đồng
không. Nếu không, hàm sẽ bị ngừng lại và một thông báo lỗi sẽ được hiển thị.
// Nếu không, hàm sẽ bị ngừng lại và một thông báo lỗi sẽ được hiển
thị.
_;
//là nơi mà nội dung của hàm gốc sẽ được thực thi nếu điều kiện của
modifier đúng.
}

modifier onlyAuthorized() { // Modifier này đảm bảo rằng chỉ các địa chỉ
được ủy quyền hoặc chủ sở hữu mới có thể gọi được hàm chứa modifier này.
require(
authorizedAddresses[msg.sender] || msg.sender == owner,
"Not authorized to perform this action"
// kiểm tra xem người gọi hàm có phải là một địa chỉ được ủy quyền
hoặc là chủ sở hữu của hợp đồng không.
// Nếu không, hàm sẽ bị ngừng lại và một thông báo lỗi sẽ được hiển
thị.
);
_;
// là nơi mà nội dung của hàm gốc sẽ được thực thi nếu điều kiện của
modifier đúng.
}

constructor() {
owner = msg.sender;
// Hàm này được gọi khi hợp đồng được triển khai. Nó sẽ đặt chủ sở hữu của
hợp đồng
// là địa chỉ của người triển khai hợp đồng (msg.sender).
}

function grantAuthorization(address _authorizedAddress) external onlyOwner


{
// Hàm này cho phép chủ sở hữu của hợp đồng (onlyOwner modifier đảm
bảo chỉ chủ sở hữu mới có thể gọi được)
// cấp quyền ủy quyền cho một địa chỉ khá
require(_authorizedAddress != owner, "Owner cannot grant authorization
to themselves");
// kiểm tra xem chủ sở hữu có cố gắng cấp quyền ủy quyền cho chính họ
không.
// Nếu có, hàm sẽ dừng lại và hiển thị một thông báo lỗi.
authorizedAddresses[_authorizedAddress] = true;
// thiết lập quyền ủy quyền cho địa chỉ được chỉ định.
emit AuthorizationGranted(_authorizedAddress);
// phát ra một sự kiện để thông báo rằng quyền ủy quyền đã được cấp
cho một địa chỉ cụ thể.
}

function revokeAuthorization(address _authorizedAddress) external


onlyOwner {
// Hàm này cho phép chủ sở hữu của hợp đồng (onlyOwner modifier đảm bảo
chỉ chủ sở hữu mới có thể gọi được)
// thu hồi quyền ủy quyền từ một địa chỉ.
authorizedAddresses[_authorizedAddress] = false;
// thu hồi quyền ủy quyền của địa chỉ được chỉ định.
emit AuthorizationRevoked(_authorizedAddress);
// phát ra một sự kiện để thông báo rằng quyền ủy quyền đã được thu
hồi từ một địa chỉ cụ thể.
}

function registerPatient(
// Hàm registerPatient được thiết kế để đăng ký thông tin của một bệnh
nhân mới vào hệ thống.
string memory _name,
string memory _dob,
string memory _bloodType,
string memory _addressLine1,
string memory _addressLine2,
string memory _city,
string memory _phoneNumber,
string memory _email,
string memory _healthStatus
) external onlyAuthorized {
// modifier Đảm bảo rằng chỉ những địa chỉ được ủy quyền mới có thể gọi
hàm này.
require(bytes(_name).length > 0, "Name must not be empty");
// Đảm bảo tên bệnh nhân không được trống.
require(bytes(_dob).length > 0, "Date of birth must not be empty");
// Đảm bảo ngày tháng năm sinh không được trống.
require(bytes(patients[msg.sender].dob).length == 0, "Patient already
registered");
// Kiểm tra xem bệnh nhân đã được đăng ký trước đó hay chưa bằng cách
kiểm tra xem ngày
// tháng năm sinh đã được lưu trữ cho địa chỉ người gọi hàm chưa.
// để tham chiếu đến thông tin bệnh nhân mới, sẽ được lưu trữ trong
patients mapping
// với khóa là địa chỉ của người gọi hàm.
// Lưu trữ tên, ngày tháng năm sinh, nhóm máu, thông tin liên lạc
// (bao gồm cả địa chỉ dòng 1 và dòng 2, thành phố, số điện thoại,
email), và tình trạng sức khỏe của bệnh nhân.
Patient storage newPatient = patients[msg.sender];
newPatient.name = _name;
newPatient.dob = _dob;
newPatient.bloodType = _bloodType;
newPatient.contactInfo = Contact({
addressLine1: _addressLine1,
addressLine2: _addressLine2,
city: _city,
phoneNumber: _phoneNumber,
email: _email
});
newPatient.healthStatus = _healthStatus;

patientAddresses.push(msg.sender);
// Thêm địa chỉ của bệnh nhân mới vào danh sách các địa chỉ bệnh nhân.

emit PatientRegistered(msg.sender, _name);


// Phát ra sự kiện để thông báo rằng một bệnh nhân mới đã được đăng ký
thành công,
// kèm theo địa chỉ và tên của bệnh nhân.
}

function updatePatientInfo(
// Hàm updatePatientInfo được thiết kế để cập nhật thông tin của một bệnh
nhân đã được đăng ký trong hệ thống.
address _patientAddress,
string memory _name,
string memory _dob,
string memory _bloodType,
string memory _addressLine1,
string memory _addressLine2,
string memory _city,
string memory _phoneNumber,
string memory _email,
string memory _healthStatus
) external onlyAuthorized {
// modifier Đảm bảo rằng chỉ những địa chỉ được ủy quyền mới có thể gọi
hàm này.
require(bytes(_name).length > 0, "Name must not be empty");
// Đảm bảo tên bệnh nhân không được trống.
require(bytes(_dob).length > 0, "Date of birth must not be empty");
// Đảm bảo ngày tháng năm sinh không được trống.
require(bytes(patients[_patientAddress].dob).length > 0, "Patient not
found");
// Kiểm tra xem bệnh nhân cần cập nhật có tồn tại không, dựa trên việc
kiểm tra ngày tháng năm sinh
// đã được lưu trữ cho địa chỉ bệnh nhân cần cập nhật hay không.

Patient storage patient = patients[_patientAddress];


// Lấy ra thông tin của bệnh nhân cần cập nhật từ mapping patients.
// Cập nhật tên, ngày tháng năm sinh, nhóm máu, thông tin liên lạc
// (bao gồm cả địa chỉ dòng 1 và dòng 2, thành phố, số điện thoại,
email),
// và tình trạng sức khỏe của bệnh nhân.
patient.name = _name;
patient.dob = _dob;
patient.bloodType = _bloodType;
patient.contactInfo = Contact({
addressLine1: _addressLine1,
addressLine2: _addressLine2,
city: _city,
phoneNumber: _phoneNumber,
email: _email
});
patient.healthStatus = _healthStatus;

// Phát ra sự kiện để thông báo rằng thông tin của một bệnh nhân đã
được cập nhật thành công,
// kèm theo địa chỉ của bệnh nhân và thông tin cụ thể đã được cập
nhật.
emit PatientUpdated(_patientAddress, "Name", _name);
emit PatientUpdated(_patientAddress, "DateOfBirth", _dob);
emit PatientUpdated(_patientAddress, "BloodType", _bloodType);
emit PatientUpdated(_patientAddress, "AddressLine1", _addressLine1);
emit PatientUpdated(_patientAddress, "AddressLine2", _addressLine2);
emit PatientUpdated(_patientAddress, "City", _city);
emit PatientUpdated(_patientAddress, "PhoneNumber", _phoneNumber);
emit PatientUpdated(_patientAddress, "Email", _email);
emit PatientUpdated(_patientAddress, "HealthStatus", _healthStatus);
}

function removePatient(address _patientAddress) external onlyOwner {


// Hàm removePatient được thiết kế để loại bỏ một bệnh nhân khỏi hệ thống
// modifier Đảm bảo rằng chỉ chủ sở hữu (owner) mới có thể gọi hàm này.
require(msg.sender == owner, "Only owner can remove patients");
// Chỉ chủ sở hữu mới có quyền loại bỏ bệnh nhân.

delete patients[_patientAddress];
// Xóa thông tin của bệnh nhân khỏi mapping patients.

// Duyệt qua mảng patientAddresses để tìm địa chỉ của bệnh nhân cần
xóa và xóa nó.
for (uint256 i = 0; i < patientAddresses.length; i++) {
if (patientAddresses[i] == _patientAddress) {
delete patientAddresses[i];
// delete patientAddresses[i];: Xóa địa chỉ bệnh nhân khỏi
mảng patientAddresses.
break;
}
}

emit PatientRemoved(_patientAddress);
// Phát ra sự kiện để thông báo rằng một bệnh nhân đã được loại bỏ
khỏi hệ thống,
// kèm theo địa chỉ của bệnh nhân đã bị xóa.
}

function getPatientCount() external view returns (uint256) {


// Hàm getPatientCount được thiết kế để trả về số lượng bệnh nhân đã được
đăng ký trong hệ thống
uint256 count = 0;// ban đầu là 0.
// Duyệt qua mảng patientAddresses để kiểm tra từng phần tử.
for (uint256 i = 0; i < patientAddresses.length; i++) {
// Kiểm tra xem địa chỉ bệnh nhân có khác với địa chỉ mặc định
(0x0) không.
// địa chỉ mặc định là 0x0000000000000000000000000000000000000000.
if (patientAddresses[i] != address(0)) {
count++; // Mỗi khi tìm thấy một địa chỉ bệnh nhân khác 0,
tăng biến count lên 1.
}
}
return count;
// Trả về tổng số lượng bệnh nhân đã được đếm.
}
}

You might also like