TON жетонындағы decimals дегеніміз не (USDT = 6, 9 емес)
TON жетонындағы decimals: USDT неге 6, ал жетондардың көпшілігі 9. get_jetton_info decimals-ті қалай қайтарады және бұл баланстар үшін неге критикалық.
Сіз USDT балансын көрсететін агент жазып отырсыз. Жетон-әмиянның балансын сұрайсыз, 5000000 аласыз, оны 10^9-ға бөлесіз — сонда экранда нақты 5 USDT-тың орнына 0.005 USDT шыға келеді. Транзакциялар өтеді, RPC жауап береді, get-әдіс сан қайтарады — ал сома бәрібір дәл 1000 есе қате шығады. Кінәлі — бәрі дерлік әдетпен хардкодтап қоятын жалғыз цифр: decimals.
Егер сіз ЖИ-агентті TON-ға қоссаңыз немесе жетон сомаларын қолмен санасаңыз, decimals — кез келген баланс пен свапқа дейін түсінуге тиіс бірінші нәрсе. USDT-де неге TON үшін әдеттегі 9 емес, decimals = 6 екенін, бұл сан жалпы қайдан шығатынын және оны болжамай, бір шақыруда қалай алуға болатынын талдап көрейік.
TON жетонындағы decimals: raw-бірліктер мен адам оқитын сан
Блокчейн бөлшек сандарды сақтай алмайды. Мүлдем. TON-да да, басқа жерлердің бәрінде де кез келген сома контрактіде бүтін сан ретінде жатады — raw-бірліктер деп аталатын (бөлінбейтін ең кіші бірліктер). Контракт сөздігінде ешқандай 5.5 жоқ және болуы да мүмкін емес — тек 5500000 тәрізді бүтін сан ғана бар.
Осы бүтін саннан адам көретін соманы алу үшін масштаб керек. Дәл сол масштаб — decimals: сақталған бүтін сан адам оқитын сомаға қатысты қаншаға жылжығанын көрсететін ондық дәреже:
human = raw / 10^decimals
raw = human * 10^decimals
Аналогия қарапайым. Әмияныңыздағы ақша — теңгемен, бірақ банк бухгалтериясында бәрі тиынмен, бүтін сандармен есептеледі: 100 тиын = 1 теңге, яғни decimals = 2. Адамға теңгені көрсеткің келсе — тиынды 10^2 = 100-ге бөлесің. Жетондарда да дәл солай, тек ондықтың дәрежесі басқа.
Түйінді тұс: блокчейннің өзі санның «үтірі» қай жерде екенін білмейді. Ол бүтін raw-бірліктермен жұмыс істейді. Пайдаланушыға көрсеткенде үтірді қайда қою керегін жетон метадеректеріндегі decimals мәнін оқитын клиент шешеді. decimals-пен қателестің — үтір ойда жоқ жерге кетті, сома асқабаққа айналды.
TON-дағы USDT decimals = 6, ал жетондардың көпшілігінде = 9
Есте сақтауға тиіс екі цифр:
- TON-дағы USDT (Tether) →
decimals = 6. Яғни1 USDT = 1 000 000 raw-бірлік. - Қалған TON жетондарының көпшілігі →
decimals = 9. Әрі дәл осы — әдепкі мән: егер метадеректердеdecimalsөрісі мүлдем көрсетілмесе, стандарт бойынша клиент оны9-ға тең деп есептеуге міндетті.
Тоғыздық қайдан шыққан. GRAM-ның өзінде (бұрынғы Toncoin, 2026 жылдың маусымында атауы өзгертілді — желі бұрынғысынша TON деп аталады) 9 таңба бар: 1 GRAM = 10^9 нанограмм, ал мұндағы «нано» — дәл сол raw-бірлік. TON жетондарының стандарты бұл мәнді әдепкі ретінде мұра етіп алды, сондықтан желідегі токендердің басым көпшілігі нақ decimals = 9-бен өмір сүреді. Әзірлеушілер / 1e9 деп қарамай жаза салуға үйреніп кетеді.
Ал USDT — Ethereum әлемінен келген қонақ, ол жақта Tether-де тарихи түрде 6 таңба. Эмитент әдеттегі дәлдігін TON-да да сақтап қалды. Сондықтан USDT — «жай ғана 9-ды хардкодтап қойғандардың» бәрі дерлік сүрінетін дәл сол ерекшелік, әрі бұл — төлемдерде ең жиі жүретін жетон.
Қатенің бағасын санап көрейік. Жетон-әмиянда 5 000 000 raw-бірлік USDT жатыр делік:
- дұрысы (
decimals = 6):5 000 000 / 10^6 = 5 USDT; - бұрысы (
decimals = 9):5 000 000 / 10^9 = 0.005.
Дәл 10^(9−6) = 1000 есе жаңылыс. Керісінше де солай: пайдаланушы «5 USDT жібер» деп енгізсе, ал сіз 10^9-ға көбейтсеңіз, 1000 есе көп соманы жылжытпақ боласыз. Төлем боты үшін бұл — «төленді» мен «қабылданбады» арасындағы айырма.
decimals қайдан алынады: жетон метадеректері және TEP-64 стандарты
Мынаны түсіну маңызды: decimals — әмиян кодындағы өріс те, протокол константасы да емес. Бұл — TEP-64 (Token Data Standard) стандартында сипатталған нақты жетонның метадеректерінің бөлігі. Әр жетон өзінің decimals мәнін, атауын, символын, суретін өзі мәлімдейді.
TEP-64 метадеректерді үш форматта сақтауға рұқсат етеді:
- on-chain — барлық өріс тікелей жетон контрактісіндегі сөздікте (dictionary) жатады; ештеңе жүктеп алудың қажеті жоқ;
- off-chain — контрактіде тек сілтеме (
uri) бар, ал өрістері (name,symbol,decimals,image) бар бүкіл JSON сол URI бойынша веб-серверде немесе IPFS-те жатады; - semi-chain (гибрид) — өрістердің бір бөлігі он-чейн сөздікте, бір бөлігі
uriбойынша; клиент off-chain контентті жүктеп алады да, оны сөздіктегі мәндермен мерж жасайды.
TEP-64 бойынша біріктіру ережесі мынадай: егер сөздікте uri кілті болса, клиент сілтеме бойынша off-chain контентті жүктеп алып, оны он-чейн сөздіктегі мәндермен біріктіруге міндетті. Формат әртүрлі болса — оқу бағасы да әртүрлі: on-chain бір get-әдіспен оқылады, off-chain үшін оның үстіне HTTP-сұрау да керек. Осы үш жағдайды қолмен өңдеу — өз алдына бір «қызық», ал дәл осы жерде мұны сіздің орныңызға бір құралдың істегені ыңғайлы.
USDT метадеректері: get_jetton_info decimals = 6 мәнін қалай береді
TON-дағы USDT метадеректерін off-chain форматта сақтайды: мастер-жетон контрактісінде off-chain JSON-ға сілтеме жатыр, ал name, symbol және ең бастысы decimals = 6 дәл сол JSON-да жазылған. Жетон карточкасын дұрыстап жинау үшін клиентке контрактіні оқып, сілтемені тауып, ол бойынша JSON-ды жүктеп алып, өрістерін талдау керек.
TEP-64 форматын жаттап алудың және сөздік ұяшықтарын қолмен парсылаудың қажеті жоқ: бұл — дәл сол бір құрал өз мойнына алатын жұмыс. get_jetton_info контрактіге өзі барады, метадеректерді талдайды және дайын decimals = 6 мәнін қайтарады — ал бүкіл арифметика соның үстіне құрылады.
decimals-ті бір шақыруда қалай алуға болады: get_jetton_info
Сөздікті қолмен оқып, форматты тану (on/off/semi-chain), URI бойынша жүріп, JSON-ды мерж жасаудың орнына — get_jetton_info бар. Бұл — TONNode MCP-серверінің құралы: ол жетонның мастер-контракт мекенжайын қабылдайды және жиналып қойған метадеректерді — атауын, символын, decimals мәнін және эмиссиясын — қайтарады.
TONNode — бұл TON үшін hosted MCP-сервер. MCP (Model Context Protocol) — ЖИ-агенттер (Claude, Cursor, ChatGPT/Codex, кез келген MCP-клиент) құралдарды шақыратын стандарт. Тегін, жергілікті қосуға болады — оқуға арналған құралдардың толық жинағы:
{
"mcpServers": {
"ton": { "command": "npx", "args": ["-y", "@tonnode/mcp"] }
}
}
@tonnode/mcp пакеті — open source (MIT), TON-ның нативті ADNL-протоколы бойынша, HTTP-қабаттарсыз жұмыс істейді. Әрі қарай агентке адам тіліндегі кәдімгі өтініштің өзі жеткілікті:
get_jetton_infoқұралы арқылы TON-дағы USDT жетоныныңdecimalsмәнін біл (мастер-контракт мекенжайы — мынау) және 5 000 000 raw баланс адам оқитын USDT-де қанша болатынын есепте.
get_jetton_info decimals = 6 мәнін қайтарады, әрі бүкіл кейінгі арифметика болжамға емес, дәл сол санға сүйеніп құрылады. Дәл сол шақыру еркін алынған жетон үшін оның өз мәнін қайтарады (көбіне 9, бірақ тексеру әрдайым керек). Басты ереже:
9-ды хардкодтамаңыз. Әр жетон үшінdecimalsмәнінget_jetton_info-дан оқыңыз.
Тоғыздық токендердің көпшілігінде жұмыс істейді де, USDT-де үнсіз сынады — ал бұл дәл нақты ақша жиі айналатын жетон. ЖИ-агентке лимиттері бар жария RPC емес, TON-ға бөлек MCP-қатынау неге керек екені TON-дағы агенттерге арналған MCP-сервер туралы жазбада талданған.
Қате decimals балансты да, свапты да неге бұзады
decimals — көрсету үшін жасалған косметика емес. Ол сома «raw ⇄ адам» шекарасын кесіп өтетін әрбір тұста қатысады, ал қате бүкіл тізбек бойымен таралады.
Баланстар
get_jetton_balance жетон балансын raw-бірліктермен қайтарады (керекті жетон-әмиян он-чейн есептеледі, оны өзіңіз іздеп жүрудің қажеті жоқ). Бұл бүтін санның өзі decimals-сіз ешнәрсені білдірмейді — 10^decimals-ке бөлмейінше, оны пайдаланушыға дұрыс көрсете алмайсыз:
raw = 5 000 000
decimals = 6 → 5 USDT ✅
decimals = 9 → 0.005 ❌ (1000 есе аз)
Агенттегі дұрыс реттілік: алдымен get_jetton_info → decimals алу, содан кейін get_jetton_balance → raw-ды 10^decimals-ке бөлу. Ал жария лайтсерверлердің дәл осындай оқу сұрауларында лимитке қалай тірелетіні — TON жария лайтсерверлерінің лимиттерін талдауда.
Сваптар
get_swap_quote GRAM⇄жетон DEX бойынша бекітілген котировка береді (Omniston протоколы арқылы, өтімділік — STON.fi + DeDust) — енгізілетін соманы да, алынатын соманың болжамын да жетонның raw-бірліктерімен қайтарады. Мұнда қате decimals екі есе соғады. Айталық, пайдаланушы 10 USDT свап жасағысы келеді: decimals = 6 кезінде котировкаға 10 000 000 raw беру керек. Қателесіп 9 қолдансаңыз — 10 000 000 000 raw сұрайсыз, яғни әмиянда жоқ 10 000 USDT-ға свап. Жауапты талдағандағы кері қате күтілетін соманы 1000 есе төмендетеді, сонда пайдаланушы бағам тонаушылық екен деп ойлайды.
Дәл сол принцип кроссчейн-котировкаларда да, кез келген транзакцияда да жұмыс істейді: блокчейнде бәрі бүтін raw-бірліктермен, ал адам оқитын сомаларға апаратын жалғыз көпір — дұрыс decimals.
Тәжірибеде тексеру: get_jetton_balance және get_swap_quote
Агент бірде-бір хардкодталған цифрсыз өзі жүріп өтетін қысқа сценарий жинайық.
Қадамдық сценарий
1. decimals-ті білу. get_jetton_info(USDT master) → decimals = 6.
2. Балансты оқу. get_jetton_balance(иесі, USDT master) → 5 000 000 (raw). Санаймыз: 5 000 000 / 10^6 = 5 USDT. Егер 9-ды алсақ — 0.005 шығар еді. Бұл — сіздің сигналдық тестіңіз: USDT-де күтпеген жерден өте кішкентай сан көрсеңіз, ең әуелі 6-ның орнына 9 қолданылып кетпегенін тексеріңіз.
3. Котировка сұрау. 5 USDT-ны GRAM-ға свап жасағымыз келеді. Raw-мен бұл 5 × 10^6 = 5 000 000 — get_swap_quote-қа дәл осы соманы береміз. Нәтиже де raw-мен келеді, ал GRAM — 9 таңбалы, демек пайдаланушыға көрсету үшін жауапты 10^9-ға бөлеміз.
4. Метадеректерге сенбейсіз бе? Он-чейн тікелей қайта тексеруге болады. run_get_method контрактінің кез келген read-only get-әдісін шақырады — дәл сол жолмен мастер-контрактіден get_jetton_data-ны сұрап, сандардың сәйкес келетініне көз жеткізуге болады. Бұл икемдірек, бірақ TEP-64 форматын білуді және сөздікті қолмен парсылауды талап етеді; жылдамдық пен сенімділік маңызды болғанда get_jetton_info мәселені бір жауаппен жабады. TON RPC-провайдерлерінің get-әдістерге және мұрағатқа қатынау бойынша немен ерекшеленетіні — TON RPC-провайдерлерінің адал салыстыруында.
Агентке арналған промпт
Бүкіл сценарийге арналған промпт әдеттегідей қарапайым көрінеді:
TON-дағы USDT-ны ал.
get_jetton_infoарқылыdecimalsмәнін оқы.get_jetton_balanceарқылы менің балансымды raw-мен алып, адам оқитын USDT-ға аудар. Содан кейінget_swap_quoteарқылы 5 USDT-ны GRAM-ға свап жасаудың котировкасын есепте — 5 USDT-ны оқылғанdecimalsбойынша raw-ға аударуды ұмытпа.
Агенттік сценарийлер үшін тағы бір егжей-тегжей: TONNode-тың свап құралдары қатаң түрде кастодиалды емес. Сервер ешқашан қол қоймайды және кілттерді сақтамайды — build_swap_tx қол қойылмаған TonConnect-хабарламасын қайтарады, оған пайдаланушының әмияны қол қояды. Тіпті дұрыс decimals те серверге қаражатты билеу мүмкіндігін бермейді: ол тек есептейді және транзакция жинайды. TON-дағы свапта миллисекундтар мен кідірістердің қай жерде жоғалатыны — TON-дағы жылдам трейдингті талдауда.
Қысқаша
decimals— блокчейндегі raw-бірліктер мен адам оқитын сома арасындағы ондық дәреже:human = raw / 10^decimals.- TON-дағы әдепкі мән — 9 таңба; USDT — 6 (
1 USDT = 1 000 000raw). Шатастырсаң — 1000 есе жаңылыс. decimalsкодта емес, жетонның метадеректерінде (TEP-64) тұрады. USDT-де метадеректер off-chain сақталады, бірақget_jetton_infoбәрібірdecimals = 6мәнін бір жауаппен береді.9-ды хардкодтамаңыз.decimalsмәнінget_jetton_infoарқылы оқыңыз да, барлық баланс (get_jetton_balance) пен котировканы (get_swap_quote) соның үстіне құрыңыз.
Тегін Hobby кілтін алыңыз (60 сұрау/мин, картасыз) және кез келген жетонның decimals мәнін get_jetton_info арқылы дәл қазір оқыңыз: https://tonnode.io/dashboard?plan=hobby
Агентіңізге TON-ға қолжетімділік беріңіз
16 MCP-құрал: оқу, кастодиалды емес сваптар, кроссчейн және әмияндар. Тегін тариф — 60 сұрау/мин, карта керек емес.