Skip to content

Instantly share code, notes, and snippets.

@codeWhizperer
Created August 9, 2023 21:42
Show Gist options
  • Select an option

  • Save codeWhizperer/55a8451ff67ca89c0b4464d804e6a5bb to your computer and use it in GitHub Desktop.

Select an option

Save codeWhizperer/55a8451ff67ca89c0b4464d804e6a5bb to your computer and use it in GitHub Desktop.
// 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