如何使用AssemblyScript将NEAR金额转换为yocto单位
NEAR AssemblyScript 小额NEAR转yocto单位正确实现
错误根因
- NEAR的最小单位是yoctoNEAR,
1 NEAR = 10^24 yoctoNEAR,链上所有金额逻辑必须基于整数运算实现。 - 浮点数
f64存在固有精度缺陷,无法精确表示10^24量级的整数,将u128类型的ONE_NEAR转f64做乘法再转回u128的流程,会触发WebAssembly运行时的算术异常,也就是你遇到的除零类trap报错。 - 浮点数运算本身存在非确定性,完全不适用于链上资金计算场景,轻则报错,重则产生资金计算漏洞。
正确实现方式
全程使用u128类型做整数运算,完全规避浮点数转换:
// near-sdk-as 内置的ONE_NEAR常量本身就是u128类型,值为10^24,可直接引入使用 import { u128, ONE_NEAR } from "near-sdk-as"; // 示例1:转换0.5 NEAR 到yoctoNEAR const pointFiveNear: u128 = ONE_NEAR / u128.from(2); // 运算结果为500000000000000000000000 yoctoNEAR,可直接存储、转账使用 // 示例2:转换0.1 NEAR const pointOneNear: u128 = ONE_NEAR / u128.from(10); // 示例3:转换任意小数金额,比如0.37 NEAR,先乘分子再除分母避免精度损失 const pointThreeSevenNear: u128 = ONE_NEAR * u128.from(37) / u128.from(100);
存储规范
- 合约内所有金额字段统一使用
u128类型存储,单位固定为yoctoNEAR,禁止存储浮点数格式的NEAR原值。 - 如果需要接收前端传入的金额参数,优先要求前端直接传yocto单位的整数值;如果接收字符串格式的NEAR金额,使用SDK内置的字符串转u128方法解析,不要走浮点数中间转换。
警示:所有链上资金相关逻辑禁止使用f32/f64浮点类型,这类类型的精度损失和运算非确定性会直接导致合约资金风险。
内容的提问来源于stack exchange,提问作者Hamza Tahir
相关产品推荐
相关产品推荐

