-
Notifications
You must be signed in to change notification settings - Fork 22
/
Copy pathSpendToMany.aes
48 lines (40 loc) · 2.21 KB
/
SpendToMany.aes
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
@compiler >= 6
contract SpendToMany =
// recipients_and_tokens is a map of {[publicKey1_in_hex] = some_tokens1 , ... [publicKeyN_in_hex] = some_tokensN}
payable stateful entrypoint spend_to_many(recipients_and_tokens : map(address, int)) : int =
let recipients_and_tokens_list = Map.to_list(recipients_and_tokens) // transform incoming map to list of tuples
require(validate_expenses(recipients_and_tokens_list), "The balance given to perform this action is not sufficient")
let sent_tokens = spend_to_many'(recipients_and_tokens_list, 0, Call.value)
let excess_tokens = Call.value - sent_tokens
if(excess_tokens > 0) // check if there are excess tokens
Chain.spend(Call.caller, excess_tokens) // return excess amount of tokens back to the caller
sent_tokens
// traverse through list of maps
stateful function spend_to_many'(list, total_tokens_spend, amount_left) : int =
switch(list)
[] => total_tokens_spend
(address, tokens) :: l' =>
require(amount_left >= tokens, "Not enough tokens! Aborting") // if for some reason amount of tokens is not enough, the recursion will be aborted
Chain.spend(address,tokens)
spend_to_many'(l', total_tokens_spend + tokens, amount_left - tokens)
// comparing possible expenses and given tokens
function validate_expenses(recipients_and_tokens) : bool =
sum((x) => x, pre_process_expenses(recipients_and_tokens,[])) =< Call.value
/* traversing through values of given list of tuples(in the other words, tokens),
returns a list of integers, in order to calculate them later in sum(f,l) private function. */
function pre_process_expenses(recipients_and_tokens, expenses) : list(int) =
switch(recipients_and_tokens)
[] => expenses
(_ , tokens) :: l' =>
pre_process_expenses(l', tokens :: expenses)
// traverses through list, returns a sum of elements
function sum(f : 'a => int, l : list('a)) : int =
foldr((x, y) => x + y, 0, map(f, l))
function foldr(f : (('a, 'b) => 'b), z: 'b, l : list('a)) : 'b =
switch(l)
[] => z
e :: l' => f(e, foldr(f, z, l'))
function map(f : 'a => 'b, l : list('a)) : list('b) =
switch(l)
[] => []
e :: l' => f(e) :: map(f, l')