Fundamentals·5 分钟阅读

wei、gwei、ether:在生产环境里把单位搞对

加密后端里最常见的单个 bug 就是单位错误 —— 把 wei 当 ether 显示,或者更糟,直接照着发出去。修法既枯燥又绝对:链上金额永远不用浮点数,并且时刻清楚一个数值到底是哪个单位。

单位阶梯

ether 有 18 位小数。1 ether = 10^9 gwei = 10^18 wei。gwei(10^9 wei)是 gas 价格的报价单位;wei 则是每一个 RPC 数值所采用的基础单位。Bitcoin 的对应单位是 satoshi(10^-8 BTC),TRON 的是 sun(10^-6 TRX),TON 的是 nanoton(10^-9 TON)。每条链都有一个整数形式的基础单位 —— 就在这个单位上做运算。

浮点数为什么会出错

IEEE-754 的 double 只有 53 位尾数,约合 15–16 位有效十进制数字。一个 wei 数值可能有 19 位以上,所以一旦你把它解析成 JavaScript number,就会丢失精度 —— 而且是悄无声息地。这个舍入误差在相对意义上微不足道,在账本里却是灾难性的。请从头到尾使用原生 BigInt,或一个大十进制(big-decimal)库。

只在边界处做换算

在你系统的每一处 —— 存储、算术、比较 —— 都把金额保持为基础单位的整数。只在展示边界处才把它换算成人类可读的十进制字符串,而用户输入则在进来的那一刻立即解析回基础单位。只要有浮点数在这两个边界之间碰到了金额,就当作 bug 来处理。

1st Node Engineering

常见问题

小额金额用 JavaScript number 安全吗?

不安全 —— 界线要划在类型上,而不是大小上。只要有任何一条代码路径对金额用了浮点数,早晚会有一个大数值流经它。无论量级大小,所有链上金额都用 BigInt。

不用库,怎么把一个 wei 数值显示成 ether?

用整数/BigInt 运算除以 10^18 得到整数部分,再把余数格式化为小数位 —— 绝不要用浮点除法。我们的单位换算工具做的正是这件事。

相关

充值、拿密钥、上线。

自助开通。支持加密货币或银行卡。按额度计费——重型原语更贵,简单调用很便宜。

获取 API 密钥