forked from starknet-edu/starknet-cairo-101
-
Notifications
You must be signed in to change notification settings - Fork 10
/
ex03.cairo
113 lines (99 loc) · 3.65 KB
/
ex03.cairo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# ######## Ex 03
# Using contract functions to manipulate contract variables
# In this exercice, you need to:
# - Use this contract's functions in order to manipulate an internal counter unique to your address
# - Once this counter reaches a certain value, call a specific function
# - Your points are credited by the contract
# # What you'll learn
# - How to declare mappings
# - How to read and write to mappings
# - How to use a function to manipulate storage variables
# ######## General directives and imports
#
#
%lang starknet
from starkware.starknet.common.syscalls import get_caller_address
from starkware.cairo.common.cairo_builtins import HashBuiltin
from contracts.utils.ex00_base import (
tderc20_address,
has_validated_exercise,
distribute_points,
validate_exercise,
ex_initializer,
)
#
# Declaring storage vars
# Storage vars are by default not visible through the ABI. They are similar to "private" variables in Solidity
#
# Declaring a mapping called user_counters_storage. For each 'account' key, which is a felt, we store a value which is a felt also.
@storage_var
func user_counters_storage(account : felt) -> (user_counters_storage : felt):
end
#
# Declaring getters
# Public variables should be declared explicitly with a getter
#
# Declaring a getter for our mappings. It takes one argument as a parameter, the account you wish to read the counter of
@view
func user_counters{syscall_ptr : felt*, pedersen_ptr : HashBuiltin*, range_check_ptr}(
account : felt
) -> (user_counter : felt):
let (user_counter) = user_counters_storage.read(account)
return (user_counter)
end
#
# Constructor
#
@constructor
func constructor{syscall_ptr : felt*, pedersen_ptr : HashBuiltin*, range_check_ptr}(
_tderc20_address : felt, _players_registry : felt, _workshop_id : felt, _exercise_id : felt
):
ex_initializer(_tderc20_address, _players_registry, _workshop_id, _exercise_id)
return ()
end
#
# External functions
#
@external
func claim_points{syscall_ptr : felt*, pedersen_ptr : HashBuiltin*, range_check_ptr}():
# Reading caller address
let (sender_address) = get_caller_address()
# Checking that user's counter is equal to 7
let (current_counter_value) = user_counters_storage.read(sender_address)
with_attr error_message("Counter is not equal to 7"):
assert current_counter_value = 7
end
# Checking if the user has validated the exercice before
validate_exercise(sender_address)
# Sending points to the address specified as parameter
distribute_points(sender_address, 2)
return ()
end
@external
func reset_counter{syscall_ptr : felt*, pedersen_ptr : HashBuiltin*, range_check_ptr}():
# Reading caller address
let (sender_address) = get_caller_address()
# Reinitializing the user counter
user_counters_storage.write(sender_address, 0)
return ()
end
@external
func increment_counter{syscall_ptr : felt*, pedersen_ptr : HashBuiltin*, range_check_ptr}():
# Reading caller address
let (sender_address) = get_caller_address()
# Reading counter from storage
let (current_counter_value) = user_counters_storage.read(sender_address)
# Writing updated value to storage
user_counters_storage.write(sender_address, current_counter_value + 2)
return ()
end
@external
func decrement_counter{syscall_ptr : felt*, pedersen_ptr : HashBuiltin*, range_check_ptr}():
# Reading caller address
let (sender_address) = get_caller_address()
# Reading counter from storage
let (current_counter_value) = user_counters_storage.read(sender_address)
# Writing updated value to storage
user_counters_storage.write(sender_address, current_counter_value - 1)
return ()
end