@ -127,6 +127,7 @@ slice calculate_nft_item_address(int wc, cell state_init) {
;; address new_owner
;; address new_owner
;; address response_destination (can be 0 if no response needed)
;; address response_destination (can be 0 if no response needed)
;; coins to forward + coins to pay the fees
;; coins to forward + coins to pay the fees
;; The function transfers the nft to the new owner (+forwards some coins) and (optionally) sends the excess balance to `response_destination`
() transfer_ownership(int my_balance, cell collection_content, cell nft_item_code, int index,
() transfer_ownership(int my_balance, cell collection_content, cell nft_item_code, int index,
slice collection_address, slice owner_address, slice sender_address, int query_id, slice in_msg_body,
slice collection_address, slice owner_address, slice sender_address, int query_id, slice in_msg_body,
int fwd_fees, cell domain, cell auction) impure inline {
int fwd_fees, cell domain, cell auction) impure inline {
@ -171,6 +172,7 @@ slice calculate_nft_item_address(int wc, cell state_init) {
}
}
;; Create a new item
;; Create a new item
;; As described in https://ton.org/tblkch.pdf part 1.7, we send a message to the new address with the initial state
() deploy_nft_item(int item_index, cell nft_item_code, cell nft_content) impure {
() 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);
cell state_init = calculate_nft_item_state_init(item_index, nft_item_code);
slice nft_address = calculate_nft_item_address(workchain(), state_init);
slice nft_address = calculate_nft_item_address(workchain(), state_init);
@ -180,7 +182,7 @@ slice calculate_nft_item_address(int wc, cell state_init) {
.store_coins(0)
.store_coins(0)
.store_uint(4 + 2 + 1, 1 + 4 + 4 + 64 + 32 + 1 + 1 + 1)
.store_uint(4 + 2 + 1, 1 + 4 + 4 + 64 + 32 + 1 + 1 + 1)
.store_ref(state_init)
.store_ref(state_init)
.store_ref(nft_content);
.store_ref(nft_content); ;; the content of the NFT item, will be treated as the parameter of the first incoming message
send_raw_message(msg.end_cell(), 64); ;; carry all the remaining value of the inbound message, fee deducted from amount
send_raw_message(msg.end_cell(), 64); ;; carry all the remaining value of the inbound message, fee deducted from amount
}
}
@ -282,6 +284,12 @@ cell get_nft_content(int index, cell individual_nft_content) method_id {
return individual_nft_content;
return individual_nft_content;
}
}
;; Resolving the subdomain - the most important part of the contract
;; category is either `sha256("dns_next_resolver")` or `sha256("wallet")` or `sha256("site")`
;; Returns two values
;; * The first is `8m`, the length (in bits) of the prefix of the internal representation of the domain that has been resolved, `0 < m <= n`.
;; * The second is a `Cell` with the TON DNS record for the required domain in the required category, or the root a `Dictionary` with 256-bit unsigned integer keys (categories) and values equal to the serializations of corresponding TON DNS records.
(int, cell) dnsresolve(slice subdomain, int category) method_id {
(int, cell) dnsresolve(slice subdomain, int category) method_id {
int subdomain_bits = slice_bits(subdomain);
int subdomain_bits = slice_bits(subdomain);
@ -294,16 +302,27 @@ cell get_nft_content(int index, cell individual_nft_content) method_id {
cell keyvalue_map = cs~load_dict();
cell keyvalue_map = cs~load_dict();
int starts_with_zero_byte = subdomain.preload_int(8) == 0;
int starts_with_zero_byte = subdomain.preload_int(8) == 0;
throw_unless(413, starts_with_zero_byte);
if (subdomain_bits > 8) { ;; more than "." requested
category = "dns_next_resolver"H;
}
if (category == 0) { ;; all categories are requested
if (starts_with_zero_byte & (slice_bits(subdomain) == 8)) { ;; "." requested
;; If it's ".", we behave like an item
if (category == 0) { ;; all categories are requested
return (8, keyvalue_map);
return (8, keyvalue_map);
}
(cell value, int found) = keyvalue_map.udict_get_ref?(256, category);
return (8, value);
}
;; Otherwise, we behave like a collection
if (starts_with_zero_byte) {
subdomain~load_uint(8);
}
}
(cell value, int found) = keyvalue_map.udict_get_ref?(256, category);
int top_subdomain_bits = get_top_domain_bits(subdomain);
return (8, value);
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);
}
}