Ton
416 строк · 12.5 Кб
1const int one_ton = 1000000000;
2const int dns_next_resolver_prefix = 0xba93; ;; dns_next_resolver prefix - https://github.com/ton-blockchain/ton/blob/7e3df93ca2ab336716a230fceb1726d81bac0a06/crypto/block/block.tlb#L819
3
4const int op::fill_up = 0x370fec51;
5const int op::outbid_notification = 0x557cea20;
6const int op::change_dns_record = 0x4eb1f0f9;
7const int op::dns_balance_release = 0x4ed14b65;
8
9const int op::telemint_msg_deploy = 0x4637289a;
10const int op::teleitem_msg_deploy = 0x299a3e15;
11const int op::teleitem_start_auction = 0x487a8e81;
12const int op::teleitem_cancel_auction = 0x371638ae;
13const int op::teleitem_bid_info = 0x38127de1;
14const int op::teleitem_return_bid = 0xa43227e1;
15const int op::teleitem_ok = 0xa37a0983;
16
17const int op::nft_cmd_transfer = 0x5fcc3d14;
18const int op::nft_cmd_get_static_data = 0x2fcb26a2;
19const int op::nft_cmd_edit_content = 0x1a0b9d51;
20const int op::nft_answer_ownership_assigned = 0x05138d91;
21const int op::nft_answer_excesses = 0xd53276db;
22
23const int op::ownership_assigned = 0x05138d91;
24const int op::excesses = 0xd53276db;
25const int op::get_static_data = 0x2fcb26a2;
26const int op::report_static_data = 0x8b771735;
27const int op::get_royalty_params = 0x693d3950;
28const int op::report_royalty_params = 0xa8cb00ad;
29
30const int err::invalid_length = 201;
31const int err::invalid_signature = 202;
32const int err::wrong_subwallet_id = 203;
33const int err::not_yet_valid_signature = 204;
34const int err::expired_signature = 205;
35const int err::not_enough_funds = 206;
36const int err::wrong_topup_comment = 207;
37const int err::unknown_op = 208;
38const int err::uninited = 210;
39const int err::too_small_stake = 211;
40const int err::expected_onchain_content = 212;
41const int err::forbidden_not_deploy = 213;
42const int err::forbidden_not_stake = 214;
43const int err::forbidden_topup = 215;
44const int err::forbidden_transfer = 216;
45const int err::forbidden_change_dns = 217;
46const int err::forbidden_touch = 218;
47const int err::no_auction = 219;
48const int err::forbidden_auction = 220;
49const int err::already_has_stakes = 221;
50const int err::auction_already_started = 222;
51const int err::invalid_auction_config = 223;
52const int err::incorrect_workchain = 333;
53const int err::no_first_zero_byte = 413;
54const int err::bad_subdomain_length = 70;
55
56const int min_tons_for_storage = one_ton;
57const int workchain = 0;
58
59int equal_slices(slice a, slice b) asm "SDEQ";
60int builder_null?(builder b) asm "ISNULL";
61builder store_builder(builder to, builder from) asm "STBR";
62slice zero_address() asm "b{00} PUSHSLICE";
63(slice, int) skip_first_zero_byte?(slice cs) asm "x{00} SDBEGINSQ";
64
65() force_chain(slice addr) impure inline {
66(int wc, _) = parse_std_addr(addr);
67throw_unless(err::incorrect_workchain, wc == workchain);
68}
69
70
71;; "ton\0test\0" -> "ton"
72int get_top_domain_bits(slice domain) inline {
73int i = -8;
74int char = 1;
75while (char) {
76i += 8;
77char = domain~load_uint(8); ;; we do not check domain.length because it MUST contains \0 character
78}
79throw_unless(201, i); ;; should not start with \0
80return i;
81}
82
83_ load_text(slice cs) inline {
84int len = cs~load_uint(8);
85slice text = cs~load_bits(len * 8);
86return (cs, text);
87}
88
89_ load_text_ref(slice cs) inline {
90slice text_cs = cs~load_ref().begin_parse();
91slice text = text_cs~load_text();
92return (cs, text);
93}
94
95builder store_text(builder b, slice text) inline {
96int len = slice_bits(text);
97(int bytes, int rem) = len /% 8;
98throw_if(err::invalid_length, rem);
99return b.store_uint(bytes, 8)
100.store_slice(text);
101}
102
103(slice, slice) unpack_token_info(cell c) inline {
104slice cs = c.begin_parse();
105var res = (
106cs~load_text(),
107cs~load_text()
108);
109cs.end_parse();
110return res;
111}
112
113cell pack_token_info(slice name, slice domain) {
114return begin_cell()
115.store_text(name)
116.store_text(domain)
117.end_cell();
118}
119
120cell pack_state_init(cell code, cell data) inline {
121return begin_cell()
122.store_uint(0, 2)
123.store_maybe_ref(code)
124.store_maybe_ref(data)
125.store_uint(0, 1)
126.end_cell();
127}
128
129cell pack_init_int_message(slice dest, cell state_init, cell body) inline {
130return begin_cell()
131.store_uint(0x18, 6) ;; 011000 tag=0, ihr_disabled=1, allow_bounces=1, bounced=0, add_none
132.store_slice(dest)
133.store_grams(0) ;; grams
134.store_uint(4 + 2 + 1, 1 + 4 + 4 + 64 + 32 + 1 + 1 + 1)
135.store_ref(state_init)
136.store_ref(body)
137.end_cell();
138}
139
140() send_msg(slice to_address, int amount, int op, int query_id, builder payload, int mode) impure inline {
141var msg = begin_cell()
142.store_uint(0x10, 6) ;; nobounce - int_msg_info$0 ihr_disabled:Bool bounce:Bool bounced:Bool src:MsgAddress -> 010000
143.store_slice(to_address)
144.store_grams(amount)
145.store_uint(0, 1 + 4 + 4 + 64 + 32 + 1 + 1)
146.store_uint(op, 32)
147.store_uint(query_id, 64);
148
149ifnot (builder_null?(payload)) {
150msg = msg.store_builder(payload);
151}
152
153send_raw_message(msg.end_cell(), mode);
154}
155
156slice calculate_address(int wc, cell state_init) inline {
157slice res = begin_cell()
158.store_uint(4, 3)
159.store_int(wc, 8)
160.store_uint(cell_hash(state_init), 256)
161.end_cell()
162.begin_parse();
163return res;
164}
165
166(int, slice) unpack_item_config(cell c) inline {
167slice cs = c.begin_parse();
168var res = (
169cs~load_uint(256),
170cs~load_msg_addr()
171);
172cs.end_parse();
173return res;
174}
175
176cell pack_item_config(int item_index, slice collection_address) inline {
177return begin_cell()
178.store_uint(item_index, 256)
179.store_slice(collection_address)
180.end_cell();
181}
182
183(cell, cell) unpack_item_data() inline {
184var cs = get_data().begin_parse();
185var res = (cs~load_ref(), cs~load_maybe_ref());
186cs.end_parse();
187return res;
188}
189
190cell pack_nft_royalty_params(int numerator, int denominator, slice destination) inline {
191return begin_cell()
192.store_uint(numerator, 16)
193.store_uint(denominator, 16)
194.store_slice(destination)
195.end_cell();
196}
197
198(int, int, slice) unpack_nft_royalty_params(cell c) inline {
199var cs = c.begin_parse();
200var res = (
201cs~load_uint(16),
202cs~load_uint(16),
203cs~load_msg_addr()
204);
205cs.end_parse();
206return res;
207}
208
209cell pack_item_data(cell config, cell state) inline {
210return begin_cell()
211.store_ref(config)
212.store_maybe_ref(state)
213.end_cell();
214}
215
216cell pack_item_content(cell nft_content, cell dns, cell token_info) inline {
217return begin_cell()
218.store_ref(nft_content)
219.store_dict(dns)
220.store_ref(token_info)
221.end_cell();
222}
223
224(cell, cell, cell) unpack_item_content(cell c) inline {
225var cs = c.begin_parse();
226var res = (
227cs~load_ref(),
228cs~load_dict(),
229cs~load_ref()
230);
231cs.end_parse();
232return res;
233}
234
235(slice, cell, cell, cell) unpack_item_state(cell c) inline {
236var cs = c.begin_parse();
237var res = (
238cs~load_msg_addr(),
239cs~load_ref(),
240cs~load_maybe_ref(),
241cs~load_ref()
242);
243cs.end_parse();
244return res;
245}
246
247cell pack_item_state(slice owner_address, cell content, cell auction, cell royalty_params) inline {
248return begin_cell()
249.store_slice(owner_address)
250.store_ref(content)
251.store_maybe_ref(auction)
252.store_ref(royalty_params)
253.end_cell();
254}
255
256_ save_item_data(config, state) impure inline {
257set_data(pack_item_data(config, state));
258}
259
260cell pack_item_state_init(int item_index, cell item_code) inline {
261var item_config = pack_item_config(item_index, my_address());
262var item_data = pack_item_data(item_config, null());
263return pack_state_init(item_code, item_data);
264}
265
266cell pack_teleitem_msg_deploy(slice sender_address, int bid, cell info, cell content, cell auction_config, cell royalty_params) inline {
267return begin_cell()
268.store_uint(op::teleitem_msg_deploy, 32)
269.store_slice(sender_address)
270.store_grams(bid)
271.store_ref(info)
272.store_ref(content)
273.store_ref(auction_config)
274.store_ref(royalty_params)
275.end_cell();
276}
277
278(slice, int, cell, cell, cell, cell) unpack_teleitem_msg_deploy(slice cs) inline {
279return (cs~load_msg_addr(),
280cs~load_grams(),
281cs~load_ref(),
282cs~load_ref(),
283cs~load_ref(),
284cs~load_ref());
285}
286
287(int, int, int, cell, cell, slice, cell) unpack_collection_data() inline {
288var cs = get_data().begin_parse();
289var res = (
290cs~load_int(1), ;; touched
291cs~load_uint(32), ;; subwallet_id
292cs~load_uint(256), ;; owner_key
293cs~load_ref(), ;; content
294cs~load_ref(), ;; item_code
295cs~load_text_ref(), ;; full_domain
296cs~load_ref() ;; royalty_params
297);
298cs.end_parse();
299return res;
300}
301
302_ save_collection_data(int touched, int subwallet_id, int owner_key, cell content, cell item_code, slice full_domain, cell royalty_params) impure inline {
303cell data = begin_cell()
304.store_int(touched, 1)
305.store_uint(subwallet_id, 32)
306.store_uint(owner_key, 256)
307.store_ref(content)
308.store_ref(item_code)
309.store_ref(begin_cell().store_text(full_domain).end_cell())
310.store_ref(royalty_params)
311.end_cell();
312set_data(data);
313}
314
315_ unpack_signed_cmd(slice cs) inline {
316return (
317cs~load_bits(512), ;; signature
318slice_hash(cs), ;; hash
319cs~load_uint(32), ;; subwallet_id
320cs~load_uint(32), ;; valid_since
321cs~load_uint(32), ;; valid_till
322cs ;; cmd
323);
324}
325
326_ unpack_deploy_msg(slice cs) inline {
327var res = (
328cs~load_text(), ;; token_name
329cs~load_ref(), ;; content
330cs~load_ref(), ;; auction_config
331cs~load_maybe_ref() ;; royalty
332);
333cs.end_parse();
334return res;
335}
336
337;;teleitem_last_bid bidder_address:MsgAddressInt bid:Grams bid_ts:uint32 = TeleitemLastBid;
338(slice, int, int) unpack_last_bid(cell c) inline {
339slice cs = c.begin_parse();
340var res = (
341cs~load_msg_addr(), ;; bidder_address
342cs~load_grams(), ;; bid
343cs~load_uint(32) ;; bid_ts
344);
345cs.end_parse();
346return res;
347}
348cell pack_last_bid(slice bidder_address, int bid, int bid_ts) inline {
349return begin_cell()
350.store_slice(bidder_address)
351.store_grams(bid)
352.store_uint(bid_ts, 32)
353.end_cell();
354}
355
356;;teleitem_auction_state$_ last_bid:(Maybe ^TeleitemLastBid) min_bid:Grams end_time:uint32 = TeleitemAuctionState;
357(cell, int, int) unpack_auction_state(cell c) inline {
358slice cs = c.begin_parse();
359var res = (
360cs~load_maybe_ref(), ;; maybe last_bid
361cs~load_grams(), ;; min_bid
362cs~load_uint(32) ;; end_time
363);
364cs.end_parse();
365return res;
366}
367cell pack_auction_state(cell last_bid, int min_bid, int end_time) inline {
368return begin_cell()
369.store_maybe_ref(last_bid)
370.store_grams(min_bid)
371.store_uint(end_time, 32)
372.end_cell();
373}
374
375(slice, int, int, int, int, int) unpack_auction_config(cell c) inline {
376slice cs = c.begin_parse();
377var res = (
378cs~load_msg_addr(), ;; beneficiary address
379cs~load_grams(), ;; initial_min_bid
380cs~load_grams(), ;; max_bid
381cs~load_uint(8), ;; min_bid_step
382cs~load_uint(32), ;; min_extend_time
383cs~load_uint(32) ;; duration
384);
385cs.end_parse();
386return res;
387}
388
389;;teleitem_auction$_ state:^TeleitemAuctionState config:^TeleitemConfig = TeleitemAuction;
390(cell, cell) unpack_auction(cell c) inline {
391slice cs = c.begin_parse();
392var res = (
393cs~load_ref(),
394cs~load_ref()
395);
396cs.end_parse();
397return res;
398}
399
400cell pack_auction(cell state, cell config) inline {
401return begin_cell()
402.store_ref(state)
403.store_ref(config)
404.end_cell();
405}
406
407(int, slice, slice, cell, int, slice) unpack_nft_cmd_transfer(slice cs) inline {
408return (
409cs~load_uint(64),
410cs~load_msg_addr(),
411cs~load_msg_addr(),
412cs~load_maybe_ref(),
413cs~load_grams(),
414cs
415);
416}
417