Logo
Nuevos usuarios de RPC: 35% de descuento el primer mesVer oferta
OnFinality Learn
Guías de red y protocolo11 min de lectura

Resolución de dominios TON: cómo los nombres .ton se asignan a billeteras, sitios y almacenamiento

Una guía práctica sobre cómo los dominios TON DNS se resuelven en la cadena, cómo consultarlos con el método get dnsresolve y cómo verificar a qué apunta realmente un nombre .ton.

TL;DR

Un dominio TON es un nombre en la cadena bajo el espacio de nombres de primer nivel .ton que se resuelve a direcciones de billetera, direcciones ADNL para TON Sites, IDs de bolsa de TON Storage, registros de texto o un subresolutor delegado. Los dominios son elementos NFT propiedad de una billetera, y la resolución ocurre llamando al método get dnsresolve en el contrato inteligente DNS correspondiente en lugar de consultar un servidor DNS convencional. Este artículo explica el árbol de contratos, las categorías de registros y un procedimiento reproducible para resolver un nombre .ton a través de un endpoint RPC y verificar el registro devuelto. También cubre qué puede salir mal, qué garantiza y qué no garantiza un dominio, y cómo pasar de una única consulta a una resolución de nivel de producción.

Qué es realmente un dominio TON

Un dominio TON es un identificador legible por humanos registrado bajo el espacio de nombres de primer nivel .ton en The Open Network. En lugar de copiar una dirección larga de contrato inteligente, un usuario puede enviar fondos a un nombre como example.ton, y un cliente puede resolver ese nombre a la dirección del contrato de billetera subyacente antes de construir una transferencia. La misma capa de nombres también apunta a direcciones ADNL utilizadas por TON Sites, IDs de bolsa de TON Storage, registros de texto arbitrarios y subdominios anidados.

El modelo mental importante es que TON DNS no es una base de datos de nombres separada adosada a la cadena. Es un árbol de contratos inteligentes, con el contrato raíz almacenado en la configuración de la cadena, y cada dominio .ton registrado representado como un elemento NFT propiedad de una billetera. Por lo tanto, la resolución es una lectura de contrato: se llama a un método get y se interpreta la celda devuelta. Esa distinción es importante para cualquiera que construya billeteras, exploradores, flujos de pago o puertas de enlace de sitios, porque el almacenamiento en caché, el manejo de errores y la verificación se derivan de ella.

  • .ton es el único dominio de primer nivel en el árbol de TON DNS.
  • Cada dominio registrado es un elemento NFT, por lo que la propiedad se transfiere a través de billeteras y mercados compatibles con NFT.
  • El espacio de nombres .t.me opera como un subresolutor delegado utilizando la misma interfaz de resolución.
  • Los registros pueden apuntar a billeteras, direcciones ADNL, IDs de bolsa de almacenamiento, texto u otro contrato resolutor.

Supuestos y requisitos previos para el recorrido

El procedimiento a continuación asume que tiene un endpoint HTTP que puede ejecutar métodos get de TON, un nombre de dominio que está autorizado a inspeccionar y una familiaridad básica con JSON y celdas codificadas en hexadecimal. No necesita ejecutar su propio nodo para seguir el ejemplo, pero sí necesita un endpoint que exponga la API runGetMethod en lugar de solo el historial de cuentas indexado.

Si aún está eligiendo una ruta de acceso, compare las opciones alojadas y autoalojadas en la guía de endpoints RPC de TON y revise la descripción general del servicio API para saber cómo se exponen las llamadas a métodos get. Para equipos que necesitan un rendimiento predecible o acceso privado, un nodo TON dedicado elimina la variabilidad de los endpoints compartidos de la medición.

El árbol de contratos y la interfaz dnsresolve

Cada contrato inteligente DNS en TON expone un método get con la firma (int, cell) dnsresolve(slice subdomain, int category). El argumento subdomain es la porción restante del nombre a resolver, y category es el hash SHA-256 de un nombre de categoría de registro, o cero para solicitar todos los registros. El método devuelve el número de bits consumidos y una celda que contiene el registro DNS.

El valor de retorno es donde se originan la mayoría de los errores de integración. Si el contrato consumió menos bits que la longitud total del subdominio, la celda devuelta es un registro dns_next_resolver que apunta a otro contrato que maneja el resto. Un resolutor debe seguir ese puntero en lugar de tratar el resultado parcial como final. Así es exactamente como funcionan los espacios de nombres delegados como .t.me y los subdominios definidos por el usuario: el resolutor padre cede el sufijo que no posee.

// Conceptual resolution loop (pseudocode)
// 1. Start at the root resolver from config param #4.
// 2. Call dnsresolve(remaining_subdomain, category).
// 3. If bits_consumed < remaining_subdomain.length:
//      read dns_next_resolver from the returned cell
//      set resolver = next_resolver
//      remaining_subdomain = remaining_subdomain.slice(bits_consumed)
//      repeat from step 2
// 4. Otherwise, decode the returned record by its TL-B type.

Tipos de registros y a qué resuelve cada uno

Los valores de los registros DNS de TON se describen mediante esquemas TL-B. El tipo de registro determina cómo un cliente debe interpretar la carga útil, y confundirlos es una fuente común de visualización incorrecta de direcciones. Los tipos de registro documentados cubren direcciones de contratos inteligentes, direcciones ADNL, referencias de almacenamiento, texto y delegación de resolutores.

Un registro dns_smc_address almacena una dirección de contrato inteligente, que es lo que una billetera necesita para enviar fondos a un nombre .ton. Un registro dns_adnl_address almacena una dirección ADNL de 256 bits más una lista opcional de protocolos, utilizada para localizar TON Sites. Los registros de almacenamiento llevan IDs de bolsa para TON Storage, los registros de texto llevan cadenas UTF-8 arbitrarias y dns_next_resolver delega un sufijo a otro contrato. Cuando construya un resolutor, decodifique por tipo primero y solo luego aplique la lógica de negocio.

  • dns_smc_address: dirección de billetera o contrato para transferencias.
  • dns_adnl_address: dirección de red para TON Sites, con indicadores de protocolo opcionales.
  • Registros de almacenamiento: IDs de bolsa para contenido direccionado a través de TON Storage.
  • Registros de texto: metadatos UTF-8 arbitrarios, como campos de perfil.
  • dns_next_resolver: puntero de delegación para subdominios y espacios de nombres delegados.

Resolver un dominio .ton a través de un endpoint RPC

La siguiente llamada curl invoca el método get dnsresolve en un contrato resolutor. Reemplace RPC_URL con su endpoint y RESOLVER_ADDRESS con el resolutor que está consultando. El subdominio se pasa como un slice, y la categoría se establece en cero para solicitar todos los registros. La respuesta contiene el código de salida, la pila y la celda devuelta, que luego decodifica.

Esta es una llamada de diagnóstico, no un resolutor completo. Confirma que el endpoint puede ejecutar métodos get y le muestra la forma cruda de la respuesta antes de agregar lógica de decodificación. Ejecútela primero contra un dominio que controle para poder comparar el registro devuelto con lo que espera.

curl -sS "$RPC_URL" \
  -H 'Content-Type: application/json' \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "runGetMethod",
    "params": {
      "address": "RESOLVER_ADDRESS",
      "method": "dnsresolve",
      "stack": [
        ["slice", "ZXhhbXBsZQ=="],
        ["int", "0"]
      ]
    }
  }'

Un asistente de resolución en JavaScript con verificación

El script a continuación envuelve la misma llamada al método get y agrega dos comprobaciones que importan en producción: verifica la forma de la respuesta JSON-RPC antes de leer la pila y registra la celda sin procesar para que una decodificación fallida pueda reproducirse. Deliberadamente no codifica de forma fija un endpoint público. Apunte RPC_URL al endpoint que haya elegido y mantenga las credenciales en variables de entorno.

El paso de decodificación se deja intencionalmente como una función etiquetada porque la decodificación TL-B depende del tipo de registro devuelto. En una integración real, ramificaría según el tipo de registro, decodificaría el esquema correspondiente y solo entonces convertiría la carga útil en una dirección de billetera o dirección ADNL. Registrar la celda sin decodificar junto con el valor decodificado hace que las discrepancias sean auditables.

const RPC_URL = process.env.RPC_URL;
const RESOLVER = process.env.RESOLVER_ADDRESS;

async function resolveDomain(subdomainSliceB64, category = 0) {
  const res = await fetch(RPC_URL, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      jsonrpc: '2.0',
      id: 1,
      method: 'runGetMethod',
      params: {
        address: RESOLVER,
        method: 'dnsresolve',
        stack: [
          ['slice', subdomainSliceB64],
          ['int', String(category)]
        ]
      }
    })
  });

  if (!res.ok) throw new Error(`HTTP ${res.status}`);
  const body = await res.json();
  if (body.error) throw new Error(body.error.message);

  const result = body.result;
  if (!result || !Array.isArray(result.stack)) {
    throw new Error('Unexpected runGetMethod response');
  }

  const bitsConsumed = Number(result.stack[0]?.value ?? 0);
  const recordCell = result.stack[1]?.value ?? null;

  return { bitsConsumed, recordCell, raw: result };
}

resolveDomain(process.env.SUBDOMAIN_SLICE_B64)
  .then(r => console.log(JSON.stringify(r, null, 2)))
  .catch(err => { console.error(err); process.exit(1); });

Verificar el resultado contra el estado esperado

Una llamada exitosa a un método get no es lo mismo que una resolución correcta. La verificación significa comparar el registro decodificado con una fuente de verdad independiente: la propiedad NFT del dominio, el registro que estableció al registrar y el comportamiento de un segundo cliente. Si la dirección de billetera decodificada no coincide con la dirección que configuró, la falla suele estar en la ruta de decodificación o en el resolutor que consultó, no en la cadena.

Utilice la tabla a continuación como plantilla de resultados. Complétela con sus propios valores observados; no copie números de ningún artículo, incluido este. El objetivo es hacer que cada comprobación sea reproducible para que una regresión sea visible la próxima vez que ejecute el procedimiento.

  • Comprobación 1: bitsConsumed es igual a la longitud total del subdominio, o hay un dns_next_resolver presente.
  • Comprobación 2: el tipo de registro decodificado coincide con la categoría que solicitó.
  • Comprobación 3: la dirección decodificada es igual al valor mostrado por una billetera o explorador independiente.
  • Comprobación 4: repetir la llamada devuelve el mismo registro, lo que confirma la consistencia del endpoint.

Procedimiento de la tabla de resultados

Registre cada ejecución en una tabla con columnas para el dominio, la dirección del resolutor, la categoría, los bits consumidos, el tipo de registro decodificado, el valor decodificado y si coincidió con la fuente independiente. Una fila completada podría verse como el encabezado a continuación, con sus propios valores sustituidos. | Dominio | Resolutor | Categoría | Bits consumidos | Tipo de registro | Valor decodificado | Coincidencia |. Deje las filas de datos vacías hasta que haya ejecutado el procedimiento; la tabla es un instrumento de medición, no una afirmación sobre el estado de la red.

Si está comparando endpoints, ejecute la misma tabla contra cada endpoint en secuencia y registre la latencia y la consistencia por separado de la corrección. El rendimiento del endpoint es una cuestión separada de la corrección de la resolución, y confundirlos oculta qué capa falló.

Solución de problemas comunes de resolución

La mayoría de las fallas caen en un pequeño número de categorías. Un método get que devuelve un código de salida distinto de cero generalmente significa que la dirección del resolutor es incorrecta o que el método no está presente en ese contrato. Una respuesta con una pila faltante significa que el endpoint devolvió un sobre de error que no verificó. Una falla de decodificación generalmente significa que asumió un tipo de registro en lugar de leerlo de la celda devuelta.

La delegación es el caso más sutil. Si bitsConsumed es menor que la longitud del subdominio e ignora el dns_next_resolver, informará un resultado parcial o vacío para un nombre que en realidad se resuelve correctamente un salto después. De manera similar, consultar la categoría incorrecta devuelve un conjunto de registros que no incluye el tipo que esperaba, lo que parece un registro faltante en lugar de un error de filtrado.

  • Código de salida distinto de cero: confirme la dirección del resolutor y que el contrato exponga dnsresolve.
  • Pila vacía o malformada: valide el sobre JSON-RPC antes de leer los valores.
  • Error de decodificación: ramifique según el tipo de registro en lugar de asumir dns_smc_address.
  • Resolución parcial: siga dns_next_resolver hasta que el subdominio se consuma por completo.
  • Resultados inconsistentes: repita la llamada y compare endpoints antes de cambiar la lógica de decodificación.

Limitaciones, compensaciones y qué no garantiza un dominio

Un dominio .ton es una conveniencia de nombres, no una prueba de identidad. La propiedad del NFT establece el control del nombre, pero una dirección de billetera resuelta es tan confiable como el registro que estableció el propietario. Los clientes deben mostrar la dirección resuelta y permitir que los usuarios la confirmen, especialmente para transferencias de alto valor. Un dominio se puede transferir y los registros se pueden cambiar, por lo que una resolución en caché puede quedar obsoleta.

La resolución también depende de que el árbol de resolutores sea accesible a través de su endpoint. Si depende de un único endpoint compartido, una falla transitoria parece un dominio faltante. El almacenamiento en caché mejora la latencia pero agrega riesgo de obsolescencia; el equilibrio correcto depende de si está mostrando un nombre o preparando una transacción. Para la preparación de transacciones, resuelva cerca del momento de la firma y verifique la dirección decodificada contra la intención del usuario.

Próximos pasos para la integración en producción

Pase de una única llamada de diagnóstico a un resolutor que siga la delegación, decodifique por tipo de registro, almacene en caché con una expiración explícita y registre la celda sin procesar para cada falla. Agregue un segundo endpoint como verificación cruzada para que una interrupción de un solo proveedor no se presente como un error de resolución. Si opera su propia infraestructura, revise la guía de alojamiento de nodos y el directorio de redes antes de dimensionar la capacidad.

Para la selección de endpoints específicamente, la página de precios de RPC explica cómo el volumen de solicitudes se asigna a los planes, y la guía de endpoints RPC de TON cubre los patrones de acceso que admiten llamadas a métodos get. Mantenga la lógica de resolución independiente de cualquier proveedor único para que cambiar de endpoint sea un cambio de configuración en lugar de una reescritura.

Nunca te preocupes por la infraestructura nuevamente

OnFinality elimina la carga pesada de DevOps para que puedas construir de forma más inteligente y rápida.

Comenzar