1
0
Fork 0
mirror of https://github.com/ton-blockchain/ton synced 2025-02-15 04:32:21 +00:00
ton/crypto/func/auto-tests/legacy_tests/dns-collection/nft-collection.fc
EmelyanenkoK 6b49d6a382
Add legacy_tester for existing funC contracts (#588)
* Add legacy_tester for existing funC contracts

* Add storage-contracts and pragma options
2023-01-12 12:33:15 +03:00

144 lines
4.8 KiB
Text

;; DNS resolver smart contract (implements NFT Collection interface)
#include "stdlib.fc";
#include "params.fc";
#include "dns-utils.fc";
;; storage scheme
;; storage#_ collection_content:^Cell
;; nft_item_code:^Cell
;; = Storage;
(cell, cell) load_data() inline {
var ds = get_data().begin_parse();
return (
ds~load_ref(), ;; content
ds~load_ref() ;; nft_item_code
);
}
() save_data(cell content, cell nft_item_code) impure inline {
set_data(begin_cell()
.store_ref(content)
.store_ref(nft_item_code)
.end_cell());
}
cell calculate_nft_item_state_init(int item_index, cell nft_item_code) {
cell data = begin_cell().store_uint(item_index, 256).store_slice(my_address()).end_cell();
return begin_cell().store_uint(0, 2).store_dict(nft_item_code).store_dict(data).store_uint(0, 1).end_cell();
}
slice calculate_nft_item_address(int wc, cell state_init) {
return begin_cell()
.store_uint(4, 3)
.store_int(wc, 8)
.store_uint(cell_hash(state_init), 256)
.end_cell()
.begin_parse();
}
() deploy_nft_item(int item_index, cell nft_item_code, cell nft_content) impure {
cell state_init = calculate_nft_item_state_init(item_index, nft_item_code);
slice nft_address = calculate_nft_item_address(workchain(), state_init);
var msg = begin_cell()
.store_uint(0x18, 6)
.store_slice(nft_address)
.store_coins(0)
.store_uint(4 + 2 + 1, 1 + 4 + 4 + 64 + 32 + 1 + 1 + 1)
.store_ref(state_init)
.store_ref(nft_content);
send_raw_message(msg.end_cell(), 64); ;; carry all the remaining value of the inbound message, fee deducted from amount
}
() recv_internal(int msg_value, cell in_msg_full, slice in_msg_body) impure {
if (in_msg_body.slice_empty?()) { ;; bounce back empty messages
throw(0xffff);
}
slice cs = in_msg_full.begin_parse();
int flags = cs~load_uint(4);
if (flags & 1) { ;; ignore all bounced messages
return ();
}
slice sender_address = cs~load_msg_addr();
int op = in_msg_body~load_uint(32);
var (content, nft_item_code) = load_data();
if (op == 0) { ;; deploy new nft
int now_time = now();
throw_unless(199, now_time > auction_start_time); ;; start of auction
slice domain = read_domain_from_comment(in_msg_body);
int len = slice_bits(domain);
throw_unless(200, len > 3 * 8); ;; minimum 4 characters
throw_unless(201, len <= 126 * 8); ;; maxmimum 126 characters
throw_unless(202, mod(len, 8) == 0);
throw_unless(203, check_domain_string(domain));
int min_price = get_min_price(len, now_time);
throw_unless(204, msg_value >= min_price);
int item_index = slice_hash(domain);
cell config_cell = config_param(dns_config_id);
if (~ cell_null?(config_cell)) {
slice config_cs = config_cell.begin_parse();
cell config = config_cs~load_dict();
(slice config_value, int found) = config.udict_get?(256, item_index);
throw_if(205, found);
}
cell nft_content = begin_cell()
.store_slice(sender_address)
.store_ref(begin_cell().store_slice(domain).end_cell())
.end_cell();
deploy_nft_item(item_index, nft_item_code, nft_content);
return ();
}
if (op == op::fill_up) { ;; just fill-up balance
return ();
}
throw(0xffff);
}
;; Get methods
(int, cell, slice) get_collection_data() method_id {
var (content, nft_item_code) = load_data();
return (-1, content, zero_address());
}
slice get_nft_address_by_index(int index) method_id {
var (content, nft_item_code) = load_data();
cell state_init = calculate_nft_item_state_init(index, nft_item_code);
return calculate_nft_item_address(workchain(), state_init);
}
cell get_nft_content(int index, cell individual_nft_content) method_id {
return individual_nft_content;
}
(int, cell) dnsresolve(slice subdomain, int category) method_id {
throw_unless(70, mod(slice_bits(subdomain), 8) == 0);
int starts_with_zero_byte = subdomain.preload_int(8) == 0;
if (starts_with_zero_byte & (slice_bits(subdomain) == 8)) { ;; "." requested
return (8, null()); ;; resolved but no dns-records
}
if (starts_with_zero_byte) {
subdomain~load_uint(8);
}
int top_subdomain_bits = get_top_domain_bits(subdomain);
slice top_subdomain = subdomain~load_bits(top_subdomain_bits);
int item_index = slice_hash(top_subdomain);
cell result = begin_cell()
.store_uint(dns_next_resolver_prefix, 16)
.store_slice(get_nft_address_by_index(item_index))
.end_cell();
return (top_subdomain_bits + (starts_with_zero_byte ? 8 : 0), result);
}