more mass renaming
This commit is contained in:
@@ -0,0 +1,145 @@
|
||||
/**
|
||||
* Example gym subscription contract
|
||||
*
|
||||
* Copyright (C) 2025, QPQ AG. All Rights Reserved.
|
||||
*
|
||||
* Owner can
|
||||
* - run "tick" to collect monthly fees -> spent to owner
|
||||
* - unsubscribe anyone
|
||||
*
|
||||
* Anyone can
|
||||
* - subscribe for a period of N months (debit system - all money paid up front)
|
||||
* - extend their subscription for K months
|
||||
* - cancel their subscription and withdraw any future money
|
||||
*
|
||||
* Owner must issue new contract if he wants to change monthly fee; otherwise
|
||||
* data structure is too fucking complicated.
|
||||
*/
|
||||
|
||||
include "List.aes"
|
||||
|
||||
payable contract Gym =
|
||||
type pucks = int
|
||||
type n_months = int
|
||||
record state = {owner : address,
|
||||
members : map(address, n_months),
|
||||
monthly_fee : pucks}
|
||||
|
||||
// SFP accessors
|
||||
entrypoint
|
||||
get_state : () => state
|
||||
get_state() = state
|
||||
stateful entrypoint
|
||||
put_state : state => unit
|
||||
put_state(s) = put(s)
|
||||
|
||||
entrypoint
|
||||
is_member : address => bool
|
||||
is_member(whomst) = Map.member(whomst, state.members)
|
||||
|
||||
entrypoint
|
||||
owner : () => address
|
||||
owner() = state.owner
|
||||
|
||||
entrypoint
|
||||
members : () => map(address, pucks)
|
||||
members() = state.members
|
||||
|
||||
entrypoint
|
||||
monthly_fee : () => pucks
|
||||
monthly_fee() = state.monthly_fee
|
||||
|
||||
|
||||
// actual things
|
||||
entrypoint
|
||||
init : (pucks) => state
|
||||
init(monthly_rate) =
|
||||
require(monthly_rate >= 0, "monthly rate must be non-negative")
|
||||
{owner = Call.caller,
|
||||
members = {},
|
||||
monthly_fee = monthly_rate}
|
||||
|
||||
//------------------------------------------------
|
||||
// OWNER ENTRYPOINTS: tick/ban
|
||||
//------------------------------------------------
|
||||
|
||||
stateful entrypoint
|
||||
tick : () => unit
|
||||
tick() | Call.caller != state.owner =
|
||||
abort("you are not allowed to do ticks!")
|
||||
tick() =
|
||||
// collect fees
|
||||
// 1 monthly charge per member
|
||||
let total_charge = state.monthly_fee * Map.size(state.members)
|
||||
Chain.spend(state.owner, total_charge)
|
||||
|
||||
// update members list (clean out everyone with just 1 month left)
|
||||
let old_members_list : list(address * n_months) = Map.to_list(state.members)
|
||||
let new_members_list : list(address * n_months) = List.foldl(deduct_month, [], old_members_list)
|
||||
let new_members : map(address, n_months) = Map.from_list(new_members_list)
|
||||
let new_state : state = state{members = new_members}
|
||||
put(new_state)
|
||||
|
||||
function
|
||||
deduct_month : (list(address*n_months), address*n_months) => list(address*n_months)
|
||||
// n>1 months left -> subtract a month but keep in membership list
|
||||
deduct_month(acc, (patron, months_left)) | months_left > 1 =
|
||||
(patron, months_left-1) :: acc
|
||||
// only 1 month left -> remove from membership list
|
||||
deduct_month(acc, (patron, 1)) =
|
||||
acc
|
||||
|
||||
stateful entrypoint
|
||||
ban : (address) => unit
|
||||
ban(_) | Call.caller != state.owner =
|
||||
abort("you are not allowed to ban people!")
|
||||
ban(patron) =
|
||||
refund(patron)
|
||||
|
||||
|
||||
//------------------------------------------------
|
||||
// PUBLIC ENTRYPOINTS: subscribe/cancel
|
||||
//------------------------------------------------
|
||||
|
||||
payable stateful entrypoint
|
||||
subscribe : (n_months) => unit
|
||||
subscribe(n) | n < 1 =
|
||||
abort("must subscribe for at least 1 month")
|
||||
subscribe(n) | Call.value < n*state.monthly_fee =
|
||||
abort("not enough money to subscribe for that many months!")
|
||||
subscribe(n) =
|
||||
let charge: pucks = n * state.monthly_fee
|
||||
// call will be successful
|
||||
// refund caller extra money
|
||||
let extra_money: pucks = Call.value - charge
|
||||
Chain.spend(Call.caller, extra_money)
|
||||
// update membership
|
||||
let old_months : n_months = Map.lookup_default(Call.caller, state.members, 0)
|
||||
let new_months : n_months = old_months + n
|
||||
let new_members : map(address, n_months) = state.members{[Call.caller] = new_months}
|
||||
let new_state : state = state{members = new_members}
|
||||
put(new_state)
|
||||
|
||||
stateful entrypoint
|
||||
cancel : () => unit
|
||||
cancel() =
|
||||
refund(Call.caller)
|
||||
|
||||
//------------------------------------------------
|
||||
// INTERNAL: refund people
|
||||
//------------------------------------------------
|
||||
|
||||
stateful function
|
||||
refund : (address) => unit
|
||||
refund(patron) =
|
||||
let patron_months : n_months =
|
||||
switch (Map.lookup(patron, state.members))
|
||||
None => abort("already not a member!")
|
||||
Some(remaining_months) => remaining_months
|
||||
let patron_balance : pucks = patron_months * state.monthly_fee
|
||||
// update membership
|
||||
let new_members : map(address, n_months) = Map.delete(patron, state.members)
|
||||
let new_state : state = state{members = new_members}
|
||||
put(new_state)
|
||||
// refund balance to patron
|
||||
Chain.spend(patron, patron_balance)
|
||||
Reference in New Issue
Block a user