Ton
110 строк · 2.9 Кб
1;; NFT marketplace smart contract v2
2;; Extends wallet v3r2 & adds ability to deploy sales
3
4#include "stdlib.fc";
5
6;;
7;; storage scheme
8;;
9;; storage#_ seqno:uint32 subwallet:uint32 public_key:uint25
10;; = Storage;
11;;
12_ load_data() {
13var ds = get_data().begin_parse();
14return (
15ds~load_uint(32), ;; seqno
16ds~load_uint(32), ;; subwallet
17ds~load_uint(256) ;; public_key
18);
19}
20
21() store_data(var data) impure {
22(
23int seqno,
24int subwallet,
25int public_key
26) = data;
27
28set_data(
29begin_cell()
30.store_uint(seqno, 32)
31.store_uint(subwallet, 32)
32.store_uint(public_key, 256)
33.end_cell()
34);
35}
36
37() recv_internal(int my_balance, int msg_value, cell in_msg_full, slice in_msg_body) impure {
38if (in_msg_body.slice_empty?()) { ;; ignore empty messages
39return ();
40}
41
42slice cs = in_msg_full.begin_parse();
43int flags = cs~load_uint(4);
44
45if (flags & 1) { ;; ignore all bounced messages
46return ();
47}
48slice sender_address = cs~load_msg_addr();
49var (seqno, subwallet, public_key) = load_data();
50
51int op = in_msg_body~load_uint(32);
52
53if (op == 1) { ;; deploy new signed sale
54var signature = in_msg_body~load_bits(512);
55throw_unless(35, check_signature(slice_hash(in_msg_body), signature, public_key));
56
57(cell state_init, cell body) = (in_msg_body~load_ref(), in_msg_body~load_ref());
58
59int state_init_hash = cell_hash(state_init);
60slice dest_address = begin_cell().store_int(0, 8).store_uint(state_init_hash, 256).end_cell().begin_parse();
61
62var msg = begin_cell()
63.store_uint(0x18, 6)
64.store_uint(4, 3).store_slice(dest_address)
65.store_grams(0)
66.store_uint(4 + 2 + 1, 1 + 4 + 4 + 64 + 32 + 1 + 1 + 1)
67.store_ref(state_init)
68.store_ref(body);
69
70send_raw_message(msg.end_cell(), 64); ;; carry remaining value of message
71return ();
72}
73
74return ();
75}
76
77() recv_external(slice in_msg) impure {
78var signature = in_msg~load_bits(512);
79var cs = in_msg;
80var (subwallet_id, valid_until, msg_seqno) = (cs~load_uint(32), cs~load_uint(32), cs~load_uint(32));
81throw_if(35, valid_until <= now());
82var (seqno, subwallet, public_key) = load_data();
83throw_unless(33, msg_seqno == seqno);
84throw_unless(34, subwallet_id == subwallet);
85throw_unless(35, check_signature(slice_hash(in_msg), signature, public_key));
86accept_message();
87cs~touch();
88while (cs.slice_refs()) {
89var mode = cs~load_uint(8);
90send_raw_message(cs~load_ref(), mode);
91}
92
93store_data(
94seqno + 1,
95subwallet,
96public_key
97);
98}
99
100;; Get methods
101
102int seqno() method_id {
103return get_data().begin_parse().preload_uint(32);
104}
105
106int get_public_key() method_id {
107var cs = get_data().begin_parse();
108cs~load_uint(64);
109return cs.preload_uint(256);
110}
111