type store is record [ goal : mutez; deadline : timestamp; backers : map (address, nat); funded : bool; ] function back (var store : store) : list (operation) * store is var operations : list (operation) := list [] begin if now > store.deadline then fail "Deadline passed"; else case store.backers[sender] of [ None -> store.backers[sender] := amount // or: None -> patch store.backers with map sender -> amount end | _ -> skip ] end with (operations, store) function claim (var store : store) : list (operation) * store is var operations : list (operation) := nil begin if now <= store.deadline then fail "Too soon." else case store.backers[sender] of None -> fail "Not a backer." | Some (amount) -> if balance >= store.goal or store.funded then fail "Goal reached: no refund." else begin operations := list [transaction (unit, sender, amount)]; remove sender from map store.backers end end end with (operations, store) function withdraw (var store : store) : list (operation) * store is var operations : list (operation) := list end begin if sender = owner then if now >= store.deadline then if balance >= store.goal then { store.funded := True; // or: patch store with record funded = True end; operations := list [Transfer (owner, balance)]; }; else fail "Below target." else fail "Too soon."; else skip end with (operations, store)