帮助你在 EVM 多链应用中安全处理代币精度与小数位差异
复制安装指令,让 AI 自动完成配置 · 推荐新手
请帮我安装 askskill 上的 "evm-token-decimals" 技能: 1. 下载 https://raw.githubusercontent.com/affaan-m/ECC/main/skills/evm-token-decimals/SKILL.md 2. 保存为 ~/.claude/skills/evm-token-decimals/SKILL.md 3. 装好后重载技能,告诉我可以用了
请为 EVM DeFi 机器人设计一套安全的代币 decimals 处理方案:要求运行时查询 decimals、按 chainId+tokenAddress 做缓存、处理桥接代币在不同链上 decimals 不一致的情况,并给出将原始链上金额统一标准化为 18 位精度的 TypeScript 示例与常见陷阱清单。
一套可落地的多链 decimals 处理策略,含缓存规则、标准化代码示例与风险说明。
我的多链资产仪表盘里,同一个桥接 USDC 在不同链上显示的余额和价格换算结果不一致。请帮我制定排查步骤:如何验证 token decimals 来源、识别缓存过期或错误映射、区分原生代币与桥接代币,并输出一份诊断清单。
一份系统化的诊断流程,用于定位 decimals 配置、缓存或映射导致的显示异常。
请为链上数据分析管道设计 decimals 校验机制:输入包括多个 EVM 链的 token transfer 事件和代币元数据。请输出校验规则,识别 decimals 缺失、异常变化、桥接资产精度漂移,并给出告警条件和伪代码。
一套适合数据管道的精度校验与告警方案,帮助提前发现多链代币小数位问题。
Silent decimal mismatches are one of the easiest ways to ship balances or USD values that are off by orders of magnitude without throwing an error.
Never assume stablecoins use the same decimals everywhere. Query decimals() at runtime, cache by (chain_id, token_address), and use decimal-safe math for value calculations.
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)
Do not hardcode 1_000_000 because a symbol usually has 6 decimals somewhere else.
from functools import lru_cache
@lru_cache(maxsize=512)
def get_decimals(chain_id: int, token_address: str) -> int:
w3 = get_web3_for_chain(chain_id)
contract = w3.eth.contract(
address=Web3.to_checksum_address(token_address),
abi=ERC20_ABI,
)
return contract.functions.decimals().call()
try:
decimals = contract.functions.decimals().call()
except Exception:
logging.warning(
"decimals() reverted on %s (chain %s), defaulting to 18",
token_address,
chain_id,
)
decimals = 18
Log the fallback and keep it visible. Old or non-standard tokens still exist.
interface IERC20Metadata {
function decimals() external view returns (uint8);
}
function normalizeToWad(address token, uint256 amount) internal view returns (uint256) {
uint8 d = IERC20Metadata(token).decimals();
if (d == 18) return amount;
if (d < 18) return amount * 10 ** (18 - d);
return amount / 10 ** (d - 18);
}
import { Contract, formatUnits } from 'ethers';
const ERC20_ABI = [
'function decimals() view returns (uint8)',
'function balanceOf(address) view returns (uint256)',
];
async function getBalance(provider: any, tokenAddress: string, wallet: string): Promise<string> {
const token = new Contract(tokenAddress, ERC20_ABI, provider);
const [decimals, raw] = await Promise.all([
token.decimals(),
token.balanceOf(wallet),
]);
return formatUnits(raw, decimals);
}
cast call <token_address> "decimals()(uint8)" --rpc-url <rpc>
decimals() at runtimeDecimal, BigInt, or equivalent exact math, not float为 Quarkus 项目执行发布前验证闭环,涵盖构建、测试、扫描与差异审查。
帮助开发者在多条 EVM 链上实现免 gas 支付与跨链转账集成。