Created
August 9, 2023 21:42
-
-
Save codeWhizperer/55a8451ff67ca89c0b4464d804e6a5bb 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 | |
| // TODO: set new_progress for user, | |
| let caller = get_caller_address(); | |
| assert(caller == self.contract_owner.read(), 'not owner'); | |
| // 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; | |
| use starknet::testing::set_caller_address; | |
| #[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'); | |
| // Call contract as owner | |
| // set_caller_address(owner); | |
| starknet::testing::set_caller_address(owner); | |
| let dispatcher = deploy_contract(); | |
| // 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