contracts.dns.nft-collection.fc Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of smartcontract Show documentation
Show all versions of smartcontract Show documentation
Build and manipulate TON smart contracts in easy way.
;; DNS resolver smart contract (implements NFT Collection interface)
;; 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);
}