diff --git a/contracts/Task-1/Number.counter.sol b/contracts/Task-1/Number.counter.sol new file mode 100644 index 00000000..b734e2ea --- /dev/null +++ b/contracts/Task-1/Number.counter.sol @@ -0,0 +1,94 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.24; +/** +* @title Counter +* @author Enyinnaya Wisdom +* @notice a counter contract that allows for incrementing and decrementing a counter +* @dev This contract demonstrates basic state management and event emission +*/ +contract Counter { + uint public counter; + /** + * @notice Emitted when the counter is increased. + * @param newValue The new value of the counter after incrementing. + * @param timestamp The block timestamp when the counter was increased. + */ + event CountIncreased(uint256 newValue, uint256 timestamp); + + /** + * @notice Emitted when the counter is decreased. + * @param newValue The new value of the counter after decrementing. + * @param timestamp The block timestamp when the counter was decreased. + */ + event CountDecreased(uint256 newValue, uint256 timestamp); + /** + * @notice Increases the counter by 1. + * @dev This function increments the counter and emits a `CountIncreased` event. + * It automatically checks for overflow in Solidity 0.8.0+. + */ + function increaseByOne() public { + require(counter < type(uint256).max, "cannot increase beyond max uint"); + counter ++; + emit CountIncreased(counter, block.timestamp); + } + /** + * @notice Increases the counter by a specified value. + * @dev This function increments the counter by `_value` and emits a `CountIncreased` event. + * It reverts if the counter would exceed the maximum value for `uint256`. + * @param _value The amount by which to increase the counter. + */ + function increaseByValue(uint _value) public { + require(counter < type(uint256).max, "cannot increase beyond max uint"); + counter += _value; + emit CountIncreased(counter, block.timestamp); + + } + /** + * @notice Decreases the counter by 1. + * @dev This function decrements the counter and emits a `CountDecreased` event. + * It reverts if the counter is already 0 to prevent underflow. + */ + function decreaseByOne() public { + require(counter > 1, "cannot decrease below 0"); + counter --; + emit CountDecreased(counter, block.timestamp); + } + + /** + * @notice Decreases the counter by a specified value. + * @dev This function decrements the counter by `_value` and emits a `CountDecreased` event. + * It reverts if the counter would go below 0. + * @param _value The amount by which to decrease the counter. + */ + function decreaseByValue(uint _value) public { + require(counter > _value, "cannot decrease below 0"); + counter -= _value; + emit CountDecreased(counter, block.timestamp); + } + /** + * @notice Resets the counter to 0. + * @dev This function sets the counter to 0 and emits a `CountDecreased` event. + */ + function resetCount() public { + counter = 0; + emit CountDecreased(counter, block.timestamp); + } + /** + * @notice Returns the current value of the counter. + * @dev This is a getter function for the `counter` state variable. + * @return The current value of the counter. + */ + function getCount() public view returns (uint) { + return counter; + } + /** + * @notice Sets the counter to a specific value. + * @dev This function updates the counter to `_num` and emits a `CountIncreased` event. + * @param _num The new value to set the counter to. + */ + function stateChanging(uint _num) public { + counter = _num; + emit CountIncreased(counter, block.timestamp); + } + +} \ No newline at end of file diff --git a/contracts/Task-2/Number.Registry.sol b/contracts/Task-2/Number.Registry.sol new file mode 100644 index 00000000..9eb8c3d5 --- /dev/null +++ b/contracts/Task-2/Number.Registry.sol @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: UNLICENSED +pragma solidity ^0.8.24; + +contract StudentRegistry { + // Enum for attendance status + enum Attendance { Absent, Present } + + // Struct to represent a student + struct Student { + string name; + Attendance attendance; + string[] interests; + } + + // Mapping to store students by their address + mapping(address => Student) public students; + + // Event emitted when a student is registered + event StudentCreated(address indexed studentAddress, string name); + + // Event emitted when attendance is marked + event AttendanceStatus(address indexed studentAddress, Attendance attendance); + + // Event emitted when an interest is added + event InterestAdded(address indexed studentAddress, string interest); + + // Event emitted when an interest is removed + event InterestRemoved(address indexed studentAddress, string interest); + + // Modifier to ensure only registered students can perform actions + modifier onlyRegisteredStudent(address _address) { + require(bytes(students[_address].name).length > 0, "Student not registered"); + _; + } + + // Modifier to ensure only the owner can perform certain actions + address public owner; + modifier onlyOwner() { + require(msg.sender == owner, "Only the owner can perform this action"); + _; + } + + // Constructor to set the contract owner + constructor() { + owner = msg.sender; + } + + // Function to register a new student + function registerNewStudent(string memory _name) public { + require(bytes(_name).length > 0, "Name cannot be empty"); + require(bytes(students[msg.sender].name).length == 0, "Student already registered"); + + // Initialize the student struct + students[msg.sender] = Student({ + name: _name, + attendance: Attendance.Absent, + interests: new string[](0) + }); + + emit StudentCreated(msg.sender, _name); + } + + // Function to mark attendance + function markAttendance(address _address, Attendance _attendance) public onlyRegisteredStudent(_address) { + students[_address].attendance = _attendance; + emit AttendanceStatus(_address, _attendance); + } + + // Function to add an interest + function addInterest(address _address, string memory _interest) public onlyRegisteredStudent(_address) { + require(bytes(_interest).length > 0, "Interest cannot be empty"); + require(students[_address].interests.length <= 5, "Maximum of 5 interests allowed"); + + // Check for duplicate interests + for (uint i = 0; i < students[_address].interests.length; i++) { + require( + keccak256(bytes(students[_address].interests[i])) != keccak256(bytes(_interest)), + "Interest already exists" + ); + } + + students[_address].interests.push(_interest); + emit InterestAdded(_address, _interest); + } + + // Function to remove an interest + function removeInterest(address _address, string memory _interest) public onlyRegisteredStudent(_address) { + string[] storage interests = students[_address].interests; + bool interestFound = false; + + for (uint i = 0; i < interests.length; i++) { + if (keccak256(bytes(interests[i])) == keccak256(bytes(_interest))) { + // Swap with the last element and pop + interests[i] = interests[interests.length - 1]; + interests.pop(); + interestFound = true; + emit InterestRemoved(_address, _interest); + break; + } + } + + require(interestFound, "Interest not found"); + } + + // Getter functions + function getStudentName(address _address) public view onlyRegisteredStudent(_address) returns (string memory) { + return students[_address].name; + } + + function getStudentAttendance(address _address) public view onlyRegisteredStudent(_address) returns (Attendance) { + return students[_address].attendance; + } + + function getStudentInterests(address _address) public view onlyRegisteredStudent(_address) returns (string[] memory) { + return students[_address].interests; + } + + // Ownership management + function transferOwnership(address _newOwner) public onlyOwner { + require(_newOwner != address(0), "Invalid address"); + owner = _newOwner; + } + + // Bonus: Allow a student to update their name + function updateStudentName(string memory _newName) public onlyRegisteredStudent(msg.sender) { + require(bytes(_newName).length > 0, "Name cannot be empty"); + students[msg.sender].name = _newName; + } +} \ No newline at end of file diff --git a/submissions/Assignment3/README.md b/submissions/Assignment3/README.md deleted file mode 100644 index 6f3a09c7..00000000 --- a/submissions/Assignment3/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Submissions for Assignment 3 ---- ---- \ No newline at end of file diff --git a/submissions/Task-1.md b/submissions/Task-1.md new file mode 100644 index 00000000..d60d1a2c --- /dev/null +++ b/submissions/Task-1.md @@ -0,0 +1,5 @@ +# submisssion for Assignment 1 +...... +...... +...... +[Assignment 1 submissions](../../contracts/Task-1) \ No newline at end of file diff --git a/submissions/Task-2.md b/submissions/Task-2.md new file mode 100644 index 00000000..88dee104 --- /dev/null +++ b/submissions/Task-2.md @@ -0,0 +1,5 @@ +# submisssion for Assignment 2 +...... +...... +...... +[Assignment 2 submissions](../../contracts/Task-2) \ No newline at end of file diff --git a/submissions/Task-3.md b/submissions/Task-3.md new file mode 100644 index 00000000..e69de29b