From 238c30e102a72745a2f180d9587ae264b7fad4a1 Mon Sep 17 00:00:00 2001 From: Ibrahim Suleiman Prince Date: Wed, 16 Oct 2024 09:54:15 +0100 Subject: [PATCH] feat: replaced students mapping with a vector --- src/student_registry.cairo | 68 +++++++++++++++++--------------------- src/student_struct.cairo | 1 + 2 files changed, 32 insertions(+), 37 deletions(-) diff --git a/src/student_registry.cairo b/src/student_registry.cairo index ff325c8..0fb6e3a 100644 --- a/src/student_registry.cairo +++ b/src/student_registry.cairo @@ -9,11 +9,18 @@ pub trait IStudentRegistry { ) -> bool; // read-only function to get student - fn get_student(self: @T, account: ContractAddress) -> (felt252, ContractAddress, u8, u16, bool); + fn get_student(self: @T, student_id: u64) -> (u64, felt252, ContractAddress, u8, u16, bool); // fn get_all_students(self: @T) -> Span; fn get_all_students(self: @T) -> Span; + // state-change function to update student data fn update_student( - ref self: T, _name: felt252, _account: ContractAddress, _age: u8, _xp: u16, _is_active: bool + ref self: T, + _id: u64, + _name: felt252, + _account: ContractAddress, + _age: u8, + _xp: u16, + _is_active: bool ) -> bool; } @@ -25,18 +32,14 @@ pub mod StudentRegistry { use core::num::traits::Zero; use starknet::storage::{ - StoragePointerReadAccess, StoragePointerWriteAccess, Vec, VecTrait, MutableVecTrait, - StoragePathEntry, Map + StoragePointerReadAccess, StoragePointerWriteAccess, Vec, VecTrait, MutableVecTrait }; use crate::errors::Errors; #[storage] struct Storage { admin: ContractAddress, - students_map: Map::, - students_vector: Vec, - students_index: Map::, - total_no_of_students: u64 + students_vector: Vec } @@ -60,51 +63,42 @@ pub mod StudentRegistry { ) -> bool { // validation to check if student account is valid address and not a 0 address assert(!self.is_zero_address(_account), Errors::ZERO_ADDRESS); + // validate student age assert(_age > 0, 'age cannot be 0'); + + // set student vector length as new student Id + let _id = self.students_vector.len(); let student = Student { - name: _name, account: _account, age: _age, xp: _xp, is_active: _is_active + id: _id, name: _name, account: _account, age: _age, xp: _xp, is_active: _is_active }; - // add new student to storage - self.students_map.entry(_account).write(student); - - // keep track of student's account address - self.students_vector.append().write(_account); - - // keep track of the student index - self.students_index.entry(self.total_no_of_students.read()).write(_account); - - // increase student's count - self.total_no_of_students.write(self.total_no_of_students.read() + 1); + // append student data to the students vector + self.students_vector.append().write(student); true } // read-only function to get student fn get_student( - self: @ContractState, account: ContractAddress - ) -> (felt252, ContractAddress, u8, u16, bool) { + self: @ContractState, student_id: u64 + ) -> (u64, felt252, ContractAddress, u8, u16, bool) { // validation to check if account is valid - assert(!self.is_zero_address(account), Errors::ZERO_ADDRESS); - let student = self.students_map.entry(account).read(); - (student.name, student.account, student.age, student.xp, student.is_active) + assert(student_id > 0, 'id cannot < 0'); + let student = self.students_vector.at(student_id).read(); + (student.id, student.name, student.account, student.age, student.xp, student.is_active) } fn get_all_students(self: @ContractState) -> Span { // empty array to store students let mut all_students: Array = array![]; - // loop through the students vector containing the accounts of the student and use the - // account to get and return the student details + // loop through the students vector and append each student data to the students array for i in 0 ..self .students_vector .len() { // append each student details to the students array - all_students - .append( - self.students_map.entry(self.students_vector.at(i).read()).read() - ); + all_students.append(self.students_vector.at(i).read()); }; all_students.span() @@ -112,6 +106,7 @@ pub mod StudentRegistry { fn update_student( ref self: ContractState, + _id: u64, _name: felt252, _account: ContractAddress, _age: u8, @@ -120,14 +115,13 @@ pub mod StudentRegistry { ) -> bool { // validation to check if account is valid assert(!self.is_zero_address(_account), Errors::ZERO_ADDRESS); - let old_student: Student = self.students_map.entry(_account).read(); - // validation to check if student exist - assert(old_student.age > 0, Errors::STUDENT_NOT_REGISTERED); + let mut student_pointer = self.students_vector.at(_id); let new_student = Student { - name: _name, account: _account, age: _age, xp: _xp, is_active: _is_active + id: _id, name: _name, account: _account, age: _age, xp: _xp, is_active: _is_active }; - // update student info - self.students_map.entry(_account).write(new_student); + + // update student data + student_pointer.write(new_student); true } diff --git a/src/student_struct.cairo b/src/student_struct.cairo index da29bb4..5efa94b 100644 --- a/src/student_struct.cairo +++ b/src/student_struct.cairo @@ -1,6 +1,7 @@ use starknet::ContractAddress; #[derive(Drop, Serde, starknet::Store)] pub struct Student { + pub id: u64, pub name: felt252, pub account: ContractAddress, pub age: u8,