Decimals d'un jetton TON : pourquoi USDT = 6 et pas 9
Les decimals d'un jetton sur TON — pourquoi USDT = 6 quand la plupart des jettons ont 9, comment get_jetton_info les renvoie et pourquoi vos soldes en dépendent
Vous écrivez un agent qui affiche un solde USDT. Vous interrogez le jetton-wallet, vous obtenez 5000000, vous divisez par 10^9 — et l'écran affiche 0.005 USDT au lieu des 5 USDT réels. Les transactions passent, le RPC répond, la méthode get renvoie bien un nombre — et pourtant le montant est faux, d'un facteur 1000 exactement. Le coupable : un seul chiffre que presque tout le monde code en dur par habitude — decimals.
Si vous connectez un agent IA à TON ou calculez des montants de jettons à la main, decimals est la première chose à comprendre avant le moindre solde ou swap. Voyons pourquoi USDT a decimals = 6 et non les 9 habituels de TON, d'où sort ce nombre et comment l'obtenir en un seul appel, sans deviner.
Decimals d'un jetton sur TON : unités raw contre montant lisible
Une blockchain ne sait pas stocker de fractions. Pas du tout. Sur TON, comme presque partout ailleurs, tout montant vit dans le contrat sous forme d'entier — les fameuses unités raw (les plus petites unités indivisibles). Aucun 5.5 n'existe ni ne peut exister dans le dictionnaire du contrat — seulement un entier du genre 5500000.
Pour transformer cet entier en montant qu'un humain peut lire, il faut une échelle. Cette échelle, c'est decimals — la puissance de dix qui sépare l'entier stocké du montant lisible :
human = raw / 10^decimals
raw = human * 10^decimals
L'analogie est simple. L'argent dans votre porte-monnaie est en euros, mais la comptabilité de la banque compte tout en centimes, en nombres entiers : 100 centimes = 1 euro, autrement dit decimals = 2. Vous voulez afficher des euros à un humain ? Vous divisez les centimes par 10^2 = 100. Avec les jettons, c'est exactement pareil — seule la puissance de dix change.
Le point clé : la blockchain elle-même ne sait pas où se trouve la virgule. Elle ne manipule que des unités raw entières. C'est le client qui décide où la placer à l'affichage, en lisant decimals dans les métadonnées du jetton. Trompez-vous de decimals, et la virgule dérape : le montant part en cacahuète.
USDT sur TON : decimals = 6, la plupart des jettons : 9
Deux chiffres à retenir :
- USDT (Tether) sur TON →
decimals = 6. Donc1 USDT = 1 000 000 unités raw. - La plupart des autres jettons TON →
decimals = 9. C'est aussi la valeur par défaut : si le champdecimalsest carrément absent des métadonnées, le standard impose au client de le considérer égal à9.
D'où vient ce neuf ? GRAM lui-même (ex-Toncoin, renommé en juin 2026 — le réseau s'appelle toujours TON) a 9 décimales : 1 GRAM = 10^9 nanogrammes, et ce « nano » est précisément l'unité raw. Le standard des jettons TON a hérité de cette valeur comme défaut, et l'écrasante majorité des tokens du réseau vivent avec decimals = 9. Les développeurs prennent l'habitude d'écrire / 1e9 sans même regarder.
USDT, lui, est un invité venu du monde Ethereum, où Tether a historiquement 6 décimales. L'émetteur a conservé cette précision familière sur TON. USDT est donc précisément l'exception sur laquelle trébuchent presque tous ceux qui « ont juste codé 9 en dur » — et c'est justement le jetton le plus utilisé pour les paiements.
Chiffrons le coût de l'erreur. Supposons qu'un jetton-wallet contienne 5 000 000 unités raw d'USDT :
- correct (
decimals = 6) :5 000 000 / 10^6 = 5 USDT; - incorrect (
decimals = 9) :5 000 000 / 10^9 = 0.005.
L'erreur est exactement d'un facteur 10^(9−6) = 1000. Et dans l'autre sens : si l'utilisateur saisit « envoyer 5 USDT » et que vous multipliez par 10^9, vous tenterez d'en déplacer 1000 fois plus. Pour un bot de paiement, c'est la différence entre « payé » et « rejeté ».
D'où vient decimals : les métadonnées du jetton et le standard TEP-64
Point essentiel : decimals n'est ni un champ du code du wallet ni une constante du protocole. C'est une partie des métadonnées du jetton lui-même, décrites par le standard TEP-64 (Token Data Standard). Chaque jetton déclare lui-même son decimals, son nom, son symbole, son image.
TEP-64 autorise trois formats de stockage des métadonnées :
- on-chain — tous les champs sont dans un dictionnaire (dictionary) directement dans le contrat du jetton ; rien à télécharger ;
- off-chain — le contrat ne contient qu'un lien (
uri), et tout le JSON avec les champs (name,symbol,decimals,image) se trouve à cette URI, sur un serveur web ou dans IPFS ; - semi-chain (hybride) — une partie des champs dans le dictionnaire on-chain, le reste via
uri; le client télécharge le contenu off-chain et le fusionne avec les valeurs du dictionnaire.
La règle de fusion selon TEP-64 : si le dictionnaire contient la clé uri, le client doit télécharger le contenu off-chain à cette adresse et le combiner avec les valeurs du dictionnaire on-chain. Formats différents, coûts de lecture différents : l'on-chain se lit avec un seul appel de méthode get, l'off-chain exige en plus une requête HTTP. Gérer ces trois cas à la main, c'est une vraie partie de plaisir — et c'est précisément là qu'on apprécie de laisser un seul outil s'en charger à votre place.
Les métadonnées d'USDT : comment get_jetton_info renvoie decimals = 6
USDT sur TON stocke ses métadonnées au format off-chain : le contrat maître du jetton contient un lien vers un JSON off-chain, et c'est ce JSON qui porte name, symbol et, surtout, decimals = 6. Pour reconstituer proprement la fiche du jetton, le client doit lire le contrat, extraire le lien, télécharger le JSON et en parser les champs.
Pas besoin de garder le format TEP-64 en tête ni de décoder les cellules du dictionnaire à la main : c'est exactement le travail qu'un seul outil prend en charge. get_jetton_info va lui-même lire le contrat, décortiquer les métadonnées et renvoyer un decimals = 6 prêt à l'emploi — et c'est sur ce nombre que repose ensuite toute l'arithmétique.
Obtenir decimals en un seul appel : get_jetton_info
Plutôt que de lire le dictionnaire à la main, de détecter le format (on/off/semi-chain), de suivre l'URI et de fusionner le JSON, il existe un raccourci : get_jetton_info. C'est un outil du serveur MCP TONNode : il prend l'adresse du contrat maître d'un jetton et renvoie des métadonnées déjà assemblées — le nom, le symbole, decimals et l'offre totale.
TONNode est un serveur MCP hébergé pour TON. MCP (Model Context Protocol) est le standard par lequel les agents IA (Claude, Cursor, ChatGPT/Codex, n'importe quel client MCP) appellent des outils. Connexion gratuite en local, jeu complet d'outils de lecture :
{
"mcpServers": {
"ton": { "command": "npx", "args": ["-y", "@tonnode/mcp"] }
}
}
Le paquet @tonnode/mcp est open source (MIT) et parle le protocole natif ADNL de TON, sans couches HTTP intermédiaires. Ensuite, une simple demande en langage naturel suffit à l'agent :
Via l'outil
get_jetton_info, lis lesdecimalsdu jetton USDT sur TON (adresse du contrat maître : telle et telle) et calcule combien cela fait en USDT lisibles pour un solde de 5 000 000 raw.
get_jetton_info renverra decimals = 6, et toute l'arithmétique qui suit s'appuie sur ce nombre, pas sur une supposition. Le même appel sur n'importe quel autre jetton renverra sa propre valeur (le plus souvent 9, mais il faut vérifier à chaque fois). La règle d'or :
Ne codez pas
9en dur. Lisezdecimalsviaget_jetton_infopour chaque jetton.
Le neuf fonctionnera pour la majorité des tokens et cassera en silence sur USDT — précisément le jetton où circule le plus souvent de l'argent réel. Pourquoi un agent IA a besoin d'un accès MCP dédié à TON plutôt que d'un RPC public avec ses limites ? C'est détaillé dans la note sur le serveur MCP pour agents sur TON.
Pourquoi un mauvais decimals casse les soldes et les swaps
decimals n'est pas un détail cosmétique d'affichage. Il intervient partout où un montant franchit la frontière « raw ⇄ humain », et l'erreur se propage à toute la chaîne.
Les soldes
get_jetton_balance renvoie le solde du jetton en unités raw (le bon jetton-wallet est calculé on-chain, vous n'avez pas à le chercher vous-même). En soi, cet entier ne veut rien dire sans decimals — impossible de l'afficher correctement tant que vous ne l'avez pas divisé par 10^decimals :
raw = 5 000 000
decimals = 6 → 5 USDT ✅
decimals = 9 → 0.005 ❌ (1000 fois moins)
L'ordre correct dans un agent : d'abord get_jetton_info → récupérer decimals, puis get_jetton_balance → diviser le raw par 10^decimals. Et sur la façon dont les liteservers publics butent sur leurs limites avec ce type de requêtes de lecture, voyez l'analyse des limites des liteservers publics TON.
Les swaps
get_swap_quote renvoie une cotation DEX ferme GRAM⇄jetton (via le protocole Omniston, liquidité STON.fi + DeDust) — et le montant d'entrée, et l'estimation de sortie sont eux aussi en unités raw du jetton. Ici, un mauvais decimals frappe deux fois. Supposons que l'utilisateur veuille swapper 10 USDT : avec decimals = 6, la cotation doit recevoir 10 000 000 raw. Appliquez 9 par erreur — vous demandez 10 000 000 000 raw, soit un swap de 10 000 USDT qui n'existent pas sur le wallet. L'erreur inverse, au parsing de la réponse, sous-estimera le montant attendu d'un facteur 1000, et l'utilisateur en conclura que le taux, c'est du vol.
Le même principe vaut pour les cotations cross-chain et pour toute transaction : sur la blockchain, tout est en unités raw entières, et le seul pont vers les montants lisibles est le bon decimals.
Vérification en pratique : get_jetton_balance et get_swap_quote
Assemblons un court scénario que l'agent déroule tout seul, sans un seul chiffre codé en dur.
Scénario pas à pas
1. Lire decimals. get_jetton_info(USDT master) → decimals = 6.
2. Lire le solde. get_jetton_balance(propriétaire, USDT master) → 5 000 000 (raw). Calcul : 5 000 000 / 10^6 = 5 USDT. Avec 9, on aurait obtenu 0.005. C'est votre signal d'alarme : si un montant USDT vous paraît étrangement minuscule, vérifiez d'abord que vous n'avez pas appliqué 9 au lieu de 6.
3. Demander une cotation. On veut swapper 5 USDT en GRAM. En raw, cela fait 5 × 10^6 = 5 000 000 — c'est exactement ce montant qu'on passe à get_swap_quote. Le résultat arrivera lui aussi en raw, et GRAM a 9 décimales : on divise donc la réponse par 10^9 avant de l'afficher à l'utilisateur.
4. Vous ne faites pas confiance aux métadonnées ? Vous pouvez revérifier on-chain, en direct. run_get_method appelle n'importe quelle méthode get read-only d'un contrat — de la même façon, vous pouvez invoquer get_jetton_data sur le contrat maître et vérifier que les chiffres concordent. C'est plus flexible, mais cela suppose de connaître le format TEP-64 et de parser le dictionnaire à la main ; quand la vitesse et la fiabilité priment, get_jetton_info règle la question en une seule réponse. Ce qui distingue les fournisseurs RPC TON sur l'accès aux méthodes get et à l'archive : voir le comparatif honnête des fournisseurs RPC TON.
Le prompt de l'agent
Le prompt pour l'ensemble du scénario n'a rien de spectaculaire :
Prends USDT sur TON. Lis les
decimalsviaget_jetton_info. Récupère mon solde en raw viaget_jetton_balanceet convertis-le en USDT lisibles. Puis calcule viaget_swap_quoteune cotation pour swapper 5 USDT en GRAM — n'oublie pas de convertir les 5 USDT en raw avec ledecimalsque tu as lu.
Encore un détail pour les scénarios agentiques : les outils de swap de TONNode sont strictement non-custodial. Le serveur ne signe jamais rien et ne détient aucune clé — build_swap_tx renvoie un message TonConnect non signé, que le wallet de l'utilisateur signe lui-même. Même un decimals correct ne donne au serveur aucun contrôle sur les fonds : il ne fait que calculer et construire la transaction. Où se perdent les millisecondes et la latence dans les swaps sur TON : voir l'analyse du trading haute vitesse sur TON.
En bref
decimalsest la puissance de dix entre les unités raw de la blockchain et le montant lisible :human = raw / 10^decimals.- Le défaut sur TON, c'est 9 décimales ; USDT en a 6 (
1 USDT = 1 000 000raw). Les confondre = un écart d'un facteur 1000. decimalsvit dans les métadonnées du jetton (TEP-64), pas dans le code. USDT stocke ses métadonnées off-chain, maisget_jetton_inforenvoie quand mêmedecimals = 6en une seule réponse.- Ne codez pas
9en dur. Lisezdecimalsviaget_jetton_infoet bâtissez dessus tous vos soldes (get_jetton_balance) et vos cotations (get_swap_quote).
Prenez une clé Hobby gratuite (60 requêtes/min, sans carte bancaire) et lisez les decimals de n'importe quel jetton via get_jetton_info dès maintenant : https://tonnode.io/dashboard?plan=hobby
Donnez à votre agent l'accès à TON
16 outils MCP : lecture, swaps non-custodial, cross-chain et wallets. Forfait gratuit — 60 req/min, sans carte.