nanoton、GRAM 与九位小数

TON 上的每一个金额都是整数。liteserver、API 或 get 方法从不返回“1.5 GRAM”;它们返回 1500000000,也就是 nanoton 的数量,由客户端决定如何显示。1 GRAM——TON 原生币改名后的名称,之前叫 Toncoin;网络本身仍然叫 TON——等于 10⁹ nanoton,所以显示金额就是把这个整数的小数点向左移动九位:

Text
1 GRAM           = 1 000 000 000 nanoton
0.000000001 GRAM = 1 nanoton
1e9 GRAM         = 1 000 000 000 000 000 000 nanoton

换算器做的正是这件事,仅此而已:移动小数点。这里没有汇率,也不查询链上数据。

为什么这个工具拒绝使用浮点数

JavaScript 的 number 是 64 位浮点数。它只能精确表示 2⁵³ 以内的整数,约 9.007 × 10¹⁵——换成 nanoton 大约是 900 万 GRAM——而且大多数小数根本无法表示:0.1 + 0.2 得到 0.30000000000000004。因此把余额除以 1e9 再乘回去是有损的往返,而在一笔交易里差一个 nanoton 的金额仍然是错误的金额。

本页的一切都是基于十进制字符串的 BigInt 运算。无法用该单位的小数位数表示的值——0.0000000001 GRAM,即十分之一个 nanoton——是一个错误,绝不会被四舍五入。科学计数法也同样处理:1e9 是十亿,2.5e-3 是 0.0025,两者都是精确的。

Jetton 与 decimals

Jetton 的数量同样是整数,以该 Jetton 自己的基本单位计。多少个基本单位构成一个显示单位,由 Jetton 的 decimals 决定,它发布在 Jetton 的元数据中——主合约 get_jetton_data get 方法返回的 content cell——键名为 decimals。当该键缺失时,标准(TEP-64)规定为 9。

TON 上的 USDT 使用 6,与其他链上的 USDT 一致:1 USDT 是 1000000 个原始单位。如果你以为是九位小数而发送了 1000000000,那就发出了 1,000 USDT——这是网络上最常见的单位错误。预设涵盖 USDT 和通用的九位;对于你正在查看的 Jetton,decimals 字段可以填 0 到 30 之间的任何值。

这个版本不会从链上读取 decimals。如果你不知道,请先通过 liteserver 或区块浏览器读取 Jetton 的元数据,再相信这里的数字。

换算器接受的输入

带一个小数点或一个小数逗号(1,5)的数字;当存在小数点时,空格、下划线或逗号作为千位分隔符(1 000.25、1,000,000.5);前置的 +;以及指数(1e9、2.5E-3)。负数会被拒绝。输出是纯粹的整数或小数,另附一个分组显示的版本便于阅读。