From 210fb33f957dbcd8e1ac528cb99cca43fa7b92f6 Mon Sep 17 00:00:00 2001 From: ennucore Date: Wed, 7 Dec 2022 17:02:36 +0100 Subject: [PATCH] Wrote the first version for `dnsresolve` --- contracts/main.fc | 37 ++++++++++++++++++++++++++++--------- 1 file changed, 28 insertions(+), 9 deletions(-) diff --git a/contracts/main.fc b/contracts/main.fc index 37d3b45..1857951 100644 --- a/contracts/main.fc +++ b/contracts/main.fc @@ -127,6 +127,7 @@ slice calculate_nft_item_address(int wc, cell state_init) { ;; address new_owner ;; address response_destination (can be 0 if no response needed) ;; 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, 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 { @@ -171,6 +172,7 @@ slice calculate_nft_item_address(int wc, cell state_init) { } ;; 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 { cell state_init = calculate_nft_item_state_init(item_index, nft_item_code); 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_uint(4 + 2 + 1, 1 + 4 + 4 + 64 + 32 + 1 + 1 + 1) .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 } @@ -282,6 +284,12 @@ cell get_nft_content(int index, cell individual_nft_content) method_id { 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 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(); 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); + } + + (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); - return (8, value); + 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); }