Skip to content

TON DNS reference

Reference for the TON DNS smart contract system. Source: dns-contract. Standard: TEP-0081. The root DNS address is stored in blockchain config parameter #4.

Three contracts form the DNS tree:

ContractRole
Root DNSRoutes queries to zone resolvers (.ton, .t.me)
Collection (resolver)Mints domain NFTs, resolves subdomains to item addresses
Item (domain NFT)Holds DNS records, manages auctions, processes transfers

The NFT item contract (the domain) accepts the following internal messages:

OpcodeHexNameDescription
op::bid (0)0x00000000BidPlace a bid during auction. Minimum increment: 5%.
op::transfer()0x5fcc3d14TransferTransfer domain ownership (NFT transfer, TEP-0062)
op::change_dns_record0x4eb1f0f9Change DNS recordSet or delete a DNS record. Parameters: key (uint256, SHA-256 of category name), value (cell, omit to delete).
op::dns_balance_release0x4ed14b65Release domainTrigger release of an expired domain. Restarts auction for 1 week.
op::edit_content()0x1a0b9d51Edit contentModify NFT onchain metadata
op::process_governance_decision0x44beae41GovernanceProcess administrative decision from config
op::get_static_data()0x2fcb26a2Get static dataReturn NFT static data (index + collection address)

Hex values sourced from op-codes.fc and dns-utils.fc.

MethodReturnsDescription
get_nft_data()(init?, index, collection_address, owner_address, content)NFT metadata (TEP-0062)
get_editor()owner_addressCurrent domain owner
get_domain()domain (slice)Domain name string
get_auction_info()(max_bid_address, max_bid_amount, auction_end_time)Current auction state
get_last_fill_up_time()last_fill_up_time (int)Timestamp of last renewal payment
dnsresolve(subdomain, category)(bits_consumed, record_cell)Resolve a DNS record
MethodReturnsDescription
get_collection_data()(index, content, owner)Collection metadata
get_nft_address_by_index(index)item_addressCompute domain item address from index (SHA-256 of domain name)
get_nft_content(index, content)content_cellIndividual NFT content
dnsresolve(subdomain, category)(bits_consumed, resolver_cell)Resolve subdomain to item contract

Every DNS contract in the tree exposes this get-method:

(int, cell) dnsresolve(slice subdomain, int category)

subdomain is the portion remaining to be resolved, encoded as 8n data bits (n is at most 127 bytes). category is the SHA-256 hash of the record category name, or 0 for all records. Returns the number of bits consumed and a cell containing the DNS record. If fewer bits were consumed than the full subdomain length, the returned cell is a dns_next_resolver pointing to the contract that resolves the remainder.

DNS record values are described by TL-B schemas. The following record types are defined:

  • dns_adnl_address: stores a 256-bit ADNL address for network services such as TON Sites. An optional protocol list describes supported protocols.

    dns_adnl_address#ad01 adnl_addr:bits256 flags:(## 8) { flags <= 1 }
    proto_list:flags . 0?ProtoList = DNSRecord;
  • dns_smc_address: stores any smart contract address on the TON Blockchain, including wallets. An optional capability list describes the capabilities of the contract. Under the standard wallet category, this record enables sending funds to a domain name.

    dns_smc_address#9fd3 smc_addr:MsgAddressInt flags:(## 8) { flags <= 1 }
    cap_list:flags . 0?SmcCapList = DNSRecord;
  • dns_next_resolver: delegates resolution of subdomains to another DNS smart contract at the specified address.

    dns_next_resolver#ba93 resolver:MsgAddressInt = DNSRecord;
  • dns_storage_address: stores a 256-bit TON Storage Bag ID, allowing domain names to be assigned to files stored via TON Storage.

    dns_storage_address#7473 bag_id:bits256 = DNSRecord;
  • dns_text: stores arbitrary UTF-8 text using the Text chunked encoding defined in the block layout specification.

    dns_text#1eda _:Text = DNSRecord;
ConstructorTagSchema
proto_http#4854proto_http#4854 = Protocol;
proto_list_nil$0proto_list_nil$0 = ProtoList;
proto_list_next$1proto_list_next$1 head:Protocol tail:ProtoList = ProtoList;
cap_is_wallet#2177cap_is_wallet#2177 = SmcCapability;
cap_list_nil$0cap_list_nil$0 = SmcCapList;
cap_list_next$1cap_list_next$1 head:SmcCapability tail:SmcCapList = SmcCapList;
_ (HashmapE 256 ^DNSRecord) = DNS_RecordSet;

Categories are identified by SHA-256 hash of the UTF-8 category name string.

Category nameRecord typePurpose
walletdns_smc_addressDefault wallet address
sitedns_adnl_addressTON Site ADNL address
dns_next_resolverdns_next_resolverSubdomain delegation
storagedns_storage_addressTON Storage Bag ID
dns_textdns_textArbitrary UTF-8 text record

The storage and dns_text categories are practical conventions. TEP-0081 formally defines only wallet, site, and dns_next_resolver.

Passing category 0 retrieves all records.

ConstantValueDescription
min_tons_for_storage1 TONMinimum balance for contract storage
auction_start_duration604,800 s (7 days)Initial auction period
auction_end_duration3,600 s (1 h)Final bidding window
auction_prolongation3,600 s (1 h)Extension on late bids
one_year31,622,400 s (366 days)Duration constant for expiration logic
one_month2,592,000 sDuration constant for grace period
auction_start_time1,659,171,600 (2022-07-30)Epoch when the auction system launched
dns_config_id80Blockchain config parameter index for the DNS domain denylist (blocked domains). Distinct from config param #4, which stores the root DNS contract address.
Minimum bid increment5%Over current highest bid

The get_min_price(len, now_time) get-method returns the minimum auction bid based on domain length. The price decays by 90% per month for up to 21 months from auction_start_time (1,659,171,600), then holds at the floor price. Values sourced from get_min_price_config() in dns-utils.fc.

Domain length (chars)Start price (TON)Floor price (TON)
41,000100
550050
640040
730030
820020
910010
10505
≥ 11101