Ethers.js 入门指南:快速上手区块链开发
前言
Ethers.js 是一个功能强大且轻量级的 JavaScript 库,专为区块链开发而设计。与同类库相比,它提供了更清晰的 API 设计和更完善的 TypeScript 支持。本文将带你快速了解 Ethers.js 的核心概念和基本用法。
安装与导入
安装 Ethers.js
使用 npm 可以轻松安装 Ethers.js:
npm install ethers
导入方式
Ethers.js 支持多种导入方式,可以根据项目需求选择:
Node.js 环境导入:
// 完整导入
import { ethers } from "ethers";
// 选择性导入
import { BrowserProvider, parseUnits } from "ethers";
// 从特定模块导入
import { HDNodeWallet } from "ethers/wallet";
浏览器环境导入:
<script type="module">
import { ethers } from "https://cdn.example.com/ajax/libs/ethers/6.7.0/ethers.min.js";
// 你的代码...
</script>
核心概念
1. Provider(提供者)
Provider 是区块链的只读连接,用于查询区块链状态、账户余额、交易详情等。它类似于 Web3.js 中的 Provider,但不包含写操作功能。
2. Signer(签名者)
Signer 封装了所有需要账户私钥的操作。私钥可能存储在内存中(使用 Wallet)或通过 MetaMask 等浏览器扩展保护。
3. Transaction(交易)
交易是改变区块链状态的唯一方式,需要支付 gas 费用。即使交易失败,也需要支付费用。
4. Contract(合约)
合约是部署在区块链上的程序,包含代码和可读写存储。连接到 Provider 时可读取状态,连接到 Signer 时可改变状态。
5. Receipt(收据)
交易被区块链包含后会生成收据,包含区块信息、实际支付的费用、使用的 gas 和事件日志等。
连接区块链
使用 MetaMask
let signer = null;
let provider;
if (window.ethereum == null) {
console.log("MetaMask 未安装,使用只读默认提供者");
provider = ethers.getDefaultProvider();
} else {
provider = new ethers.BrowserProvider(window.ethereum);
signer = await provider.getSigner();
}
自定义 RPC 后端
// 默认连接 http://localhost:8545
provider = new ethers.JsonRpcProvider(url);
signer = await provider.getSigner();
用户交互与单位转换
区块链使用大整数(如 wei)避免浮点精度问题。Ethers.js 提供了方便的转换函数:
// 将用户输入的以太转换为 wei
eth = parseEther("1.0");
// 将用户输入的 gwei 转换为 wei
feePerGas = parseUnits("4.5", "gwei");
// 将 wei 转换为以太字符串显示
formatEther(eth);
// 将 wei 转换为 gwei 字符串显示
formatUnits(feePerGas, "gwei");
与区块链交互
查询状态
// 获取当前区块高度
await provider.getBlockNumber();
// 查询账户余额
balance = await provider.getBalance("ethers.eth");
// 转换为易读格式
formatEther(balance);
// 获取交易计数
await provider.getTransactionCount("ethers.eth");
发送交易
tx = await signer.sendTransaction({
to: "ethers.eth",
value: parseEther("1.0")
});
// 等待交易确认
receipt = await tx.wait();
合约交互
ABI 简介
ABI(应用二进制接口)定义了如何与合约交互。Ethers.js 支持多种 ABI 格式:
abi = [
"function decimals() view returns (string)",
"function symbol() view returns (string)",
"function balanceOf(address addr) view returns (uint)"
];
只读方法
contract = new Contract("dai.tokens.ethers.eth", abi, provider);
// 获取代币符号
sym = await contract.symbol();
// 获取小数位数
decimals = await contract.decimals();
// 查询余额
balance = await contract.balanceOf("ethers.eth");
// 格式化显示
formatUnits(balance, decimals);
状态变更方法
contract = new Contract("dai.tokens.ethers.eth", abi, signer);
// 转账 1 DAI
amount = parseUnits("1.0", 18);
tx = await contract.transfer("ethers.eth", amount);
// 等待确认
await tx.wait();
监听事件
contract.on("Transfer", (from, to, _amount, event) => {
const amount = formatEther(_amount, 18);
console.log(`${from} => ${to}: ${amount}`);
event.removeListener(); // 可选:停止监听
});
查询历史事件
// 查询最近100个区块的转账事件
filter = contract.filters.Transfer;
events = await contract.queryFilter(filter, -100);
// 查询所有转账给ethers.eth的事件
filter = contract.filters.Transfer("ethers.eth");
events = await contract.queryFilter(filter);
消息签名
signer = new Wallet(id("test"));
message = "sign into ethers.org?";
// 签名消息
sig = await signer.signMessage(message);
// 验证签名
verifyMessage(message, sig); // 返回签名者地址
结语
本文介绍了 Ethers.js 的核心概念和基本用法,包括安装、连接区块链、单位转换、交易发送和合约交互等。Ethers.js 的设计注重清晰性和安全性,是开发区块链应用的优秀选择。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考