From 558814a83fe97e375e85d26472b8323b7eb0b445 Mon Sep 17 00:00:00 2001 From: Isaac Date: Fri, 15 Dec 2023 12:12:34 +0100 Subject: [PATCH 1/3] chore:add trait and impl --- src/class_character_v2.cairo | 2 +- src/owner_contract.cairo | 23 +++++++++++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/src/class_character_v2.cairo b/src/class_character_v2.cairo index 8fa3718..ad1ab5e 100644 --- a/src/class_character_v2.cairo +++ b/src/class_character_v2.cairo @@ -1,7 +1,7 @@ #[starknet::contract] mod ClassCharacterV2 { use core::zeroable::Zeroable; -use core::starknet::event::EventEmitter; + use core::starknet::event::EventEmitter; use starknet::{ContractAddress, get_caller_address}; // event diff --git a/src/owner_contract.cairo b/src/owner_contract.cairo index 2ebbc9d..06d237c 100644 --- a/src/owner_contract.cairo +++ b/src/owner_contract.cairo @@ -21,5 +21,28 @@ mod OwnerContract { fn get_owner(self: @ContractState) -> ContractAddress { self.owner.read() } + + fn set_owner_OnlyOwner(ref sef: ContractState, new_owner: ContractAddress) { + // let caller = get_caller_address(); + // let owner = self.owner.read(); + // assert(caller == owner, 'Caller is not the owner'); + self.only_owner(); + self.owner.write(new_owner); + } + + fn get_owner_onlyOwner(self: @ContractState) -> ContractAddress { + // let caller = get_caller_address(); + // assert(caller == owner, 'Caller is not the owner'); + self.only_owner(); + self.owner.read() + } + } + + #[generate_trait] + impl PrivateMethods of PrivateMethodsTrait { + fn only_owner(self: @ContractState) { + let caller = get_caller_address(); + assert(caller == self.owner.read(), 'Caller is not the owner'); + } } } From 1e279bd2df7226144e782b31e5ce7f8363a15a26 Mon Sep 17 00:00:00 2001 From: Isaac Date: Fri, 15 Dec 2023 14:07:04 +0100 Subject: [PATCH 2/3] refac: add traits and impls --- src/class_character_v3.cairo | 98 ++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 src/class_character_v3.cairo diff --git a/src/class_character_v3.cairo b/src/class_character_v3.cairo new file mode 100644 index 0000000..78c4aac --- /dev/null +++ b/src/class_character_v3.cairo @@ -0,0 +1,98 @@ +#[starknet::interface] +trait IStudent { + fn add_student( + ref self: TContractState, + student_account: ContractAddress, + _name: felt252, + _age: u8, + _is_active: bool, + _has_reward: bool, + _xp_earnings: u256, + ); + + fn get_student(self: @TContractState) -> ContractAddress; +} + +#[starknet::interface] +trait IOwnable { + fn set_owner(ref self: ContractState, new_owner: ContractAddress); + + fn get_owner(self: ContractState) -> ContractAddress; +} + + +#[starknet::contract] +mod ClassCharacterV3 { + use core::zeroable::Zeroable; + use core::starknet::event::EventEmitter; + use starknet::{ContractAddress, get_caller_address}; + + #[event] + #[derive(Drop, starknet::Event)] + enum Event { + OwnerUpdated: OwnerUpdated, + StudentAdded: StudentAdded + } + + #[derive(Drop, starknet::Event)] + struct StudentAdded { + student: ContractAddress, + } + + #[storage] + struct Storage { + owner: ContractAddress, + students: LegacyMap:: + } + + #[constructor] + fn constructor(ref self: ContractState, init_owner: ContractAddress) { + self.owner.write(init_owner); + } + + #[derive(Copy, Drop, Serde, starknet::Store)] + struct Student { + name: felt252, + age: u8, + is_active: bool, + has_reward: bool, + xp_earnings: u256 + } + + #[abi_embed(v0)] + impl withoutAccess of IStudent { + fn add_student( + ref self: TContractState, + student_account: ContractAddress, + _name: felt252, + _age: u8, + _is_active: bool, + _has_reward: bool, + _xp_earnings: u256, + ) { + self.only_owner(); + assert(!student_account.is_zero(), 'caller cannot be address zero'); + assert(student_account != owner, 'student_account cannot be owner'); + assert(_name != '', 'name cannot be empty'); + assert(_age != 0, 'age cannot be zero'); + + // Create student instance + let student_instance = Student { _name, _age, is_active, _has_reward, _xp_earnings }; + self.students.write(student_account, student_instance); + self.emit(StudentAdded { Student: student_account }); + } + + fn get_student(self: @TContractState) -> ContractAddress { + self.only_owner(); + self.students.read(); + } + } + + #[generate_trait] + impl PrivateMethods of PrivateMethodsTrait { + fn only_owner(self: @ContractState) { + let caller = get_caller_address(); + assert(caller == self.owner.read(), 'Caller is not the owner'); + } + } +} From 344dfba45a3c135ade288a5216d9d38778a79b80 Mon Sep 17 00:00:00 2001 From: Isaac Date: Fri, 15 Dec 2023 22:05:00 +0100 Subject: [PATCH 3/3] chore: add traits and impls with access control --- src/class_character_v3.cairo | 91 +++++++++++++++++++++++++++++++++++- 1 file changed, 90 insertions(+), 1 deletion(-) diff --git a/src/class_character_v3.cairo b/src/class_character_v3.cairo index 78c4aac..c46bfbd 100644 --- a/src/class_character_v3.cairo +++ b/src/class_character_v3.cairo @@ -1,3 +1,4 @@ +use starknet::ContractAddress; #[starknet::interface] trait IStudent { fn add_student( @@ -13,6 +14,22 @@ trait IStudent { fn get_student(self: @TContractState) -> ContractAddress; } +#[starknet::interface] +trait IStudentWithAccess { + fn add_student( + ref self: TContractState, + student_account: ContractAddress, + _name: felt252, + _age: u8, + _is_active: bool, + _has_reward: bool, + _xp_earnings: u256, + ); + + fn get_student(self: @TContractState) -> ContractAddress; +} + + #[starknet::interface] trait IOwnable { fn set_owner(ref self: ContractState, new_owner: ContractAddress); @@ -20,9 +37,18 @@ trait IOwnable { fn get_owner(self: ContractState) -> ContractAddress; } +#[starknet::interface] +trait IOwnableWithAccess { + fn set_owner(ref self: ContractState, new_owner: ContractAddress); + + fn get_owner(self: ContractState) -> ContractAddress; +} + #[starknet::contract] mod ClassCharacterV3 { + use super::{IOwnable, IOwnableWithAccessControl}; + use super::{IStudent, IStudentWithAccess}; use core::zeroable::Zeroable; use core::starknet::event::EventEmitter; use starknet::{ContractAddress, get_caller_address}; @@ -34,6 +60,12 @@ mod ClassCharacterV3 { StudentAdded: StudentAdded } + #[derive(Drop, starknet::Event)] + struct OwnerUpdated { + init_owner: ContractAddress, + new_owner: ContractAddress + } + #[derive(Drop, starknet::Event)] struct StudentAdded { student: ContractAddress, @@ -60,7 +92,35 @@ mod ClassCharacterV3 { } #[abi_embed(v0)] - impl withoutAccess of IStudent { + impl StudentImpl of IStudent { + fn add_student( + ref self: TContractState, + student_account: ContractAddress, + _name: felt252, + _age: u8, + _is_active: bool, + _has_reward: bool, + _xp_earnings: u256, + ) { + assert(!student_account.is_zero(), 'caller cannot be address zero'); + assert(student_account != owner, 'student_account cannot be owner'); + assert(_name != '', 'name cannot be empty'); + assert(_age != 0, 'age cannot be zero'); + + // Create student instance + let student_instance = Student { _name, _age, is_active, _has_reward, _xp_earnings }; + self.students.write(student_account, student_instance); + self.emit(StudentAdded { Student: student_account }); + } + + fn get_student(self: @TContractState) -> ContractAddress { + self.only_owner(); + self.students.read(); + } + } + + #[abi_embed(v0)] + impl StudentImplWithoutAcess of IStudent { fn add_student( ref self: TContractState, student_account: ContractAddress, @@ -88,6 +148,35 @@ mod ClassCharacterV3 { } } + + #[abi_embed(v0)] + impl OwnableImpl of IOwnable { + fn set_owner(ref self: ContractState, new_owner: ContractAddress) { + self.owner.write(new_owner); + self.emit(OwnerUpdated { init_owner: owner, new_owner: new_owner }); + true + } + + fn get_owner(self: @ContractState) -> ContractAddress { + self.owner.read(); + } + } + + impl OwnableWithAccessImpl of IOwnable { + fn set_owner(ref self: ContractState, new_owner: ContractAddress) { + self.only_owner(); + self.owner.write(new_owner); + self.emit(OwnerUpdated { init_owner: owner, new_owner: new_owner }); + true + } + + fn get_owner(self: @ContractState) -> ContractAddress { + self.only_owner(); + self.owner.read(); + } + } + + #[generate_trait] impl PrivateMethods of PrivateMethodsTrait { fn only_owner(self: @ContractState) {