Ton
122 строки · 4.6 Кб
1;; Jettons minter smart contract
2
3;; storage scheme
4;; storage#_ total_supply:Coins admin_address:MsgAddress content:^Cell jetton_wallet_code:^Cell = Storage;
5
6#include "imports/stdlib.fc";
7#include "imports/params.fc";
8#include "imports/constants.fc";
9#include "imports/jetton-utils.fc";
10#include "imports/op-codes.fc";
11#include "imports/utils.fc";
12#pragma version >=0.2.0;
13
14(int, slice, cell, cell) load_data() inline {
15slice ds = get_data().begin_parse();
16return (
17ds~load_coins(), ;; total_supply
18ds~load_msg_addr(), ;; admin_address
19ds~load_ref(), ;; content
20ds~load_ref() ;; jetton_wallet_code
21);
22}
23
24() save_data(int total_supply, slice admin_address, cell content, cell jetton_wallet_code) impure inline {
25set_data(begin_cell()
26.store_coins(total_supply)
27.store_slice(admin_address)
28.store_ref(content)
29.store_ref(jetton_wallet_code)
30.end_cell()
31);
32}
33
34() mint_tokens(slice to_address, cell jetton_wallet_code, int amount, cell master_msg) impure {
35cell state_init = calculate_jetton_wallet_state_init(to_address, my_address(), jetton_wallet_code);
36slice to_wallet_address = calculate_jetton_wallet_address(state_init);
37var msg = begin_cell()
38.store_uint(0x18, 6)
39.store_slice(to_wallet_address)
40.store_coins(amount)
41.store_uint(4 + 2 + 1, 1 + 4 + 4 + 64 + 32 + 1 + 1 + 1)
42.store_ref(state_init)
43.store_ref(master_msg);
44send_raw_message(msg.end_cell(), 1); ;; pay transfer fees separately, revert on errors
45}
46
47() recv_internal(int msg_value, cell in_msg_full, slice in_msg_body) impure {
48if (in_msg_body.slice_empty?()) { ;; ignore empty messages
49return ();
50}
51slice cs = in_msg_full.begin_parse();
52int flags = cs~load_uint(4);
53
54if (flags & 1) { ;; ignore all bounced messages
55return ();
56}
57slice sender_address = cs~load_msg_addr();
58
59int op = in_msg_body~load_uint(32);
60int query_id = in_msg_body~load_uint(64);
61
62(int total_supply, slice admin_address, cell content, cell jetton_wallet_code) = load_data();
63
64if (op == op::mint()) {
65throw_unless(73, equal_slices(sender_address, admin_address));
66slice to_address = in_msg_body~load_msg_addr();
67int amount = in_msg_body~load_coins();
68cell master_msg = in_msg_body~load_ref();
69slice master_msg_cs = master_msg.begin_parse();
70master_msg_cs~skip_bits(32 + 64); ;; op + query_id
71int jetton_amount = master_msg_cs~load_coins();
72mint_tokens(to_address, jetton_wallet_code, amount, master_msg);
73save_data(total_supply + jetton_amount, admin_address, content, jetton_wallet_code);
74return ();
75}
76
77if (op == op::burn_notification()) {
78int jetton_amount = in_msg_body~load_coins();
79slice from_address = in_msg_body~load_msg_addr();
80throw_unless(74,
81equal_slices(calculate_user_jetton_wallet_address(from_address, my_address(), jetton_wallet_code), sender_address)
82);
83save_data(total_supply - jetton_amount, admin_address, content, jetton_wallet_code);
84slice response_address = in_msg_body~load_msg_addr();
85if (response_address.preload_uint(2) != 0) {
86var msg = begin_cell()
87.store_uint(0x10, 6) ;; nobounce - int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool src:MsgAddress -> 011000
88.store_slice(response_address)
89.store_coins(0)
90.store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1)
91.store_uint(op::excesses(), 32)
92.store_uint(query_id, 64);
93send_raw_message(msg.end_cell(), 2 + 64);
94}
95return ();
96}
97
98if (op == 3) { ;; change admin
99throw_unless(73, equal_slices(sender_address, admin_address));
100slice new_admin_address = in_msg_body~load_msg_addr();
101save_data(total_supply, new_admin_address, content, jetton_wallet_code);
102return ();
103}
104
105if (op == 4) { ;; change content, delete this for immutable tokens
106throw_unless(73, equal_slices(sender_address, admin_address));
107save_data(total_supply, admin_address, in_msg_body~load_ref(), jetton_wallet_code);
108return ();
109}
110
111throw(0xffff);
112}
113
114(int, int, slice, cell, cell) get_jetton_data() method_id {
115(int total_supply, slice admin_address, cell content, cell jetton_wallet_code) = load_data();
116return (total_supply, -1, admin_address, content, jetton_wallet_code);
117}
118
119slice get_wallet_address(slice owner_address) method_id {
120(int total_supply, slice admin_address, cell content, cell jetton_wallet_code) = load_data();
121return calculate_user_jetton_wallet_address(owner_address, my_address(), jetton_wallet_code);
122}
123