用途
EVM Token Decimals 针对的是 EVM 生态中一类常见且隐蔽的问题:代币小数位不匹配。这类问题不会直接报错,却容易让余额或美元估值出现数量级偏差。该技能适用于需要在多条 EVM 链上正确读取和处理 ERC-20 金额的场景。
何时使用
- 在 Python、TypeScript 或 Solidity 中读取 ERC-20 余额
- 根据链上余额计算法币价值
- 跨多条 EVM 链比较代币数量
- 处理桥接资产
- 构建投资组合追踪器、机器人或聚合器
主要能力
核心做法包括以下几点:
- 运行时查询精度:不要假设稳定币在各处都使用相同小数位,应在运行时调用 decimals()。
- 链感知缓存:按 (chain_id, token_address) 缓存结果,而不是按代币符号缓存。
- 精确数学:使用 Decimal、BigInt 或等价精确数学类型,避免使用浮点数进行价值计算。
- 桥接资产处理:桥接或包装资产发生变化后,应重新查询 decimals。
- 防御异常代币:decimals() 调用可能回滚,此时可记录警告并回退到默认值(示例中为 18),并保持该回退行为可见。
- Solidity 归一化:提供 normalizeToWad 函数,将任意精度代币金额统一归一化到 18 位 WAD,便于比较与定价。
使用方式
资料给出了 Python(web3.py)、TypeScript(ethers)与 Solidity 的示例代码,实际操作方式为:
- Python:定义包含 decimals 与 balanceOf 的 ERC20_ABI,通过 contract.functions.decimals().call() 获取精度,用 Decimal(raw) / Decimal(10 ** decimals) 计算可读余额;也可用 functools.lru_cache 按 chain_id 与 token_address 缓存 get_decimals。
- TypeScript:使用 ethers 的 Contract 与 formatUnits,并发读取 decimals 与 balanceOf 后格式化余额。
- Solidity:通过 IERC20Metadata 接口读取 decimals,并按精度差异乘除 10 的幂次归一化到 18 位。
- 链上快速检查:使用 cast call <token_address> "decimals()(uint8)" --rpc-url <rpc>。
适用场景
适合投资组合追踪、余额展示、法币估值、跨链金额对比、桥接资产处理、机器人及聚合器等需要正确理解代币精度的应用。
限制与注意事项
- 示例中的回退默认值(18)只是防御性处理,并不意味着所有异常代币都是 18 位;应记录日志并保持可见。
- 内部记账应在比较或定价前统一归一化,避免混用不同精度。
- 关于支持的链清单、性能开销、最低运行环境、安装方式与收费信息,资料暂未提供。