Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat - implement update student from array and mapping in student registry contracts #7

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"solidity.compileUsingRemoteVersion": "v0.8.14+commit.80d49f37"
"solidity.compileUsingRemoteVersion": "v0.8.24+commit.e11b9ed9"
}
135 changes: 98 additions & 37 deletions contracts/StudentRegistry.sol
Original file line number Diff line number Diff line change
@@ -1,45 +1,51 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;
import './modifiers/AccessControlModifiers.sol';
import './modifiers/InputValidation.sol';

contract StudentRegistry {
//custom data type
/// @title Student Registry Contract
/// @notice This contract allows the management of students' information
/// @dev This contract uses access control and input validation modifiers
contract StudentRegistry is AccessControlModifiers, InputValidation {


/// @dev Custom data type representing a student
struct Student {
address studentAddr;
string name;
uint256 studentId;
uint8 age;
}

address public owner;
/// @dev Dynamic array of students
Student[] private students;

constructor() {
owner = msg.sender;
}
/// @dev Mapping from address to Student struct
mapping(address => Student) private studentsMapping;

//dynamic array of students
Student[] private students;
/// @dev Event emitted when a new student is added
/// @param studentsMapping[_studentAddr] or students[_studentId - 1] The student that was added
event addNewStudentEvent(Student students, Student studentsMapping);

mapping(address => Student) public studentsMapping;
/// @dev Event emitted when a student is deleted from the array
/// @param students[_studentId - 1] The student that was deleted
event deleteStudentEvent(Student students);

modifier onlyOwner () {
require( owner == msg.sender, "You fraud!!!");
_;
}
/// @dev Event emitted when a student is deleted from the mapping
/// @param studentsMapping[_studentAddr] The student that was deleted
event deleteStudentFromMappingEvent(Student studentsMapping);

modifier isNotAddressZero () {
require(msg.sender != address(0), "Invalid Address");
_;
}

/// @notice Adds a new student to the registry
/// @dev Only the owner can add a new student
/// @param _studentAddr The address of the student
/// @param _name The name of the student
/// @param _age The age of the student
function addStudent(
address _studentAddr,
string memory _name,
uint8 _age
) public onlyOwner isNotAddressZero {

require( bytes(_name).length > 0, "Name cannot be blank");
require( _age >= 18, "This student is under age");

) public onlyOwner validateStudentAge(_age) validateStudentName(_name) validateStudentAddress(_studentAddr) {
uint256 _studentId = students.length + 1;
Student memory student = Student({
studentAddr: _studentAddr,
Expand All @@ -49,41 +55,96 @@ contract StudentRegistry {
});

students.push(student);
// add student to studentsMapping
//@dev add student to studentsMapping
studentsMapping[_studentAddr] = student;
emit addNewStudentEvent(students[_studentId - 1], studentsMapping[_studentAddr]);
}

function getStudent(uint8 _studentId) public isNotAddressZero view returns (Student memory) {
/// @notice Gets a student by their ID
/// @param _studentId The ID of the student
/// @return The student with the specified ID
function getStudent(uint8 _studentId) public validateStudentId(_studentId) view returns (Student memory) {
require(_studentId < students.length, "student Id does not exist");
return students[_studentId - 1];
}



/// @notice Gets a student by their address from the mapping
/// @param _studentAddr The address of the student
/// @return The student with the specified address
function getStudentFromMapping(address _studentAddr)
public
isNotAddressZero
public validateStudentAddress(_studentAddr)
view
returns (Student memory)
{
return studentsMapping[_studentAddr];
}

/// @notice Deletes a student by their ID from the array
/// @dev Only the owner can delete a student
/// @param _studentId The ID of the student to delete
function deleteStudent(uint8 _studentId) public onlyOwner {
require(_studentId < students.length, "student Id does not exist");
for (uint256 i = 0; i < students.length; i++) {
if (students[i].studentId == _studentId) {
//@dev Maintaining Order in the array
students[i] = students[i + 1];
///@dev Not Maintaining Order in the array
// students[i] = students[students.length - 1];
// students.pop();
// emit deleteStudentEvent(students[_studentId - 1]);
// break;
}
}
students.pop();
emit deleteStudentEvent(students[_studentId - 1]);
}

/// @notice Deletes a student by their address from the mapping
/// @dev Only the owner can delete a student
/// @param _studentAddr The address of the student to delete
function deleteStudentFromMapping(address _studentAddr) public onlyOwner {
require(studentsMapping[_studentAddr].studentAddr != address(0), "Student does not exist");
delete studentsMapping[_studentAddr];

function deleteStudent(address _studentAddr) public onlyOwner isNotAddressZero{
}

/// @notice Updates a student in the mapping
/// @dev Only the owner can update a student
/// @param _studentAddr The address of the student to update
/// @param _name The new name of the student
/// @param _age The new age of the student
function updateStudentFromMapping(
address _studentAddr,
string memory _name,
uint8 _age
) public onlyOwner {
require(studentsMapping[_studentAddr].studentAddr != address(0), "Student does not exist");

// delete studentsMapping[_studentAddr];
Student storage student = studentsMapping[_studentAddr];
student.name = _name;
student.age = _age;
}

Student memory student = Student({
studentAddr: address(0),
name: "",
age: 0,
studentId: 0
});
/// @notice Updates a student in the array
/// @dev Only the owner can update a student
/// @param _studentId The ID of the student to update
/// @param _studentAddr The new address of the student
/// @param _name The new name of the student
/// @param _age The new age of the student
function updateStudent(
uint8 _studentId,
address _studentAddr,
string memory _name,
uint8 _age
) public onlyOwner validateStudentId(_studentId) {
require(_studentId <= students.length, "student Id does not exist");

studentsMapping[_studentAddr] = student;
Student storage student = students[_studentId - 1];
student.studentAddr = _studentAddr;
student.name = _name;
student.age = _age;

//@dev Also update the student in studentsMapping
studentsMapping[_studentAddr] = student;
}
}
37 changes: 37 additions & 0 deletions contracts/modifiers/AccessControlModifiers.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

/// @title Access Control Modifiers Contract
/// @notice This contract contains access control modifiers for ownership and authorization
contract AccessControlModifiers {
address private owner;

/// @notice Constructor sets the contract deployer as the owner
constructor() {
owner = msg.sender;
}

/// @notice Modifier to allow only the owner to execute the function
/// @dev Reverts if the caller is not the contract owner
modifier onlyOwner() {
require(msg.sender == owner, "Not the contract owner");
_;
}

/// @notice Modifier to allow only authorized addresses to execute the function
/// @dev Reverts if the address is not authorized
/// @param _address The address to check for authorization
modifier onlyAuthorized(address _address) {
require(isAuthorized(_address), "Not authorized");
_;
}

/// @notice Checks if an address is authorized
/// @dev This is a placeholder function for custom authorization logic
/// @param _address The address to check for authorization
/// @return bool True if the address is authorized, false otherwise
function isAuthorized(address _address) internal view returns (bool) {
//@dev Custom authorization logic
return _address == owner;
}
}
39 changes: 39 additions & 0 deletions contracts/modifiers/InputValidation.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.24;

/// @title Input Validation Contract
/// @notice This contract contains modifiers to validate inputs for student registration
contract InputValidation {

/// @notice Modifier to validate the age of the student
/// @dev Ensures that the student is at least 18 years old
/// @param _age The age of the student
modifier validateStudentAge(uint256 _age) {
require( _age >= 18, "This student is under age");
_;
}

/// @notice Modifier to validate the name of the student
/// @dev Ensures that the name is not blank
/// @param _name The name of the student
modifier validateStudentName(string memory _name) {
require( bytes(_name).length > 0, "Name cannot be blank");
_;
}

/// @notice Modifier to validate the ID of the student
/// @dev Ensures that the student ID is greater than zero
/// @param _studentId The ID of the student
modifier validateStudentId(uint8 _studentId) {
require(_studentId > 0, "Invalid Student ID");
_;
}

/// @notice Modifier to validate the address of the student
/// @dev Ensures that the address is not the zero address
/// @param _studentAddr The address of the student
modifier validateStudentAddress(address _studentAddr) {
require( _studentAddr != address(0), "Invalid Address");
_;
}
}