ethers.js-8-bigNmber和callstatic模拟
⸻
🚀 1️⃣ ethers.js 的数值转换(0 ~ 18 精度)
以及 BigNumber(不是原生 BigInt)
⸻
📌 BigNumber 简介
• ethers.js 使用 ethers.BigNumber(不是 BigInt)。
• 因为以太坊所有 uint256 都超出 JS 的 Number(安全上限是 2^53)。
• BigNumber 支持 .add() .mul() .div() .toString() 等方法。
例如:
import { ethers } from “ethers”;
const big = ethers.BigNumber.from(“1000000000000000000”);
console.log(big.toString()); // “1000000000000000000”
⸻
⚙️ 0~18 精度的 Wei 与 Token 转换
以太坊常用:
• Wei: 最小单位,整数。
• ETH: 18 位小数。
• ERC20 代币通常也是 18 位(USDT 可能是 6 位)。
⸻
🔁 ETH ⇔ Wei
➡️ ETH(字符串) -> Wei(BigNumber)
const wei = ethers.utils.parseEther(“1.5”); // “1.5 ETH”
console.log(wei.toString()); // “1500000000000000000”
➡️ Wei(BigNumber) -> ETH(字符串)
const eth = ethers.utils.formatEther(wei);
console.log(eth); // “1.5”
⸻
🔁 Token(任意精度) ⇔ Wei
➡️ 小数转整数
// 18 decimals
const amount18 = ethers.utils.parseUnits(“123.456789”, 18);
console.log(amount18.toString()); // “123456789000000000000”
// 6 decimals (比如 USDT)
const amount6 = ethers.utils.parseUnits(“123.456”, 6);
console.log(amount6.toString()); // “123456000”
➡️ 整数转小数
const back18 = ethers.utils.formatUnits(amount18, 18);
console.log(back18); // “123.456789”
const back6 = ethers.utils.formatUnits(amount6, 6);
console.log(back6); // “123.456”
⸻
📝 ✨ 整个 0~18 的转换示例
import { ethers } from “ethers”;
for (let decimals = 0; decimals <= 18; decimals += 3) {
const value = “123.456”;
const toWei = ethers.utils.parseUnits(value, decimals);
const back = ethers.utils.formatUnits(toWei, decimals);
console.log(${value} @ ${decimals} decimals -> ${toWei.toString()} -> ${back}
);
}
输出类似:
123.456 @ 0 decimals -> 123 -> 123
123.456 @ 3 decimals -> 123456 -> 123.456
123.456 @ 6 decimals -> 123456000 -> 123.456
123.456 @ 9 decimals -> 123456000000 -> 123.456
…
123.456 @ 18 decimals -> 123456000000000000000 -> 123.456
⸻
🚀 2️⃣ callStatic 用法详解 + Demo
⸻
📚 callStatic 是什么?
用于**「在本地节点上预演写操作」**,不会真正发出交易,只会告诉你执行结果或是否会 revert。
非常适合:
• 查看执行结果(函数返回值)
• 判断是否会失败(节省 gas)
⸻
🔥 简单 Demo
假设你的合约里有:
function buy(uint256 amount) external returns (uint256 minted);
你可以这样用:
import { ethers } from “ethers”;
const provider = new ethers.providers.JsonRpcProvider(“https://rpc-url”);
const wallet = new ethers.Wallet(“0xyourprivatekey”, provider);
const contract = new ethers.Contract(contractAddress, abi, wallet);
async function previewBuy() {
const amount = ethers.utils.parseUnits(“10”, 18);
// 用 callStatic 来模拟执行
try {
const minted = await contract.callStatic.buy(amount);
console.log(“预计会 mint:”, minted.toString());
} catch (err) {
console.error(“交易会失败:”, err);
}
}
previewBuy();
这不会真正写入链上,也不花 gas。
但如果 callStatic 返回就说明交易按当前状态可以正常执行。
⸻
⚠️ callStatic 特别注意
• 要用写方法(state changing function)调用 callStatic,不能直接对 view / pure 调用。
• 如果交易必然会 revert,这里就会抛出错误。
• 可以用于测试 approve、mint、swap 之类复杂交易能否成功。
⸻
✅ 小结
功能 用法
ETH ↔ Wei parseEther, formatEther
任意小数 ↔ 整数 parseUnits, formatUnits
大整数操作 ethers.BigNumber
预演写交易(不发交易) contract.callStatic.xxx()
⸻