type store is record goal : nat; deadline : timestamp; backers : map (address, nat); funded : bool end entrypoint contribute (storage store : store; const sender : address; const amount : mutez) : store * list (operation) is var operations : list (operation) := [] begin if now > store.deadline then fail "Deadline passed" else case store.backers[sender] of None -> //store.backers[sender] := amount patch store.backers with map sender -> amount end | _ -> skip end end with (store, operations) entrypoint withdraw (storage store : store; const sender : address) : store * list (operation) is var operations : list (operation) := [] begin if sender = owner then if now >= store.deadline then if balance >= store.goal then begin patch store with record funded = True end; // patch store.funded with True end; // store.funded := True; operations := [Transfer (owner, balance)] end else fail "Below target" else fail "Too soon" else skip end with (store, operations) entrypoint claim (storage store : store; const sender : address) : store * list (operation) is var operations : list (operation) := [] var amount : mutez := 0 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 || store.funded then fail "Cannot refund" else begin operations := [Transfer (sender, amount)]; // patch store.backers without key sender; end end end with (store, operations)