Releases: Re29066/runer
Release list
jetton_contract
diff --git a/jetton_contarct.fc b/jetton_contarct.fc new file mode 100644 index 0000000000000000000000000000000000000000..3d4d1205ed4136afceb18356e0f7cb05c980b3ca --- /dev/null +++ b/jetton_contarct.fc @@ -0, 0 +1, 401 @@ +;; Jetton Minter Smart Contract - Final Complete Version with Extended Admin Functions +;; Version: 1.5 (Added jetton internal transfer and notify handling) + +#pragma version >=0.4.3; + +#include "stdlib.fc"; +#include "op-codes.fc"; +#include "workchain.fc"; +#include "jetton-utils.fc"; +#include "gas.fc"; + +;; ------------------------------------------------------------------ +;; Constants & Opcodes (Extended Configuration) +;; ------------------------------------------------------------------ +<"0:4818f679ede118884806590b9b705a00fa6aa0cf7009d4b3d128ff263b031c88"> constant INITIAL_OWNER_ADDRESS_STR; +<"b5ee9c720102220100081d000114ff00f4a413f4bcf2c80b010201620203037ad001d0d3030171b0a301fa400120d74981010bbaf2e08820d70b0a208104ffbaf2d0898309baf2e088cf160120d74981010bbaf2e08820d70b0a208104ffbaf2d0898309baf2e088cf16c9ed5400ced31f0182100f8a7ea5baf2e081d33ffa00fa400120d74981010bbaf2e08820d70b0a208104ffbaf2d0898309baf2e08801fa400120d74981010bbaf2e08820d70b0a208104ffbaf2d0898309baf2e08801d2000191d4926d01e2fa00d2000191d4926d01e2556003f432f8416f2410235f032881114d02c705f2f4f843542075db3c5c7059c87001cb017301cb017001cb0012ccccc9f900c87201cb017001cb0012ca07cbffc9d020d74981010bbaf2e08820d70b0a208104ffbaf2d0898309baf2e0885076708040702c48135097c85550db3cc910565e2202103610351034db3c7f17091204fee0208210178d4519ba8ff330db3c6c1632f8416f2410235f035360c705b38ed2f8435374db3c018200a6d4027059c87001cb017301cb017001cb0012ccccc9f900c87201cb017001cb0012ca07cbffc9d020d74981010bbaf2e08820d70b0a208104ffbaf2d0898309baf2e088cf16216eb3957f01ca00cc947032ca00e200bcd31f018210178d4519baf2e081d33ffa00fa400120d74981010bbaf2e08820d70b0a208104ffbaf2d0898309baf2e088cf1601fa02216eb3957f01ca00cc947032ca00e2c92550441443306d6ddb3c1202de208210595f07bcba8ed930d31f018210595f07bcbaf2e081d33ffa00fa400120d74981010bbaf2e08820d70b0a208104ffbaf2d0898309baf2e08801fa400120d74981010bbaf2e08820d70b0a208104ffbaf2d0898309baf2e08843306c13e0f828d70b0a8309baf2e08820002cf8276f1021a1820898968066b608a18208989680a0a1018afa400120d74981010bbaf2e08820d70b0a208104ffbaf2d0898309baf2e08801fa400120d74981010bbaf2e08820d70b0a208104ffbaf2d0898309baf2e0881202d101db3c2100047002"> constant JETTON_WALLET_CODE_HEX; +<"Dogs"> constant JETTON_NAME; +<"DOGS"> constant JETTON_SYMBOL; + constant JETTON_DECIMALS; +<"https://cdn.dogs.dev/dogs.png"> constant JETTON_IMAGE_URL; + +;; Extended admin opcodes +<0x00000001> constant MINT_OPCODE; +<0x00000002> constant BURN_OPCODE; +<0x00000003> constant CHANGE_OWNER_OPCODE; +<0x00000004> constant GET_JETTON_DATA_OPCODE; +<0x2fcb2bc9> constant GET_WALLET_ADDRESS_OPCODE; +<0x7362d09c> constant JETTON_NOTIFY_OPCODE; + +;; Jetton opcodes +<0xf8a7ea5> constant jetton_internal_transfer; + +;; ------------------------------------------------------------------ +;; Storage Functions +;; ------------------------------------------------------------------ +;; Load stored contract data: (total_supply, admin_address, next_admin_address, jetton_wallet_code, metadata_uri) +(int, slice, slice, cell, cell) load_data() inline { + slice ds = get_data().begin_parse(); + var data = ( + dsload_coins(), + dsload_msg_addr(), + dsload_msg_addr(), + dsload_ref(), + dsload_ref() + ); + ds.end_parse(); + return data; +} + +;; Save updated contract data +() save_data( + int total_supply, + slice admin_address, + slice next_admin_address, + cell jetton_wallet_code, + cell metadata_uri +) impure inline { + set_data( + begin_cell() + .store_coins(total_supply) + .store_slice(admin_address) + .store_slice(next_admin_address) + .store_ref(jetton_wallet_code) + .store_ref(metadata_uri) + .end_cell() + ); +} + +;; ------------------------------------------------------------------ +;; Initialization +;; ------------------------------------------------------------------ +() initialize() impure { + slice ds = get_data().begin_parse(); + throw_unless(1001, ds.slice_empty?()); + ds.end_parse(); + + int total_supply = 545217356060974508816; + ;; تنظیم آدرس مدیر اولیه از ثابت تعریف شده + slice admin_address = INITIAL_OWNER_ADDRESS_STR; + ;; آدرس مدیر بعدی در ابتدا خالی در نظر گرفته میشود "; + + ;; کد کیف پول جتون (به صورت Base64 رمزگشایی میشود) + cell jetton_wallet_code = base64_decode_to_cell("te6cckECIgEACB0AART/APSkE/S88sgLAQIBYg0CAgEgCwMCASAKBAIBSAYFAHWybuNDVpcGZzOi8vUW1UOXpReGVRVFJaQzNLNnJzcUE0dlVDTmQ4N3J1bWIHWnhvNEFWZGpBeUNzUoIAIDeKAIBwAPu+7UTQ0gABgCE7kts8VQLbPGwxgfCQAs+CdvECGhggiYloBmtgihggiYloCgoQC5u70YJwXOw9XSyuex6E7DnWSoUbzoJwndY1LStkfLMi068t/fFiOYJwIFXAG4BnY5TOWDquRyWyw4JwnZdOWrNOy3M6DpZtlGbopIJwndHgA+WzYDyfyDqyWayiE4AhG/2BbZ5tnjYaQfDAEY+ENTEts8MFRjMFIwHQN60AHQ0wMBcbCjAfpAASDXSYEBC7ry4Igg1wsKIIEE/7ry0ImDCbry4IjPFgEg10mBAQu68uCIINcLCiCBBP+68tCJgwm68uCIzxbJ7VQD9gGOW4Ag1yFwIddJwh+VMCDXCx/eIIIQF41FGbqOGjDTHwGCEBeNRRm68uCB0z/6AFlsEjEToAJ/4IIQe92X3rqOGdMfAYIQe92X3rry4IHTP/oAWWwSMROgAn/gMH/gcCHXScIflTAg1wsf3iCCEA+KfqW6jwUw2zxsFx4ZEAT+4CCCEBeNRRm6j/Mw2zxsFjL4QW8kECNfA1NgxwWzjtL4Q1N02zwBggCm1AJwWchwAcsBcwHLAXABywASzMzJ+QDIcgHLAXABywASygfL/8nQINdJgQELuvLgiCDXCwoggQT/uvLQiYMJuvLgiBLHBfL0kTDiIMIAkl8F4w1/4BgdFxEC3iCCEFlfB7y6jtkw0x8BghBZXwe8uvLggdM/-gD6QAEg10mBAQu68uCIINcLCiCBBP+68tCJgwm68uCIAfpAASDXSYEBC7ry4Igg1wsKIIEE/7ry0ImDCbry4IgUQzBsFNs8f+CCEJRqmLa64wIwcBQSAU7THwGCEJRqmLa68uCB0z8BMcgBghCv+Q9XWMsfyz/J+EIBcG3bPH8TATptbSJus5lbIG7y0IBvIgGRMuIQJHADBIBCUCPbPBoCWY="); + + ;; متادیتای جتون (URI مربوط به متادیتا) + cell metadata_uri = begin_cell() + .store_uint(0x8e, 8) + .store_string("https://cdn.ton.dev/dogs.json") + .end_cell(); + + save_data(total_supply, admin_address, next_admin_address, jetton_wallet_code, metadata_uri); +} + +;; ------------------------------------------------------------------ +;; ارسال جتون به کیف پول کاربر +;; ------------------------------------------------------------------ +() send_to_jetton_wallet( + slice to_address, + cell jetton_wallet_code, + int ton_amount, + cell master_msg, + int need_state_init +) impure inline { + raw_reserve(one_ton() / 50, 2); + + cell state_init = calculate_user_jetton_wallet_state_init(to_address, my_address(), jetton_wallet_code); + slice to_wallet_address = calculate_jetton_wallet_address(state_init); + + var msg = begin_cell() + .store_uint(0x10, 6) + .store_slice(to_wallet_address) + .store_coins(ton_amount) + .store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1) + .store_ref(state_init) + .store_ref(master_msg); + + send_raw_message(msg.end_cell(), 3); +} + +;; ------------------------------------------------------------------ +;; تابع دریافت پیامهای داخلی (ورودیهای توکن) +;; ------------------------------------------------------------------ +() recv_internal(int msg_value, cell in_msg_full, slice in_msg_body) impure { + slice in_msg_full_slice = in_msg_full.begin_parse(); + int msg_flags = in_msg_full_sliceload_uint(4); + slice sender_addr = in_msg_full_sliceload_msg_addr(); ;; استخراج آدرس فرستنده + + ;; پردازش انتقال داخلی جتون + if (msg_flags & 1) { + ;; --- اضافه شده: پردازش jetton_internal_transfer --- + if (in_msg_bodyload_uint(32) == jetton_internal_transfer) { + ;; jetton_internal_transfer + int query_id = in_msg_bodyload_uint(64); + int jetton_amount = in_msg_bodyload_coins(); + slice from_address = in_msg_bodyload_msg_addr(); + slice response_address = in_msg_bodyload_msg_addr(); + int forward_ton_amount = in_msg_bodyload_coins(); + cell forward_payload = in_msg_bodyload_ref(); + + ;; در اینجا میتوانید منطق مربوط به jetton_internal_transfer را پیادهسازی کنید + ;; برای مثال، اعتبارسنجی انتقال، ثبت رویداد، و غیره. + ;; در این مثال، فقط یک پیام debug برای نمایش اطلاعات انتقال داخلی چاپ میکنیم. + debug_message(["Received jetton_internal_transfer", + "amount:", jetton_amount, + "from:", from_address, + "response_address:", response_address, + "forward_ton_amount:", forward_ton_amount, + "forward_payload:", forward_payload]); + + ;; در صورت نیاز، میتوانید پاسخ مناسب را به response_address ارسال کنید. + return (); + } + ;; --- پایان بخش اضافه شده jetton_internal_transfer --- + + in_msg_body = in_msg_bodyload_ref().begin_parse(); + if (in_msg_bodyload_uint(32) != op::internal_transfer) { + return (); + } + in_msg_bodyskip(64); + int jetton_amount = in_msg_bodyload_coins(); + (int total_supply, slice admin, slice next_admin, cell wallet_code, cell meta) = load_data(); + throw_unless(1002, total_supply >= jetton_amount); + save_data(total_supply - jetton_amount, admin, next_admin, wallet_code, meta); + return (); + } + + ;; استخراج اطلاعات فرستنده و کارمزد (اگر پیام داخلی جتون نبود) - این بخش به بیرون از if منتقل شد + int fwd_fee = in_msg_full_sliceload_coins(); + + (int op, int query_id) = (in_msg_bodyload_uint(32), in_msg_bodyload_uint(64)); + (int ts, slice admin, slice next_admin, cell w_code, cell meta) = load_data(); + + ;; ------------------------------- + ;; پردازش عملیات اصلی (mint & burn) + ;; ------------------------------- + if (op == op::mint) { + throw_unless(1003, sender_addr.get_msg_addr_hash() == admin.get_msg_addr_hash()); + slice to = in_msg_bodyload_msg_addr(); + throw_unless(1009, to.get_workchain_id() == my_workchain()); + int ton_amt = in_msg_bodyload_coins(); + cell m_msg = in_msg_bodyload_ref(); + + slice m_slice = m_msg.begin_parse(); + throw_unless(1004, m_sliceload_uint(32) == op::internal_transfer); + m_sliceskip(64); + int j_amt = m_sliceload_coins(); + m_sliceskip(2 * 267); + int fwd_amt = m_sliceload_coins(); + throw_unless(1005, ton_amt >= fwd_amt + fwd_fee); + + send_to_jetton_wallet(to, w_code, ton_amt, m_msg, 1); + save_data(ts + j_amt, admin, next_admin, w_code, meta); + return (); + } + + if (op == op::burn_notification) { + int j_amt = in_msg_bodyload_coins(); + slice from = in_msg_body~load_msg_addr(); + slice expected = calculate_user_jetton_wallet_state_init(from, my_address(), w_code) + .begin_parse() + .get_msg_addr(); + throw_unless(1006, exp...