Ton

Форк
0
144 строки · 4.8 Кб
1
;; DNS resolver smart contract (implements NFT Collection interface)
2

3

4
#include "stdlib.fc";
5
#include "params.fc";
6
#include "dns-utils.fc";
7

8
;; storage scheme
9
;; storage#_ collection_content:^Cell
10
;;           nft_item_code:^Cell
11
;;           = Storage;
12

13
(cell, cell) load_data() inline {
14
    var ds = get_data().begin_parse();
15
    return (
16
            ds~load_ref(), ;; content
17
            ds~load_ref() ;; nft_item_code
18
    );
19
}
20

21
() save_data(cell content, cell nft_item_code) impure inline {
22
    set_data(begin_cell()
23
            .store_ref(content)
24
            .store_ref(nft_item_code)
25
            .end_cell());
26
}
27

28
cell calculate_nft_item_state_init(int item_index, cell nft_item_code) {
29
    cell data = begin_cell().store_uint(item_index, 256).store_slice(my_address()).end_cell();
30
    return begin_cell().store_uint(0, 2).store_dict(nft_item_code).store_dict(data).store_uint(0, 1).end_cell();
31
}
32

33
slice calculate_nft_item_address(int wc, cell state_init) {
34
    return begin_cell()
35
            .store_uint(4, 3)
36
            .store_int(wc, 8)
37
            .store_uint(cell_hash(state_init), 256)
38
            .end_cell()
39
            .begin_parse();
40
}
41

42
() deploy_nft_item(int item_index, cell nft_item_code, cell nft_content) impure {
43
    cell state_init = calculate_nft_item_state_init(item_index, nft_item_code);
44
    slice nft_address = calculate_nft_item_address(workchain(), state_init);
45
    var msg = begin_cell()
46
            .store_uint(0x18, 6)
47
            .store_slice(nft_address)
48
            .store_coins(0)
49
            .store_uint(4 + 2 + 1, 1 + 4 + 4 + 64 + 32 + 1 + 1 + 1)
50
            .store_ref(state_init)
51
            .store_ref(nft_content);
52
    send_raw_message(msg.end_cell(), 64); ;; carry all the remaining value of the inbound message, fee deducted from amount
53
}
54

55
() recv_internal(int msg_value, cell in_msg_full, slice in_msg_body) impure {
56
    if (in_msg_body.slice_empty?()) { ;; bounce back empty messages
57
        throw(0xffff);
58
    }
59
    slice cs = in_msg_full.begin_parse();
60
    int flags = cs~load_uint(4);
61

62
    if (flags & 1) { ;; ignore all bounced messages
63
        return ();
64
    }
65
    slice sender_address = cs~load_msg_addr();
66

67
    int op = in_msg_body~load_uint(32);
68

69
    var (content, nft_item_code) = load_data();
70

71
    if (op == 0) { ;; deploy new nft
72
        int now_time = now();
73
        throw_unless(199, now_time > auction_start_time); ;; start of auction
74
        slice domain = read_domain_from_comment(in_msg_body);
75
        int len = slice_bits(domain);
76
        throw_unless(200, len > 3 * 8); ;; minimum 4 characters
77
        throw_unless(201, len <= 126 * 8); ;; maxmimum 126 characters
78
        throw_unless(202, mod(len, 8) == 0);
79
        throw_unless(203, check_domain_string(domain));
80
        int min_price = get_min_price(len, now_time);
81
        throw_unless(204, msg_value >= min_price);
82

83
        int item_index = slice_hash(domain);
84

85
        cell config_cell = config_param(dns_config_id);
86
        if (~ cell_null?(config_cell)) {
87
            slice config_cs = config_cell.begin_parse();
88
            cell config = config_cs~load_dict();
89
            (slice config_value, int found) = config.udict_get?(256, item_index);
90
            throw_if(205, found);
91
        }
92

93
        cell nft_content = begin_cell()
94
                .store_slice(sender_address)
95
                .store_ref(begin_cell().store_slice(domain).end_cell())
96
                .end_cell();
97
        deploy_nft_item(item_index, nft_item_code, nft_content);
98
        return ();
99
    }
100

101
    if (op == op::fill_up) { ;; just fill-up balance
102
        return ();
103
    }
104
    throw(0xffff);
105
}
106

107
;; Get methods
108

109
(int, cell, slice) get_collection_data() method_id {
110
    var (content, nft_item_code) = load_data();
111
    return (-1, content, zero_address());
112
}
113

114
slice get_nft_address_by_index(int index) method_id {
115
    var (content, nft_item_code) = load_data();
116
    cell state_init = calculate_nft_item_state_init(index, nft_item_code);
117
    return calculate_nft_item_address(workchain(), state_init);
118
}
119

120
cell get_nft_content(int index, cell individual_nft_content) method_id {
121
    return individual_nft_content;
122
}
123

124
(int, cell) dnsresolve(slice subdomain, int category) method_id {
125
    throw_unless(70, mod(slice_bits(subdomain), 8) == 0);
126

127
    int starts_with_zero_byte = subdomain.preload_int(8) == 0;
128

129
    if (starts_with_zero_byte & (slice_bits(subdomain) == 8)) { ;; "." requested
130
        return (8, null());  ;; resolved but no dns-records
131
    }
132
    if (starts_with_zero_byte) {
133
        subdomain~load_uint(8);
134
    }
135

136
    int top_subdomain_bits = get_top_domain_bits(subdomain);
137
    slice top_subdomain = subdomain~load_bits(top_subdomain_bits);
138
    int item_index = slice_hash(top_subdomain);
139
    cell result = begin_cell()
140
            .store_uint(dns_next_resolver_prefix, 16)
141
            .store_slice(get_nft_address_by_index(item_index))
142
            .end_cell();
143
    return (top_subdomain_bits + (starts_with_zero_byte ? 8 : 0), result);
144
}
145

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.