Last active
August 11, 2023 09:15
-
-
Save codeWhizperer/ce79b39aafda5c15c8731a7d703d6c6d to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // starknet3.cairo | |
| // Joe liked Jill's work very much. He really likes how useful storage can be. | |
| // Now they decided to write a contract to track the number of exercises they | |
| // complete successfully. Jill says they can use the owner code and allow | |
| // only the owner to update the contract, they agree. | |
| // Can you help them write this contract? | |
| // I AM NOT DONE | |
| use starknet::ContractAddress; | |
| #[starknet::interface] | |
| trait IProgressTracker<TContractState>{ | |
| fn set_progress(ref self:TContractState, user:ContractAddress, new_progress: u16); | |
| fn get_progress(self:@TContractState ,user: ContractAddress) -> u16; | |
| fn get_contract_owner(self:@TContractState) -> ContractAddress; | |
| } | |
| #[starknet::contract] | |
| mod ProgressTracker { | |
| use starknet::ContractAddress; | |
| use starknet::get_caller_address; // Required to use get_caller_address function | |
| #[storage] | |
| struct Storage { | |
| contract_owner: ContractAddress, | |
| // TODO: Set types for LegacyMap | |
| progress: LegacyMap<ContractAddress, u16> | |
| } | |
| #[constructor] | |
| fn constructor(ref self:ContractState,owner: ContractAddress) { | |
| self.contract_owner.write(owner); | |
| } | |
| #[external(v0)] | |
| impl ProgressTrackerImpl of super::IProgressTracker<ContractState>{ | |
| fn set_progress(ref self: ContractState, user: ContractAddress, new_progress: u16) { | |
| // TODO: assert owner is calling | |
| let caller = get_caller_address(); | |
| assert(caller == self.contract_owner.read(), 'not_owner'); | |
| // TODO: set new_progress for user, | |
| self.progress.write(user, new_progress); | |
| } | |
| fn get_progress(self:@ContractState ,user: ContractAddress) -> u16 { | |
| // Get user progress | |
| self.progress.read(user) | |
| } | |
| fn get_contract_owner(self:@ContractState) -> ContractAddress{ | |
| self.contract_owner.read() | |
| } | |
| } | |
| } | |
| #[cfg(test)] | |
| mod test { | |
| use starknet::ContractAddress; | |
| use array::ArrayTrait; | |
| use array::SpanTrait; | |
| use debug::PrintTrait; | |
| use traits::TryInto; | |
| use starknet::syscalls::deploy_syscall; | |
| use core::result::ResultTrait; | |
| use starknet::Felt252TryIntoContractAddress; | |
| use option::OptionTrait; | |
| use super::IProgressTrackerDispatcher; | |
| use super::IProgressTrackerDispatcherTrait; | |
| use super::ProgressTracker; | |
| #[test] | |
| #[available_gas(2000000000)] | |
| fn test_owner() { | |
| let owner: ContractAddress = 'Sensei'.try_into().unwrap(); | |
| let dispatcher = deploy_contract(); | |
| assert(owner == dispatcher.get_contract_owner(), 'Mr. Sensei should be the owner'); | |
| } | |
| #[test] | |
| #[available_gas(2000000000)] | |
| fn test_set_progress() { | |
| let owner = util_felt_addr('Sensei'); | |
| let dispatcher = deploy_contract(); | |
| // Call contract as owner | |
| starknet::testing::set_caller_address(owner); | |
| let owner = dispatcher.get_contract_owner(); | |
| owner.print(); | |
| // Set progress | |
| dispatcher.set_progress('Joe'.try_into().unwrap(), 20); | |
| dispatcher.set_progress('Jill'.try_into().unwrap(), 25); | |
| let joe_score = dispatcher.get_progress('Joe'.try_into().unwrap()); | |
| assert(joe_score == 20, 'Joe\'s progress should be 20'); | |
| } | |
| #[test] | |
| #[should_panic] | |
| #[available_gas(2000000000)] | |
| fn test_set_progress_fail() { | |
| let dispatcher = deploy_contract(); | |
| let jon_doe = util_felt_addr('JonDoe'); | |
| // Caller not owner | |
| starknet::testing::set_caller_address(jon_doe); | |
| // Try to set progress, should panic to pass test! | |
| dispatcher.set_progress('Joe'.try_into().unwrap(), 20); | |
| } | |
| fn util_felt_addr(addr_felt: felt252) -> ContractAddress { | |
| addr_felt.try_into().unwrap() | |
| } | |
| fn deploy_contract() -> IProgressTrackerDispatcher { | |
| let owner: felt252 = 'Sensei'; | |
| let mut calldata = ArrayTrait::new(); | |
| calldata.append(owner); | |
| let (address0, _) = deploy_syscall( | |
| ProgressTracker::TEST_CLASS_HASH.try_into().unwrap(), 0, calldata.span(), false | |
| ).unwrap(); | |
| let contract0 = IProgressTrackerDispatcher { contract_address: address0 }; | |
| contract0 | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment