From 018c79205b25e13fe130066651a44293c064669c Mon Sep 17 00:00:00 2001 From: martin machiebe Date: Sun, 28 Jul 2024 23:04:52 +0100 Subject: [PATCH 1/3] assignment on solidity --- contracts/StudentRegistry.sol | 83 ++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 35 deletions(-) diff --git a/contracts/StudentRegistry.sol b/contracts/StudentRegistry.sol index 4f5bb554..a2946c32 100644 --- a/contracts/StudentRegistry.sol +++ b/contracts/StudentRegistry.sol @@ -2,12 +2,12 @@ pragma solidity ^0.8.24; contract StudentRegistry { - //custom data type + struct Student { address studentAddr; string name; - uint256 studentId; uint8 age; + uint studentId; } address public owner; @@ -16,31 +16,29 @@ contract StudentRegistry { owner = msg.sender; } - //dynamic array of students Student[] private students; - mapping(address => Student) public studentsMapping; + mapping(address => Student) public studentMap; - modifier onlyOwner () { - require( owner == msg.sender, "You fraud!!!"); + modifier onlyOwner() { + require(owner == msg.sender, "you're not authorized"); _; } - modifier isNotAddressZero () { + modifier isNotAddressZero() { require(msg.sender != address(0), "Invalid Address"); _; } - 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"); + event StudentAdded(address indexed studentAddr, string name, uint8 age, uint studentId); + event StudentDeleted(address indexed studentAddr); - uint256 _studentId = students.length + 1; + /// @dev function to add student to the students array and mapping + /// @notice adds student + function addStudent(address _studentAddr, string memory _name, uint8 _age) public onlyOwner isNotAddressZero { + require(bytes(_name).length > 0, "input cannot be empty"); + require(_age >= 18, "You are not up to age"); + uint _studentId = students.length + 1; Student memory student = Student({ studentAddr: _studentAddr, name: _name, @@ -49,32 +47,36 @@ contract StudentRegistry { }); students.push(student); - // add student to studentsMapping - studentsMapping[_studentAddr] = student; + studentMap[_studentAddr] = student; + + emit StudentAdded(_studentAddr, _name, _age, _studentId); } - function getStudent(uint8 _studentId) public isNotAddressZero view returns (Student memory) { + /// @dev function to get student using studentId + /// @notice gets student ID + function getStudent(uint256 _studentId) public view onlyOwner isNotAddressZero returns (Student memory) { return students[_studentId - 1]; } - - - function getStudentFromMapping(address _studentAddr) - public - isNotAddressZero - view - returns (Student memory) - { - return studentsMapping[_studentAddr]; + /// @dev function to get student using studentAddr + /// @notice gets student Address + function getStudentAddr(address _ownerAddr) public view onlyOwner isNotAddressZero returns (Student memory) { + return studentMap[_ownerAddr]; } + function updateStudent(address _studentAddr, string memory _name, uint8 _age, uint _studentId) public onlyOwner isNotAddressZero { + Student storage studentToUpdate = studentMap[_studentAddr]; + studentToUpdate.name = _name; + studentToUpdate.age = _age; + studentToUpdate.studentId = _studentId; + } + /// @dev function to delete using address + /// @notice resets it back to the initial state + function deleteStudent(address _studentAddr) public onlyOwner isNotAddressZero { + require(studentMap[_studentAddr].studentAddr != address(0), "student not available"); - function deleteStudent(address _studentAddr) public onlyOwner isNotAddressZero{ - - require(studentsMapping[_studentAddr].studentAddr != address(0), "Student does not exist"); - - // delete studentsMapping[_studentAddr]; + // delete studentMap[_studentAddr]; Student memory student = Student({ studentAddr: address(0), @@ -83,7 +85,18 @@ contract StudentRegistry { studentId: 0 }); - studentsMapping[_studentAddr] = student; + studentMap[_studentAddr] = student; + + emit StudentDeleted(_studentAddr); + } + + /// @dev function to delete using Uint + /// @notice resets it back to the initial state + function deleteStudentUint(uint _student) public onlyOwner isNotAddressZero { + require(_student > 0, "student not available or does not exist"); + + delete students[_student - 1]; + emit StudentDeleted(students[_student - 1].studentAddr); } -} +} \ No newline at end of file From e7cd9679b516b5b655a8086eb5db58ceae0cccb7 Mon Sep 17 00:00:00 2001 From: martin machiebe Date: Sun, 28 Jul 2024 23:11:26 +0100 Subject: [PATCH 2/3] updated the code --- contracts/StudentRegistry.sol | 151 +++++++++++++++++++++++++++++++--- 1 file changed, 140 insertions(+), 11 deletions(-) diff --git a/contracts/StudentRegistry.sol b/contracts/StudentRegistry.sol index a2946c32..c6220ce2 100644 --- a/contracts/StudentRegistry.sol +++ b/contracts/StudentRegistry.sol @@ -1,13 +1,105 @@ +// SPDX-License-Identifier: MIT +// pragma solidity ^0.8.24; + +// contract StudentRegistry { +// //custom data type +// struct Student { +// address studentAddr; +// string name; +// uint256 studentId; +// uint8 age; +// } + +// address public owner; + +// constructor() { +// owner = msg.sender; +// } + +// //dynamic array of students +// Student[] private students; + +// mapping(address => Student) public studentsMapping; + +// modifier onlyOwner () { +// require( owner == msg.sender, "You fraud!!!"); +// _; +// } + +// modifier isNotAddressZero () { +// require(msg.sender != address(0), "Invalid Address"); +// _; +// } + +// 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"); + +// uint256 _studentId = students.length + 1; +// Student memory student = Student({ +// studentAddr: _studentAddr, +// name: _name, +// age: _age, +// studentId: _studentId +// }); + +// students.push(student); +// // add student to studentsMapping +// studentsMapping[_studentAddr] = student; +// } + +// function getStudent(uint8 _studentId) public isNotAddressZero view returns (Student memory) { +// return students[_studentId - 1]; +// } + + + +// function getStudentFromMapping(address _studentAddr) +// public +// isNotAddressZero +// view +// returns (Student memory) +// { +// return studentsMapping[_studentAddr]; +// } + + + +// function deleteStudent(address _studentAddr) public onlyOwner isNotAddressZero{ + +// require(studentsMapping[_studentAddr].studentAddr != address(0), "Student does not exist"); + +// // delete studentsMapping[_studentAddr]; + +// Student memory student = Student({ +// studentAddr: address(0), +// name: "", +// age: 0, +// studentId: 0 +// }); + +// studentsMapping[_studentAddr] = student; + +// } +// } +// ` + + + // SPDX-License-Identifier: MIT pragma solidity ^0.8.24; contract StudentRegistry { - struct Student { address studentAddr; string name; uint8 age; - uint studentId; + uint256 studentId; } address public owner; @@ -30,15 +122,24 @@ contract StudentRegistry { _; } - event StudentAdded(address indexed studentAddr, string name, uint8 age, uint studentId); + event StudentAdded( + address indexed studentAddr, + string name, + uint8 age, + uint256 studentId + ); event StudentDeleted(address indexed studentAddr); /// @dev function to add student to the students array and mapping /// @notice adds student - function addStudent(address _studentAddr, string memory _name, uint8 _age) public onlyOwner isNotAddressZero { + function addStudent( + address _studentAddr, + string memory _name, + uint8 _age + ) public onlyOwner isNotAddressZero { require(bytes(_name).length > 0, "input cannot be empty"); require(_age >= 18, "You are not up to age"); - uint _studentId = students.length + 1; + uint256 _studentId = students.length + 1; Student memory student = Student({ studentAddr: _studentAddr, name: _name, @@ -54,17 +155,34 @@ contract StudentRegistry { /// @dev function to get student using studentId /// @notice gets student ID - function getStudent(uint256 _studentId) public view onlyOwner isNotAddressZero returns (Student memory) { + function getStudent(uint256 _studentId) + public + view + onlyOwner + isNotAddressZero + returns (Student memory) + { return students[_studentId - 1]; } /// @dev function to get student using studentAddr /// @notice gets student Address - function getStudentAddr(address _ownerAddr) public view onlyOwner isNotAddressZero returns (Student memory) { + function getStudentAddr(address _ownerAddr) + public + view + onlyOwner + isNotAddressZero + returns (Student memory) + { return studentMap[_ownerAddr]; } - function updateStudent(address _studentAddr, string memory _name, uint8 _age, uint _studentId) public onlyOwner isNotAddressZero { + function updateStudent( + address _studentAddr, + string memory _name, + uint8 _age, + uint256 _studentId + ) public onlyOwner isNotAddressZero { Student storage studentToUpdate = studentMap[_studentAddr]; studentToUpdate.name = _name; studentToUpdate.age = _age; @@ -73,8 +191,15 @@ contract StudentRegistry { /// @dev function to delete using address /// @notice resets it back to the initial state - function deleteStudent(address _studentAddr) public onlyOwner isNotAddressZero { - require(studentMap[_studentAddr].studentAddr != address(0), "student not available"); + function deleteStudent(address _studentAddr) + public + onlyOwner + isNotAddressZero + { + require( + studentMap[_studentAddr].studentAddr != address(0), + "student not available" + ); // delete studentMap[_studentAddr]; @@ -92,7 +217,11 @@ contract StudentRegistry { /// @dev function to delete using Uint /// @notice resets it back to the initial state - function deleteStudentUint(uint _student) public onlyOwner isNotAddressZero { + function deleteStudentUint(uint256 _student) + public + onlyOwner + isNotAddressZero + { require(_student > 0, "student not available or does not exist"); delete students[_student - 1]; From 3f4f8757347b6eb936d7703bc0c72d17c13f830d Mon Sep 17 00:00:00 2001 From: martin machiebe Date: Fri, 9 Aug 2024 08:46:22 +0100 Subject: [PATCH 3/3] refac: refactored student registry --- contracts/IStudentRegsr.sol | 27 ++++ contracts/MyStudentRegstr.sol | 56 ++++++++ contracts/Ownable.sol | 47 +++++++ contracts/Student.sol | 8 ++ contracts/StudentCount.sol | 18 +++ contracts/StudentRegistry.sol | 252 ++++++++++------------------------ 6 files changed, 229 insertions(+), 179 deletions(-) create mode 100644 contracts/IStudentRegsr.sol create mode 100644 contracts/MyStudentRegstr.sol create mode 100644 contracts/Ownable.sol create mode 100644 contracts/Student.sol create mode 100644 contracts/StudentCount.sol diff --git a/contracts/IStudentRegsr.sol b/contracts/IStudentRegsr.sol new file mode 100644 index 00000000..a3aea516 --- /dev/null +++ b/contracts/IStudentRegsr.sol @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; +import "./Student.sol"; +interface IStudentRegistry { + + + function registerStudents( + address _studentAddr, + string memory _name, + uint8 _age + ) external payable ; + + function authorizeStudent(address _studentAddr) external; + + function updateStudent(address _studentAddr, string memory _name, uint8 _age) external returns (Student memory); + + function getStudentFromMapping(address _studentAddr) external view returns (Student memory); + + function deleteStudent(address _studentAddr) external; + + function modifyOwner(address _newOwner) external ; + + function withdraw() external ; + + function getBalance() external view returns (uint256); + +} \ No newline at end of file diff --git a/contracts/MyStudentRegstr.sol b/contracts/MyStudentRegstr.sol new file mode 100644 index 00000000..5c906cf8 --- /dev/null +++ b/contracts/MyStudentRegstr.sol @@ -0,0 +1,56 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.7.0 <0.9.0; +import "./IStudentRegsr.sol"; +import "./Student.sol"; +import "./Ownable.sol"; + +contract MyStudentRegistry is Ownable { + + address private StudentRegistryContractAddress; + + constructor(address _studentRgistry){ + StudentRegistryContractAddress = _studentRgistry; + } + + function registerStudents( + address _studentAddr, + string memory _name, + uint8 _age + ) public payable onlyOwner { + + IStudentRegistry(StudentRegistryContractAddress).registerStudents(_studentAddr, _name, _age); + } + + + function authorizeStudents( + address _studentId + ) public { + + return IStudentRegistry(StudentRegistryContractAddress).authorizeStudent(_studentId); + } + + function StudentUpdates(address _studentAddr, string memory _name, uint8 _age) public returns (Student memory) { + return IStudentRegistry(StudentRegistryContractAddress).updateStudent(_studentAddr, _name, _age); + } + + function getStudentFromMappings(address _studentAddr) public view returns (Student memory) { + return IStudentRegistry(StudentRegistryContractAddress).getStudentFromMapping(_studentAddr); + } + + function deleteStudents(address _studentAddr) public { + IStudentRegistry(StudentRegistryContractAddress).deleteStudent(_studentAddr); + } + + function modifyOwners(address _newOwner) public { + IStudentRegistry(StudentRegistryContractAddress).modifyOwner(_newOwner); + } + + function withdraws() public { + IStudentRegistry(StudentRegistryContractAddress).withdraw(); + } + + function getsBalance() public view returns (uint256) { + return IStudentRegistry(StudentRegistryContractAddress).getBalance(); + } + +} \ No newline at end of file diff --git a/contracts/Ownable.sol b/contracts/Ownable.sol new file mode 100644 index 00000000..4edb101f --- /dev/null +++ b/contracts/Ownable.sol @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.7.0 <0.9.0; + + +contract Ownable { + + address private owner; + + event ChangeOwner(address indexed oldOwner, address indexed newOwner); + + constructor() payable { + owner = payable (msg.sender); + } + + modifier onlyOwner() { + require(owner == msg.sender, "You are not the owner or admin"); + _; + } + + modifier nameIsNotEmpty(string memory _name) { + require(bytes(_name).length != 0, "Please input a name"); + _; + } + + modifier isNotAddressZero() { + require(msg.sender != address(0), "Invalid Address"); + _; + } + + modifier upToAge(uint256 _age) { + require(_age >= 18, "You must be above 18 to proceed"); + _; + } + + + function getOwner() public view returns (address){ + return owner; + } + + + function changeOwner(address _newOwner) internal onlyOwner { + require(_newOwner != address(0), "Owner can not be address zero"); + + emit ChangeOwner(owner, _newOwner); + owner = _newOwner; + } +} \ No newline at end of file diff --git a/contracts/Student.sol b/contracts/Student.sol new file mode 100644 index 00000000..6fe7bea5 --- /dev/null +++ b/contracts/Student.sol @@ -0,0 +1,8 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; +struct Student { + address studentAddr; + string name; + uint8 age; + uint256 studentId; +} diff --git a/contracts/StudentCount.sol b/contracts/StudentCount.sol new file mode 100644 index 00000000..eb3aab63 --- /dev/null +++ b/contracts/StudentCount.sol @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +contract StudentCount { + uint public studentId = 0; + + function getStudentMainId() internal view returns (uint) { + return studentId; + } + + function incrementStudentId() internal { + studentId += 1; + } + + function decrementStudentId() internal { + studentId -= 1; + } +} \ No newline at end of file diff --git a/contracts/StudentRegistry.sol b/contracts/StudentRegistry.sol index c6220ce2..f1459eb2 100644 --- a/contracts/StudentRegistry.sol +++ b/contracts/StudentRegistry.sol @@ -1,207 +1,89 @@ // SPDX-License-Identifier: MIT -// pragma solidity ^0.8.24; - -// contract StudentRegistry { -// //custom data type -// struct Student { -// address studentAddr; -// string name; -// uint256 studentId; -// uint8 age; -// } - -// address public owner; - -// constructor() { -// owner = msg.sender; -// } - -// //dynamic array of students -// Student[] private students; - -// mapping(address => Student) public studentsMapping; - -// modifier onlyOwner () { -// require( owner == msg.sender, "You fraud!!!"); -// _; -// } - -// modifier isNotAddressZero () { -// require(msg.sender != address(0), "Invalid Address"); -// _; -// } - -// 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"); - -// uint256 _studentId = students.length + 1; -// Student memory student = Student({ -// studentAddr: _studentAddr, -// name: _name, -// age: _age, -// studentId: _studentId -// }); - -// students.push(student); -// // add student to studentsMapping -// studentsMapping[_studentAddr] = student; -// } - -// function getStudent(uint8 _studentId) public isNotAddressZero view returns (Student memory) { -// return students[_studentId - 1]; -// } - - - -// function getStudentFromMapping(address _studentAddr) -// public -// isNotAddressZero -// view -// returns (Student memory) -// { -// return studentsMapping[_studentAddr]; -// } - - - -// function deleteStudent(address _studentAddr) public onlyOwner isNotAddressZero{ - -// require(studentsMapping[_studentAddr].studentAddr != address(0), "Student does not exist"); +pragma solidity ^0.8.24; +import "./Ownable.sol"; +import "./Student.sol"; +import "contracts/StudentCount.sol"; -// // delete studentsMapping[_studentAddr]; +contract StudentRegistry is Ownable, StudentCount { + event PaymentStatus(bool indexed havePaid, string message); + event StudentUpdate(bool indexed updated, string message); -// Student memory student = Student({ -// studentAddr: address(0), -// name: "", -// age: 0, -// studentId: 0 -// }); + mapping(address => Student) private studentsMapping; -// studentsMapping[_studentAddr] = student; + mapping(address => uint) public studentUId; -// } -// } -// ` + mapping(address => uint) public receipt; + function registerStudents( + address _studentAddr, + string memory _name, + uint8 _age, + uint256 _studentId + ) public payable isNotAddressZero onlyOwner nameIsNotEmpty(_name) upToAge(_age) { + uint amount = msg.value; + uint hasUserPaid = receipt[_studentAddr]; + require(hasUserPaid == 0 ether, "You have registered"); + require(amount == 1 ether, "You must pay exactly 1 ether to proceed"); -// SPDX-License-Identifier: MIT -pragma solidity ^0.8.24; + Student memory student = Student({ + studentAddr: _studentAddr, + name: _name, + age: _age, + studentId: _studentId + }); -contract StudentRegistry { - struct Student { - address studentAddr; - string name; - uint8 age; - uint256 studentId; + // add student to studentsMapping + studentsMapping[_studentAddr] = student; + receipt[_studentAddr] = amount; + emit PaymentStatus(true, "you have succesfully registered"); } - address public owner; - - constructor() { - owner = msg.sender; - } + function authorizeStudent(address _studentAddr) public { + require(receipt[_studentAddr] == 1 ether, "Go and register to proceed"); - Student[] private students; + Student storage studentsDetails = studentsMapping[_studentAddr]; - mapping(address => Student) public studentMap; + studentsDetails.studentAddr = _studentAddr; + studentsDetails.studentId = getStudentMainId(); + incrementStudentId(); - modifier onlyOwner() { - require(owner == msg.sender, "you're not authorized"); - _; - } + studentUId[_studentAddr] = studentId; - modifier isNotAddressZero() { - require(msg.sender != address(0), "Invalid Address"); - _; } - event StudentAdded( - address indexed studentAddr, - string name, - uint8 age, - uint256 studentId - ); - event StudentDeleted(address indexed studentAddr); - - /// @dev function to add student to the students array and mapping - /// @notice adds student - function addStudent( - address _studentAddr, - string memory _name, - uint8 _age - ) public onlyOwner isNotAddressZero { - require(bytes(_name).length > 0, "input cannot be empty"); - require(_age >= 18, "You are not up to age"); - uint256 _studentId = students.length + 1; - Student memory student = Student({ - studentAddr: _studentAddr, - name: _name, - age: _age, - studentId: _studentId - }); + function updateStudent(address _studentAddr, string memory _name, uint8 _age) public isNotAddressZero onlyOwner nameIsNotEmpty(_name) upToAge(_age) returns (Student memory) { + Student storage studentsUpdate = studentsMapping[_studentAddr]; + studentsUpdate.name = _name; + studentsUpdate.age = _age; - students.push(student); - studentMap[_studentAddr] = student; + studentsMapping[_studentAddr] = studentsUpdate; + emit StudentUpdate(true, "Successfully Updated"); - emit StudentAdded(_studentAddr, _name, _age, _studentId); - } + return studentsUpdate; - /// @dev function to get student using studentId - /// @notice gets student ID - function getStudent(uint256 _studentId) - public - view - onlyOwner - isNotAddressZero - returns (Student memory) - { - return students[_studentId - 1]; } - /// @dev function to get student using studentAddr - /// @notice gets student Address - function getStudentAddr(address _ownerAddr) + function getStudentFromMapping(address _studentAddr) public view - onlyOwner isNotAddressZero returns (Student memory) { - return studentMap[_ownerAddr]; - } - - function updateStudent( - address _studentAddr, - string memory _name, - uint8 _age, - uint256 _studentId - ) public onlyOwner isNotAddressZero { - Student storage studentToUpdate = studentMap[_studentAddr]; - studentToUpdate.name = _name; - studentToUpdate.age = _age; - studentToUpdate.studentId = _studentId; + return studentsMapping[_studentAddr]; } - /// @dev function to delete using address - /// @notice resets it back to the initial state function deleteStudent(address _studentAddr) public onlyOwner isNotAddressZero { require( - studentMap[_studentAddr].studentAddr != address(0), - "student not available" + studentsMapping[_studentAddr].studentAddr != address(0), + "Student does not exist" ); - // delete studentMap[_studentAddr]; + // delete studentsMapping[_studentAddr]; Student memory student = Student({ studentAddr: address(0), @@ -210,22 +92,34 @@ contract StudentRegistry { studentId: 0 }); - studentMap[_studentAddr] = student; + studentsMapping[_studentAddr] = student; + } + - emit StudentDeleted(_studentAddr); + function modifyOwner(address _newOwner) public { + changeOwner(_newOwner); } - /// @dev function to delete using Uint - /// @notice resets it back to the initial state - function deleteStudentUint(uint256 _student) - public - onlyOwner - isNotAddressZero - { - require(_student > 0, "student not available or does not exist"); + /** + @notice Withdraws the contract's balance to the owner's address. + */ + function withdraw() public isNotAddressZero onlyOwner { + uint256 balance = address(this).balance; + require(balance > 0, "Empty Balance"); + + (bool success, ) = getOwner().call{value: balance}(""); + require(success, "your Withdrawal was unsucessful"); + } - delete students[_student - 1]; - emit StudentDeleted(students[_student - 1].studentAddr); + /** + @notice Returns the balance of the contract. + @return balance The current balance of the contract. + */ + function getBalance() public view returns (uint256) { + return address(this).balance; } + + receive() external payable { } + } \ No newline at end of file