Skip to content
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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
target
student-registry-dapp-starter
103 changes: 103 additions & 0 deletions Scarb.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,112 @@ version = 1
name = "cairo_bootcamp_3"
version = "0.1.0"
dependencies = [
"openzeppelin",
"snforge_std",
]

[[package]]
name = "openzeppelin"
version = "0.17.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.17.0#bf5d02c25c989ccc24f3ab42ec649617d3f21289"
dependencies = [
"openzeppelin_access",
"openzeppelin_account",
"openzeppelin_finance",
"openzeppelin_governance",
"openzeppelin_introspection",
"openzeppelin_merkle_tree",
"openzeppelin_presets",
"openzeppelin_security",
"openzeppelin_token",
"openzeppelin_upgrades",
"openzeppelin_utils",
]

[[package]]
name = "openzeppelin_access"
version = "0.17.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.17.0#bf5d02c25c989ccc24f3ab42ec649617d3f21289"
dependencies = [
"openzeppelin_introspection",
"openzeppelin_utils",
]

[[package]]
name = "openzeppelin_account"
version = "0.17.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.17.0#bf5d02c25c989ccc24f3ab42ec649617d3f21289"
dependencies = [
"openzeppelin_introspection",
"openzeppelin_utils",
]

[[package]]
name = "openzeppelin_finance"
version = "0.17.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.17.0#bf5d02c25c989ccc24f3ab42ec649617d3f21289"
dependencies = [
"openzeppelin_access",
"openzeppelin_token",
]

[[package]]
name = "openzeppelin_governance"
version = "0.17.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.17.0#bf5d02c25c989ccc24f3ab42ec649617d3f21289"
dependencies = [
"openzeppelin_access",
"openzeppelin_introspection",
]

[[package]]
name = "openzeppelin_introspection"
version = "0.17.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.17.0#bf5d02c25c989ccc24f3ab42ec649617d3f21289"

[[package]]
name = "openzeppelin_merkle_tree"
version = "0.17.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.17.0#bf5d02c25c989ccc24f3ab42ec649617d3f21289"

[[package]]
name = "openzeppelin_presets"
version = "0.17.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.17.0#bf5d02c25c989ccc24f3ab42ec649617d3f21289"
dependencies = [
"openzeppelin_access",
"openzeppelin_account",
"openzeppelin_finance",
"openzeppelin_introspection",
"openzeppelin_token",
"openzeppelin_upgrades",
]

[[package]]
name = "openzeppelin_security"
version = "0.17.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.17.0#bf5d02c25c989ccc24f3ab42ec649617d3f21289"

[[package]]
name = "openzeppelin_token"
version = "0.17.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.17.0#bf5d02c25c989ccc24f3ab42ec649617d3f21289"
dependencies = [
"openzeppelin_account",
"openzeppelin_governance",
"openzeppelin_introspection",
]

[[package]]
name = "openzeppelin_upgrades"
version = "0.17.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.17.0#bf5d02c25c989ccc24f3ab42ec649617d3f21289"

[[package]]
name = "openzeppelin_utils"
version = "0.17.0"
source = "git+https://github.com/OpenZeppelin/cairo-contracts.git?tag=v0.17.0#bf5d02c25c989ccc24f3ab42ec649617d3f21289"

[[package]]
name = "snforge_scarb_plugin"
version = "0.31.0"
Expand Down
12 changes: 12 additions & 0 deletions assignments/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<!--ASSIGNMENT CREATED ON 14/10/2024-->

# ASSIGNMENT 5

## Student Attendance Component
### Implemented:
- get_attendance(student_account: ContractAddress, date: felt252).


- mark_attendance(_student_account: ContractAddress, _date: felt252, _present: bool).

- Contrack address: 0x55abee888d949203f3973ad9ad725fd7c57c8d5da79a6756ef0473af86af863
4 changes: 2 additions & 2 deletions snfoundry.toml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[sncast.cohort_dev]
account = "cohort_dev"
[sncast.stark1]
account = "stark1"
accounts-file = "~/.starknet_accounts/starknet_open_zeppelin_accounts.json"
url = "https://free-rpc.nethermind.io/sepolia-juno/"

Expand Down
1 change: 1 addition & 0 deletions src/lib.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ pub mod ownable_counter;
pub mod addition;

pub mod student_registry_manager;
pub mod student_attendance;
100 changes: 100 additions & 0 deletions src/student_attendance.cairo
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
use starknet::ContractAddress;

#[starknet::interface]
pub trait IStudentAttendance<T> {
fn mark_attendance(
ref self: T, _student_account: ContractAddress, _date: felt252, _present: bool
) -> bool;

fn get_attendance(self: @T, student_account: ContractAddress, date: felt252) -> bool;
}

#[starknet::component]
pub mod StudentAttendanceComponent {
use OwnableComponent::InternalTrait;
use starknet::ContractAddress;
use core::num::traits::Zero;
use openzeppelin::access::ownable::{OwnableComponent, OwnableComponent::InternalImpl};

use super::{IStudentAttendance};
use starknet::storage::{
StoragePointerReadAccess, StoragePointerWriteAccess, StoragePathEntry, Map
};
use crate::errors::Errors;

#[storage]
struct Storage {
admin_account: ContractAddress,
attendance_map: Map::<ContractAddress, Map<felt252, bool>>,
}

#[event]
#[derive(Drop, starknet::Event)]
pub enum Event {
AttendanceMarked: AttendanceMarked
}

#[derive(Drop, starknet::Event)]
struct AttendanceMarked {
marked_student: ContractAddress,
}

#[embeddable_as(StudentAttendance)]
pub impl StudenAttendanceImpl<
TContractState,
+HasComponent<TContractState>,
+Drop<TContractState>,
impl Ownable: OwnableComponent::HasComponent<TContractState>
> of IStudentAttendance<ComponentState<TContractState>> {
fn mark_attendance(
ref self: ComponentState<TContractState>,
_student_account: ContractAddress,
_date: felt252,
_present: bool
) -> bool {
assert(self.is_zero_address(_student_account), Errors::ZERO_ADDRESS);

// assert only owner
let ownable_comp = get_dep_component!(@self, Ownable);
ownable_comp.assert_only_owner();

self.attendance_map.entry(_student_account).entry(_date).write(_present);

self.emit(AttendanceMarked { marked_student: _student_account });

true
}

fn get_attendance(
self: @ComponentState<TContractState>, student_account: ContractAddress, date: felt252
) -> bool {
let attendance = self.attendance_map.entry(student_account).entry(date).read();
return attendance;
}
}


#[generate_trait]
pub impl Private<
TContractState,
+HasComponent<TContractState>,
+Drop<TContractState>,
impl Ownable: OwnableComponent::HasComponent<TContractState>
> of PrivateTrait<TContractState> {
fn initializer(ref self: ComponentState<TContractState>, _admin: ContractAddress) {
// validation to check if admin account has valid address and not 0 address
assert(self.is_zero_address(_admin) == false, Errors::ZERO_ADDRESS);
let mut ownable_comp = get_dep_component_mut!(ref self, Ownable);
ownable_comp.initializer(_admin);
}

fn is_zero_address(
self: @ComponentState<TContractState>, account: ContractAddress
) -> bool {
if account.is_zero() {
return true;
}
return false;
}
}
}
18 changes: 16 additions & 2 deletions src/student_registry_manager.cairo
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,16 @@ pub mod StudentRegistryManager {
use super::IStudentRegistryManager;
use crate::student_registry::StudentRegistryComponent;
use openzeppelin::access::ownable::OwnableComponent;
use crate::student_attendance::StudentAttendanceComponent;

// Declare component
component!(
path: StudentRegistryComponent, storage: studentRegistry, event: StudentRegistryEvent
);
component!(path: OwnableComponent, storage: ownable, event: OwnableEvent);
component!(
path: StudentAttendanceComponent, storage: studentAttendance, event: AttendanceEvent
);

#[abi(embed_v0)]
impl OwnableMixinImpl = OwnableComponent::OwnableMixinImpl<ContractState>;
Expand All @@ -27,16 +31,23 @@ pub mod StudentRegistryManager {
impl studentRegistryImpl =
StudentRegistryComponent::StudentRegistry<ContractState>;

#[abi(embed_v0)]
impl studentAttendanceImpl =
StudentAttendanceComponent::StudentAttendance<ContractState>;

// instantiate component's private implementation
impl studentRegisterPrivateImpl = StudentRegistryComponent::Private<ContractState>;
impl studentAttendancePrivateImpl = StudentAttendanceComponent::Private<ContractState>;

#[storage]
struct Storage {
name: felt252,
#[substorage(v0)] // component's storage variable must be annotated with this attribute
studentRegistry: StudentRegistryComponent::Storage,
#[substorage(v0)]
ownable: OwnableComponent::Storage
ownable: OwnableComponent::Storage,
#[substorage(v0)]
studentAttendance: StudentAttendanceComponent::Storage
}

#[event]
Expand All @@ -46,7 +57,9 @@ pub mod StudentRegistryManager {
#[flat] // component's event must be annotated with this attribute
StudentRegistryEvent: StudentRegistryComponent::Event,
#[flat]
OwnableEvent: OwnableComponent::Event
OwnableEvent: OwnableComponent::Event,
#[flat]
AttendanceEvent: StudentAttendanceComponent::Event
}

#[derive(Drop, starknet::Event)]
Expand All @@ -61,6 +74,7 @@ pub mod StudentRegistryManager {

// initialize component
self.studentRegistry.initializer(_admin);
self.studentAttendance.initializer(_admin);
}

#[abi(embed_v0)]
Expand Down