() send_tokens (slice in_msg_body, slice sender_address, int msg_value, int fwd_fee) impure { int query_id = in_msg_body~load_uint(64); int jetton_amount = in_msg_body~load_coins(); slice to_owner_address = in_msg_body~load_msg_addr(); force_chain(to_owner_address); (int balance, slice owner_address, slice jetton_master_address, cell jetton_wallet_code) = load_data(); balance -= jetton_amount; throw_unless(705, equal_slices(owner_address, sender_address)); throw_unless(706, balance >= 0); cell state_init = calculate_jetton_wallet_state_init(to_owner_address, jetton_master_address, jetton_wallet_code); slice to_wallet_address = calculate_jetton_wallet_address(state_init); slice response_address = in_msg_body~load_msg_addr(); cell custom_payload = in_msg_body~load_dict(); int forward_ton_amount = in_msg_body~load_coins(); throw_unless(708, slice_bits(in_msg_body) >= 1); slice either_forward_payload = in_msg_body; var msg = begin_cell() .store_uint(0x18, 6) .store_slice(to_wallet_address) .store_coins(0) .store_uint(4 + 2 + 1, 1 + 4 + 4 + 64 + 32 + 1 + 1 + 1) .store_ref(state_init); var msg_body = begin_cell() .store_uint(op::internal_transfer(), 32) .store_uint(query_id, 64) .store_coins(jetton_amount) .store_slice(owner_address) .store_slice(response_address) .store_coins(forward_ton_amount) .store_slice(either_forward_payload) .end_cell(); msg = msg.store_ref(msg_body); int fwd_count = forward_ton_amount ? 2 : 1; throw_unless(709, msg_value > forward_ton_amount + ;; 3 messages: wal1->wal2, wal2->owner, wal2->response ;; but last one is optional (it is ok if it fails) fwd_count * fwd_fee + (2 * gas_consumption() + min_tons_for_storage())); ;; universal message send fee calculation may be activated here ;; by using this instead of fwd_fee ;; msg_fwd_fee(to_wallet, msg_body, state_init, 15) send_raw_message(msg.end_cell(), 64); ;; revert on errors save_data(balance, owner_address, jetton_master_address, jetton_wallet_code); }