﻿---
title: "如何核对代币的小数位数"
description: "从正确的合约和区块核对 ERC-20 代币的 decimals，并在不引入浮点误差的前提下复核原始余额、转账、授权与跨链换算。"
image: "https://wiki.fcontext.com/og.png"
---

> Documentation Index
> Fetch the complete documentation index at: https://wiki.fcontext.com/llms.txt
> Use this file to discover all available pages before exploring further.

# 如何核对代币的小数位数

> 仅供教育参考，不构成投资或安全建议。小数位数不能证明代币的身份、价值、储备或安全性。

<a id="answer"></a>

## 直接答案

对于 ERC-20 代币，`decimals()` 是可选元数据，用来告诉界面如何显示整数形式的代币单位。如果返回 `d`，惯常的显示金额是 `raw / 10^d`。它不会改变合约运算，也不能认证代币身份。信任结果前，应核对链、准确合约地址、代码或代理实现以及区块。

通过独立 RPC 在指定区块直接读取 `decimals()`，按 ABI 将返回值解码为 `uint8`，再与发行方官方合约名录和可信区块浏览器比较。随后用原始 `balanceOf`、转账、授权、收据与事件值检验该比例。调用不存在、回退、返回畸形数据或与其他证据冲突时，不要悄悄假定为 `18`。

<a id="mechanism"></a>

## 工作原理

ERC-20 存储和转移的是无符号整数金额。显示层负责插入小数点，合约接收的仍是整数。转换用户输入时应使用十进制字符串或任意精度整数运算，绝不能使用二进制浮点数。只有乘以 `10^d` 后得到整数的数量才可表示。

因为 `decimals()` 是可选项，合规代币可以不实现它。自定义或可升级实现也可能返回意外值，或在升级后改变行为。对于 ERC-1967 代理，应检查代理地址、实现或信标、管理员和升级事件；代币状态要在代理地址读取，并将所有比较固定在同一区块。

授权额度和 ERC-2612 `permit` 的值也是原始整数。转账显示正确，并不能证明授权、路由器最低金额、跨链金额或会计数据库采用了相同比例。跨链桥两端合约可能使用不同小数位，应按桥的书面换算与舍入规则，分别比较两端的人类可读价值和原始单位。

按以下流程核对：

1. 固定链 ID 或域、代币合约、区块号、RPC 端点和观察时间。
2. 通过发行方官方名录确认地址；名称、符号、图标和搜索结果均不能作为权威证据。
3. 检查已部署代码以及地址是否为代理；记录实现或信标、管理员和近期升级。
4. 调用 `decimals()` 并按 ABI 解码 `uint8`；如实记录成功、回退、空值或畸形输出，不要填入默认值。
5. 在兼容区块读取原始 `balanceOf`、`totalSupply`、授权额、交易 calldata、收据和事件，再按观察到的比例格式化。
6. 用整数运算重算转账、授权、报价和跨链金额，并计入费用、舍入、零头、变基或转账税。
7. 先模拟并发送小额交易，再核对交易前后的原始余额；界面、RPC、事件或余额只要有一处不一致就停止。

<a id="example"></a>

## 示例

- **同一原始值，两种比例。** 当 `raw = 123456789` 时，`d = 6` 显示为 `123.456789`；`d = 18` 则显示为 `0.000000000123456789`，两者相差 `10^12` 倍。
- **必须考虑可表示性。** 当 `d = 6` 时，`1.25` 个代币换算为 `1250000` 个原始单位。`0.0000001` 个代币小于一个原始单位，必须拒绝，或按明确规则舍入。
- **授权比例不匹配。** 当 `d = 6` 时，`100` 个代币的授权额是 `100000000`。若按 `d = 18` 编码，会得到 `100000000000000000000`，比预期大 `10^12` 倍。
- **跨链重新缩放。** 若书面规定的 `1:1` 路由把 `d = 6` 的源代币转换为 `d = 18` 的目标表示，源端原始值 `2500000` 表示 `2.5` 个代币，目标端原始值 `2500000000000000000` 也表示 `2.5`。费用、上限、零头和实际到账余额仍须核对。

<a id="risks"></a>

## 风险

- 在错误的链上查询了正确地址。
- 复制的名称、符号或图标掩盖了另一个合约。
- 代理实现或信标在早先检查后发生变化。
- RPC 或浏览器提供过时、未最终确认或相互矛盾的状态。
- 缺失或畸形元数据被悄悄替换为 `18`。
- 二进制浮点换算对大额或高精度金额产生舍入。
- 钱包正确格式化转账，却错误格式化授权或 permit。
- 数据库混用了原始单位和人类可读金额。
- 跨链桥假定两端小数位相同，或未披露零头舍入。
- 转账扣费、变基、铸造、销毁、暂停或冻结行为破坏简单对账。
- 交易 calldata、事件、收据和实际余额变化不一致。
- 将小数位核对误当成发行方、储备、流动性或安全性的证明。

<a id="misconceptions"></a>

## 常见误区

- **所有 ERC-20 代币都有 `18` 位小数。** 该元数据是可选的，实现可以返回其他值。
- **小数位是 EVM 使用的精度位数。** 它是十进制显示约定；代币运算仍是整数运算。
- **浏览器格式化的余额是独立确认。** 它可能依赖同一次元数据调用，因而共享同一错误。
- **相同符号和小数位可确定同一资产。** 还必须核对正确链、准确合约和发行方证据。
- **小额转账成功就验证了所有集成。** 授权、路由器、跨链桥、交易所和会计系统可能分别缩放金额。

<a id="related"></a>

## 相关主题

- [代币合约核验](/crypto/token-contract-verification/)
- [钱包 calldata 解码](/crypto/calldata-decoding-wallet/)
- [跨链代币核验](/crypto/bridge-token-verification/)
- [转账扣费代币风险](/crypto/fee-on-transfer-token-risk/)
- [代理合约](/crypto/proxy-contract/)

<a id="sources"></a>

## 来源

- [ERC-20：代币标准](https://eips.ethereum.org/EIPS/eip-20) - Ethereum Improvement Proposals（访问日期：2026-08-21）
- [ERC-20](https://docs.openzeppelin.com/contracts/5.x/erc20) - OpenZeppelin Docs（访问日期：2026-08-21）
- [JSON-RPC API](https://ethereum.org/developers/docs/apis/json-rpc/) - ethereum.org（访问日期：2026-08-21）
- [ERC-1967：代理存储槽](https://eips.ethereum.org/EIPS/eip-1967) - Ethereum Improvement Proposals（访问日期：2026-08-21）
- [ERC-2612：EIP-20 签名授权的 Permit 扩展](https://eips.ethereum.org/EIPS/eip-2612) - Ethereum Improvement Proposals（访问日期：2026-08-21）

Source: https://wiki.fcontext.com/zh-cn/crypto/token-decimals-verification/index.mdx
