Qué son los decimals de un jetton en TON (USDT = 6, no 9)
Decimals de un jetton en TON: por qué USDT usa 6 y casi todos los demás 9, cómo get_jetton_info devuelve decimals y por qué es crítico para balances y swaps
Estás escribiendo un agente que muestra el balance de USDT. Consultas el balance del jetton-wallet, recibes 5000000, divides entre 10^9 — y en pantalla aparece 0.005 USDT en lugar de los 5 USDT reales. Las transacciones pasan, el RPC responde, el get-method devuelve un número — y aun así el monto falla exactamente por un factor de 1000. La culpable es una sola cifra que casi todo el mundo hardcodea por costumbre: decimals.
Si estás conectando un agente de IA a TON o calculas montos de jettons a mano, decimals es lo primero que hay que entender antes de tocar cualquier balance o swap. Veamos por qué USDT tiene decimals = 6 y no el 9 habitual de TON, de dónde sale ese número y cómo obtenerlo con una sola llamada, sin adivinar.
Decimals de un jetton en TON: unidades raw vs. número legible por humanos
La blockchain no puede almacenar fracciones. Sencillamente no puede. En TON, como en casi todas partes, cualquier monto vive en el contrato como un número entero — las llamadas unidades raw (las unidades mínimas indivisibles). No existe ningún 5.5 en el diccionario del contrato ni puede existir — solo hay un entero como 5500000.
Para convertir ese entero en el monto que ve una persona hace falta una escala. Esa escala es precisamente decimals: la potencia de diez que separa el entero almacenado del monto legible por humanos:
human = raw / 10^decimals
raw = human * 10^decimals
La analogía es simple. El dinero de tu billetera está en dólares, pero la contabilidad del banco lo lleva todo en centavos, con números enteros: 100 centavos = 1 dólar, es decir, decimals = 2. ¿Quieres mostrarle dólares al usuario? Divides los centavos entre 10^2 = 100. Con los jettons pasa exactamente lo mismo, solo cambia la potencia de diez.
El punto clave: la propia blockchain no sabe dónde va la "coma" del número. Opera con unidades raw enteras. Dónde colocar la coma al mostrárselo al usuario lo decide el cliente, leyendo decimals de los metadatos del jetton. Si te equivocas con decimals, la coma se va de sitio y el importe que muestras deja de tener sentido.
USDT en TON tiene decimals = 6; la mayoría de los jettons, 9
Dos cifras que hay que memorizar:
- USDT (Tether) en TON →
decimals = 6. Es decir,1 USDT = 1 000 000 de unidades raw. - La mayoría del resto de jettons de TON →
decimals = 9. Ese mismo valor es además el que se asume por defecto: si el campodecimalsno aparece en los metadatos, el estándar obliga al cliente a darlo por igual a9.
De dónde sale el nueve. El propio GRAM (el antiguo Toncoin, renombrado en junio de 2026 — la red se sigue llamando TON) tiene 9 decimales: 1 GRAM = 10^9 nanogramos, y ese "nano" es justamente la unidad raw. El estándar de jettons de TON heredó ese valor por defecto, y la inmensa mayoría de tokens de la red vive con decimals = 9. Los desarrolladores se acostumbran a escribir / 1e9 sin mirar.
USDT, en cambio, es un recién llegado del mundo Ethereum, donde Tether ha usado siempre 6 decimales. El emisor conservó su precisión de siempre también en TON. Por eso USDT es la excepción con la que tropieza casi cualquiera que "simplemente hardcodeó el 9" — y resulta ser justo el jetton más usado para pagos.
Calculemos el precio del error. Supón que en el jetton-wallet hay 5 000 000 de unidades raw de USDT:
- correcto (
decimals = 6):5 000 000 / 10^6 = 5 USDT; - incorrecto (
decimals = 9):5 000 000 / 10^9 = 0.005.
Un desfase de exactamente 10^(9−6) = 1000 veces. Y al revés: si el usuario escribe "envía 5 USDT" y tú multiplicas por 10^9, intentarás mover 1000 veces más. Para un bot de pagos, esa es la diferencia entre "pagado" y "rechazado".
De dónde sale decimals: los metadatos del jetton y el estándar TEP-64
Es importante entenderlo: decimals no es un campo del código del wallet ni una constante del protocolo. Es parte de los metadatos de cada jetton concreto, descritos por el estándar TEP-64 (Token Data Standard). Cada jetton declara por sí mismo su decimals, su nombre, su símbolo y su imagen.
TEP-64 permite almacenar los metadatos en tres formatos:
- on-chain — todos los campos viven en un diccionario (dictionary) directamente en el contrato del jetton; no hay que descargar nada;
- off-chain — en el contrato solo hay un enlace (
uri), y todo el JSON con los campos (name,symbol,decimals,image) vive en esa URI, en un servidor web o en IPFS; - semi-chain (híbrido) — parte de los campos en el diccionario on-chain, parte vía
uri; el cliente descarga el contenido off-chain y lo mergea con los valores del diccionario.
La regla de fusión según TEP-64 es esta: si el diccionario contiene la clave uri, el cliente está obligado a descargar el contenido off-chain del enlace y combinarlo con los valores del diccionario on-chain. Cada formato tiene un costo de lectura distinto: on-chain se lee con un único get-method, off-chain exige además una petición HTTP. Manejar los tres casos a mano no es precisamente divertido, y es justo aquí donde agradeces que una sola herramienta lo haga por ti.
Los metadatos de USDT: cómo get_jetton_info devuelve decimals = 6
USDT en TON guarda sus metadatos en formato off-chain: en el contrato maestro del jetton hay un enlace al JSON off-chain, y es en ese JSON donde están escritos name, symbol y, sobre todo, decimals = 6. Para montar correctamente la ficha del jetton, el cliente tiene que leer el contrato, extraer el enlace, descargar el JSON y parsear los campos.
No hace falta tener en la cabeza el formato TEP-64 ni parsear celdas del diccionario a mano: ese es exactamente el trabajo que asume una sola herramienta. get_jetton_info va al contrato por ti, parsea los metadatos y te devuelve directamente decimals = 6 — y sobre ese número se construye toda la aritmética.
Cómo obtener decimals con una sola llamada: get_jetton_info
En lugar de leer el diccionario a mano, detectar el formato (on/off/semi-chain), seguir la URI y mergear el JSON, existe get_jetton_info. Es una herramienta del servidor MCP de TONNode: recibe la dirección del contrato maestro del jetton y devuelve los metadatos ya ensamblados — nombre, símbolo, decimals y emisión.
TONNode es un servidor MCP hospedado para TON. MCP (Model Context Protocol) es el estándar mediante el cual los agentes de IA (Claude, Cursor, ChatGPT/Codex, cualquier cliente MCP) invocan herramientas. Se conecta gratis y de forma local, con el set completo de herramientas de lectura:
{
"mcpServers": {
"ton": { "command": "npx", "args": ["-y", "@tonnode/mcp"] }
}
}
El paquete @tonnode/mcp es open source (MIT) y funciona sobre el protocolo nativo ADNL de TON, sin capas HTTP intermedias. A partir de ahí, al agente le basta una petición normal en lenguaje humano:
Con la herramienta
get_jetton_infoaverigua losdecimalsdel jetton USDT en TON (dirección del contrato maestro: tal y cual) y calcula cuánto es en USDT legibles para un balance de 5 000 000 raw.
get_jetton_info devolverá decimals = 6, y toda la aritmética posterior se apoya en ese número, no en una suposición. La misma llamada para cualquier otro jetton devolverá su propio valor (normalmente 9, pero siempre hay que comprobarlo). La regla de oro:
No hardcodees el
9. Leedecimalsdeget_jetton_infopara cada jetton.
El nueve funcionará para la mayoría de los tokens y se romperá en silencio con USDT — que es justo el jetton donde más dinero real se mueve. Por qué un agente de IA necesita un acceso MCP propio a TON en lugar de un RPC público con límites lo explicamos en la nota sobre el servidor MCP para agentes en TON.
Por qué un decimals incorrecto rompe balances y swaps
decimals no es cosmética de presentación. Interviene en todos los puntos donde un monto cruza la frontera "raw ⇄ humano", y el error se propaga por toda la cadena.
Balances
get_jetton_balance devuelve el balance del jetton en unidades raw (el jetton-wallet correcto se calcula on-chain; no tienes que buscarlo tú). Ese entero por sí solo no significa nada sin decimals: no puedes mostrárselo bien al usuario hasta que lo dividas entre 10^decimals:
raw = 5 000 000
decimals = 6 → 5 USDT ✅
decimals = 9 → 0.005 ❌ (1000 veces menos)
El orden correcto en el agente: primero get_jetton_info → tomar decimals, después get_jetton_balance → dividir el raw entre 10^decimals. Y cómo los liteservers públicos se estrellan contra sus límites justo con este tipo de lecturas lo desglosamos en el análisis de los límites de los liteservers públicos de TON.
Swaps
get_swap_quote entrega una cotización firme de DEX GRAM⇄jetton (vía el protocolo Omniston, liquidez de STON.fi + DeDust) — y tanto el monto de entrada como la estimación de salida van también en unidades raw del jetton. Aquí un decimals incorrecto golpea dos veces. Supón que el usuario quiere swapear 10 USDT: con decimals = 6 hay que pasar a la cotización 10 000 000 raw. Aplicaste 9 por error y pediste 10 000 000 000 raw, o sea un swap de 10 000 USDT que no existen en el wallet. El error inverso al parsear la respuesta rebajará el monto esperado 1000 veces, y el usuario concluirá que el tipo de cambio es un robo.
El mismo principio rige en las cotizaciones cross-chain y en cualquier transacción: en la blockchain todo va en unidades raw enteras, y el único puente hacia los montos legibles es el decimals correcto.
Comprobación en la práctica: get_jetton_balance y get_swap_quote
Armemos un escenario corto que el agente ejecuta solo, sin una sola cifra hardcodeada.
Escenario paso a paso
1. Averiguar decimals. get_jetton_info(USDT master) → decimals = 6.
2. Leer el balance. get_jetton_balance(propietario, USDT master) → 5 000 000 (raw). Calculamos: 5 000 000 / 10^6 = 5 USDT. Si hubiéramos usado 9, habríamos obtenido 0.005. Esa es tu señal de alarma: si ves un número inesperadamente diminuto en USDT, lo primero es comprobar si aplicaste 9 en lugar de 6.
3. Pedir la cotización. Queremos swapear 5 USDT a GRAM. En raw son 5 × 10^6 = 5 000 000 — es exactamente ese monto el que pasamos a get_swap_quote. El resultado también llega en raw, y GRAM usa 9 decimales, así que dividimos la respuesta entre 10^9 antes de mostrarla al usuario.
4. ¿No te fías de los metadatos? Puedes verificarlo on-chain directamente. run_get_method invoca cualquier get-method de solo lectura de un contrato — por esa vía puedes llamar a get_jetton_data del contrato maestro y comprobar que las cifras cuadran. Es más flexible, pero exige conocer el formato TEP-64 y parsear el diccionario a mano; cuando importan la velocidad y la fiabilidad, get_jetton_info cierra el asunto con una sola respuesta. En qué se diferencian los proveedores RPC de TON en cuanto a acceso a get-methods y al archivo lo repasamos en la comparativa honesta de proveedores RPC de TON.
El prompt para el agente
El prompt de todo el escenario suena de lo más cotidiano:
Toma USDT en TON. Con
get_jetton_infolee losdecimals. Conget_jetton_balanceobtén mi balance en raw y conviértelo a USDT legibles. Después, conget_swap_quote, calcula la cotización para swapear 5 USDT a GRAM — no olvides convertir los 5 USDT a raw con eldecimalsque leíste.
Un detalle más para escenarios agénticos: las herramientas de swap de TONNode son estrictamente no custodiales. El servidor nunca firma ni guarda claves: build_swap_tx devuelve un mensaje TonConnect sin firmar, que firma el wallet del usuario. Ni siquiera un decimals correcto le da al servidor control sobre los fondos: solo calcula y construye la transacción. Dónde se pierden los milisegundos y de dónde sale la latencia en los swaps de TON lo cubrimos en el análisis del trading de alta velocidad en TON.
En resumen
decimalses la potencia de diez entre las unidades raw de la blockchain y el monto legible por humanos:human = raw / 10^decimals.- El valor por defecto en TON son 9 decimales; USDT usa 6 (
1 USDT = 1 000 000raw). Confundirlos = fallar por un factor de 1000. decimalsvive en los metadatos del jetton (TEP-64), no en el código. USDT guarda sus metadatos off-chain, peroget_jetton_infoigualmente entregadecimals = 6en una sola respuesta.- No hardcodees el
9. Leedecimalsconget_jetton_infoy construye sobre él todos los balances (get_jetton_balance) y cotizaciones (get_swap_quote).
Consigue tu clave gratuita Hobby (60 peticiones/min, sin tarjeta) y lee los decimals de cualquier jetton con get_jetton_info ahora mismo: https://tonnode.io/dashboard?plan=hobby
Dale a tu agente acceso a TON
16 herramientas MCP: lectura, swaps no custodiales, cross-chain y billeteras. Plan gratuito — 60 req/min, sin tarjeta.