forked from mjtbkh/starknet-cairo-101
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ex09.cairo
98 lines (81 loc) · 2.83 KB
/
ex09.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
######### Ex 09
## Recursions - advanced
# In this exercice, you need to:
# - Use this contract's claim_points() function
# - Your points are credited by the contract
%lang starknet
%builtins pedersen range_check
from starkware.cairo.common.cairo_builtins import HashBuiltin
from starkware.cairo.common.math import (assert_not_zero, assert_le)
from starkware.starknet.common.syscalls import (get_caller_address)
from contracts.utils.ex00_base import (
tderc20_address,
has_validated_exercise,
distribute_points,
validate_exercise,
ex_initializer
)
#
# View functions
#
@view
func get_sum{syscall_ptr : felt*, pedersen_ptr : HashBuiltin*, range_check_ptr}(array_len: felt, array: felt*) -> (array_sum: felt):
let (array_sum) = get_sum_internal(array_len, array)
return (array_sum)
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
# Calling this function will simply credit 2 points to the address specified in parameter
#
@external
func claim_points{syscall_ptr : felt*, pedersen_ptr : HashBuiltin*, range_check_ptr}(array_len: felt, array: felt*):
# Checking that the array is at least of length 4
assert_le(4, array_len)
# Calculating the sum of the array sent by the user
let (array_sum) = get_sum_internal(array_len, array)
# The sum should be higher than 50
assert_le ( 50, array_sum)
# Reading caller address
let (sender_address) = get_caller_address()
# 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
#
# Internal functions
#
#
func get_sum_internal{ range_check_ptr}(length : felt, array : felt*) -> (sum : felt):
# This function is used recursively to calculate the sum of all the values in an array
# Recursively, we first go through the length of the array
# Once at the end of the array (length = 0), we start summing
if length == 0:
# Start with sum=0.
return (sum=0)
end
# If length is NOT zero, then the function calls itself again, by moving forward one slot
let (current_sum) = get_sum_internal(length=length - 1, array=array + 1)
# This part of the function is first reached when length=0.
# Checking that the first value in the array ([array]) is not 0
assert_not_zero([array])
# The sum begins
let sum = [array] + current_sum
assert_le(current_sum * 2, sum)
# The return function targets the body of this function
return (sum)
end