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 4f5bb554..f1459eb2 100644 --- a/contracts/StudentRegistry.sol +++ b/contracts/StudentRegistry.sol @@ -1,46 +1,31 @@ // SPDX-License-Identifier: MIT pragma solidity ^0.8.24; +import "./Ownable.sol"; +import "./Student.sol"; +import "contracts/StudentCount.sol"; -contract StudentRegistry { - //custom data type - struct Student { - address studentAddr; - string name; - uint256 studentId; - uint8 age; - } - - address public owner; - - constructor() { - owner = msg.sender; - } +contract StudentRegistry is Ownable, StudentCount { + event PaymentStatus(bool indexed havePaid, string message); + event StudentUpdate(bool indexed updated, string message); - //dynamic array of students - Student[] private students; + mapping(address => Student) private studentsMapping; - mapping(address => Student) public studentsMapping; + mapping(address => uint) public studentUId; - modifier onlyOwner () { - require( owner == msg.sender, "You fraud!!!"); - _; - } - - modifier isNotAddressZero () { - require(msg.sender != address(0), "Invalid Address"); - _; - } + mapping(address => uint) public receipt; - function addStudent( + function registerStudents( address _studentAddr, string memory _name, - uint8 _age - ) public onlyOwner isNotAddressZero { + uint8 _age, + uint256 _studentId + ) public payable isNotAddressZero onlyOwner nameIsNotEmpty(_name) upToAge(_age) { + uint amount = msg.value; + uint hasUserPaid = receipt[_studentAddr]; - require( bytes(_name).length > 0, "Name cannot be blank"); - require( _age >= 18, "This student is under age"); + require(hasUserPaid == 0 ether, "You have registered"); + require(amount == 1 ether, "You must pay exactly 1 ether to proceed"); - uint256 _studentId = students.length + 1; Student memory student = Student({ studentAddr: _studentAddr, name: _name, @@ -48,31 +33,55 @@ contract StudentRegistry { studentId: _studentId }); - students.push(student); // add student to studentsMapping studentsMapping[_studentAddr] = student; + receipt[_studentAddr] = amount; + emit PaymentStatus(true, "you have succesfully registered"); } - function getStudent(uint8 _studentId) public isNotAddressZero view returns (Student memory) { - return students[_studentId - 1]; + function authorizeStudent(address _studentAddr) public { + require(receipt[_studentAddr] == 1 ether, "Go and register to proceed"); + + Student storage studentsDetails = studentsMapping[_studentAddr]; + + studentsDetails.studentAddr = _studentAddr; + studentsDetails.studentId = getStudentMainId(); + incrementStudentId(); + + studentUId[_studentAddr] = 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; + + studentsMapping[_studentAddr] = studentsUpdate; + emit StudentUpdate(true, "Successfully Updated"); + return studentsUpdate; + + } function getStudentFromMapping(address _studentAddr) public - isNotAddressZero view + isNotAddressZero returns (Student memory) { return studentsMapping[_studentAddr]; } - - - function deleteStudent(address _studentAddr) public onlyOwner isNotAddressZero{ - - require(studentsMapping[_studentAddr].studentAddr != address(0), "Student does not exist"); + function deleteStudent(address _studentAddr) + public + onlyOwner + isNotAddressZero + { + require( + studentsMapping[_studentAddr].studentAddr != address(0), + "Student does not exist" + ); // delete studentsMapping[_studentAddr]; @@ -84,6 +93,33 @@ contract StudentRegistry { }); studentsMapping[_studentAddr] = student; + } + + function modifyOwner(address _newOwner) public { + changeOwner(_newOwner); } -} + + /** + @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"); + } + + + /** + @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