;; =============== storage ============================= ;; storage binary format is defined as TL-B in companion .tlb file (slice, int) load_data() inline { var ds = get_data().begin_parse(); return ( ds~load_msg_addr(), ;; owner_address ds~load_uint(64) ;; counter ); } () save_data(slice owner_address, int counter) impure inline { set_data(begin_cell() .store_slice(owner_address) .store_uint(counter, 64) .end_cell()); } ;; =============== messages ============================= ;; message binary format is defined as TL-B in companion .tlb file () op_withdraw(int withdraw_amount, slice owner_address) impure; () recv_internal(int msg_value, cell in_msg, slice in_msg_body) impure { ;; parse incoming internal message slice cs = in_msg.begin_parse(); int flags = cs~load_uint(4); ;; int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool slice sender_address = cs~load_msg_addr(); ;; handle bounced messages if (flags & 1) { return (); ;; ignore } ;; load from contract storage var (owner_address, counter) = load_data(); ;; handle operations int op = in_msg_body~load_uint(32); int query_id = in_msg_body~load_uint(64); if (op == op::increment()) { save_data(owner_address, counter + 1); return (); } if (op == op::deposit()) { ;; empty since ton received (msg_value) is added automatically to contract balance ;; ~dump msg_value; ;; an example of debug output, requires running contract in debug mode return (); } if (op == op::withdraw()) { throw_unless(error::access_denied(), equal_slices(sender_address, owner_address)); int withdraw_amount = in_msg_body~load_coins(); op_withdraw(withdraw_amount, owner_address); return (); } if (op == op::transfer_ownership()) { throw_unless(error::access_denied(), equal_slices(sender_address, owner_address)); slice new_owner_address = in_msg_body~load_msg_addr(); save_data(new_owner_address, counter); return (); } throw(error::unknown_op()); } () op_withdraw(int withdraw_amount, slice owner_address) impure { var [balance, _] = get_balance(); throw_unless(error::insufficient_balance(), balance >= withdraw_amount); int return_value = min(withdraw_amount, balance - const::min_tons_for_storage()); send_grams(owner_address, return_value); } ;; =============== getters ============================= int meaning_of_life() method_id { return 42; } slice owner_address() method_id { var (owner_address, _) = load_data(); return owner_address; } int counter() method_id { var (_, counter) = load_data(); return counter; } int balance() method_id { var [balance, _] = get_balance(); return balance; }