EVM 代币精度
静默的精度不匹配是导致余额或美元价值出现数量级偏差且不抛出错误的最常见原因之一。
适用场景
- 在 Python、TypeScript 或 Solidity 中读取 ERC-20 余额
- 根据链上余额计算法币价值
- 跨多条 EVM 链比较代币数量
- 处理跨链桥接资产
- 构建投资组合追踪器、机器人或聚合器
工作原理
切勿假设稳定币在所有链上使用相同的精度。在运行时查询 decimals(),按 (chain_id, token_address) 进行缓存,并使用精度安全的数学运算进行价值计算。
示例
运行时查询精度
from decimal import Decimal
from web3 import Web3
ERC20_ABI = [
{"name": "decimals", "type": "function", "inputs": [],
"outputs": [{"type": "uint8"}], "stateMutability": "view"},
{"name": "balanceOf", "type": "function",
"inputs": [{"name": "account", "type": "address"}],
"outputs": [{"type": "uint256"}], "stateMutability": "view"},
]
def get_token_balance(w3: Web3, token_address: str, wallet: str) -> Decimal:
contract = w3.eth.contract(
address=Web3.to_checksum_address(token_address),
abi=ERC20_ABI,
)
decimals = contract.functions.decimals().call()
raw = contract.functions.balanceOf(Web3.to_checksum_address(wallet)).call()
return Decimal(raw) / Decimal(10 ** decimals)
不要硬编码 1_000_000,因为同名代币在其他链上通常有 6 位小数。
按链和代币缓存
from functools import lru_cache
@lru_cache(maxsize=512)
def get_decimals(chain_id…