Ethers.js基础
核心知识点讲解
Ethers.js简介
Ethers.js是一个轻量级的JavaScript库,用于与以太坊网络进行交互:
- 轻量级:比Web3.js更小,加载更快
- 易于使用:API设计更加简洁直观
- 功能完整:支持所有以太坊交互功能
- 钱包集成:内置钱包功能
- 类型安全:TypeScript支持良好
Ethers.js安装与配置
安装方式
# 使用npm安装
npm install ethers
# 使用yarn安装
yarn add ethers基本配置
// 引入Ethers.js
const { ethers } = require('ethers');
// 创建Provider
// 连接到本地节点
const provider = new ethers.JsonRpcProvider('http://localhost:8545');
// 连接到Infura节点
const provider = new ethers.JsonRpcProvider('https://mainnet.infura.io/v3/YOUR_INFURA_API_KEY');
// 连接到MetaMask
if (window.ethereum) {
const provider = new ethers.BrowserProvider(window.ethereum);
// 请求用户授权
const signer = await provider.getSigner();
}Ethers.js核心功能
1. Provider
- 连接网络:连接到以太坊网络
- 查询数据:查询区块、交易和账户信息
- 估算Gas:估算交易Gas消耗
- 获取网络信息:获取网络ID、链ID等信息
2. Signer
- 管理账户:管理以太坊账户
- 签名交易:签名并发送交易
- 签名消息:签名消息进行身份验证
- 获取账户信息:获取账户地址、余额等
3. Contract
- 部署合约:部署智能合约
- 调用方法:调用合约的读取方法
- 发送交易:调用合约的写入方法
- 监听事件:监听合约事件
实用案例分析
连接以太坊网络
// 连接到以太坊网络
const { ethers } = require('ethers');
// 连接到本地Ganache节点
const provider = new ethers.JsonRpcProvider('http://localhost:8545');
// 连接到Infura的Sepolia测试网
const provider = new ethers.JsonRpcProvider('https://sepolia.infura.io/v3/YOUR_INFURA_API_KEY');
// 检查连接状态
async function checkConnection() {
try {
const network = await provider.getNetwork();
console.log('Connected to network:', network.name, '(ID:', network.chainId, ')');
const blockNumber = await provider.getBlockNumber();
console.log('Current block number:', blockNumber);
return true;
} catch (error) {
console.error('Connection error:', error);
return false;
}
}
checkConnection();钱包管理
// 钱包管理
const { ethers } = require('ethers');
const provider = new ethers.JsonRpcProvider('http://localhost:8545');
// 创建钱包
function createWallet() {
const wallet = ethers.Wallet.createRandom();
console.log('New wallet address:', wallet.address);
console.log('Private key:', wallet.privateKey);
console.log('Mnemonic:', wallet.mnemonic.phrase);
return wallet;
}
// 从私钥创建钱包
function createWalletFromPrivateKey(privateKey) {
const wallet = new ethers.Wallet(privateKey, provider);
console.log('Wallet address:', wallet.address);
return wallet;
}
// 从助记词创建钱包
function createWalletFromMnemonic(mnemonic) {
const wallet = ethers.Wallet.fromPhrase(mnemonic, provider);
console.log('Wallet address:', wallet.address);
return wallet;
}
// 获取钱包余额
async function getWalletBalance(wallet) {
try {
const balance = await wallet.getBalance();
const balanceInEther = ethers.formatEther(balance);
console.log('Wallet balance:', balanceInEther, 'ETH');
return balanceInEther;
} catch (error) {
console.error('Error getting balance:', error);
return '0';
}
}
// 示例用法
async function main() {
const wallet = createWallet();
await getWalletBalance(wallet);
// 从私钥创建钱包
// const privateKey = '0x1234567890123456789012345678901234567890123456789012345678901234';
// const walletFromPrivateKey = createWalletFromPrivateKey(privateKey);
// await getWalletBalance(walletFromPrivateKey);
}
main();智能合约交互
// 智能合约交互
const { ethers } = require('ethers');
const provider = new ethers.JsonRpcProvider('http://localhost:8545');
// 合约ABI
const contractABI = [
{
"inputs": [{"internalType": "uint256", "name": "_value", "type": "uint256"}],
"name": "setValue",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "getValue",
"outputs": [{"internalType": "uint256", "name": "", "type": "uint256"}],
"stateMutability": "view",
"type": "function"
},
{
"anonymous": false,
"inputs": [{"indexed": false, "internalType": "uint256", "name": "value", "type": "uint256"}],
"name": "ValueChanged",
"type": "event"
}
];
// 合约地址
const contractAddress = '0x1234567890123456789012345678901234567890';
// 获取签名者
async function getSigner() {
// 从私钥创建签名者
const privateKey = '0x1234567890123456789012345678901234567890123456789012345678901234';
const signer = new ethers.Wallet(privateKey, provider);
return signer;
}
// 创建合约实例
async function createContract() {
const signer = await getSigner();
const contract = new ethers.Contract(contractAddress, contractABI, signer);
return contract;
}
// 调用合约方法(读取)
async function getContractValue() {
const contract = await createContract();
try {
const value = await contract.getValue();
console.log('Contract value:', value.toString());
return value;
} catch (error) {
console.error('Error getting contract value:', error);
return 0;
}
}
// 发送交易(写入)
async function setContractValue(value) {
const contract = await createContract();
try {
const tx = await contract.setValue(value);
await tx.wait();
console.log('Transaction hash:', tx.hash);
return tx;
} catch (error) {
console.error('Error setting contract value:', error);
return null;
}
}
// 监听事件
async function listenToEvents() {
const contract = await createContract();
contract.on('ValueChanged', (value) => {
console.log('Event received:', value.toString());
});
console.log('Listening for events...');
}
// 示例用法
async function main() {
await getContractValue();
await setContractValue(42);
await getContractValue();
await listenToEvents();
}
main();交易操作
// 交易操作
const { ethers } = require('ethers');
const provider = new ethers.JsonRpcProvider('http://localhost:8545');
// 获取签名者
async function getSigner() {
// 从私钥创建签名者
const privateKey = '0x1234567890123456789012345678901234567890123456789012345678901234';
const signer = new ethers.Wallet(privateKey, provider);
return signer;
}
// 发送ETH
async function sendEther(to, amount) {
const signer = await getSigner();
try {
const tx = await signer.sendTransaction({
to: to,
value: ethers.parseEther(amount)
});
await tx.wait();
console.log('Transaction hash:', tx.hash);
return tx;
} catch (error) {
console.error('Error sending ether:', error);
return null;
}
}
// 估算Gas
async function estimateGas(to, amount) {
try {
const gas = await provider.estimateGas({
to: to,
value: ethers.parseEther(amount)
});
console.log('Estimated gas:', gas.toString());
return gas;
} catch (error) {
console.error('Error estimating gas:', error);
return 21000; // 默认值
}
}
// 获取Gas价格
async function getGasPrice() {
try {
const gasPrice = await provider.getGasPrice();
const gasPriceInGwei = ethers.formatUnits(gasPrice, 'gwei');
console.log('Gas price:', gasPriceInGwei, 'Gwei');
return gasPriceInGwei;
} catch (error) {
console.error('Error getting gas price:', error);
return '0';
}
}
// 示例用法
async function main() {
const signer = await getSigner();
const to = '0x9876543210987654321098765432109876543210';
const amount = '0.01';
await getGasPrice();
await estimateGas(to, amount);
await sendEther(to, amount);
// 检查余额
const balance = await signer.getBalance();
console.log('Balance:', ethers.formatEther(balance), 'ETH');
}
main();区块链查询
// 区块链查询
const { ethers } = require('ethers');
const provider = new ethers.JsonRpcProvider('http://localhost:8545');
// 获取区块信息
async function getBlock(blockNumber) {
try {
const block = await provider.getBlock(blockNumber);
console.log('Block:', block);
return block;
} catch (error) {
console.error('Error getting block:', error);
return null;
}
}
// 获取交易信息
async function getTransaction(txHash) {
try {
const tx = await provider.getTransaction(txHash);
console.log('Transaction:', tx);
return tx;
} catch (error) {
console.error('Error getting transaction:', error);
return null;
}
}
// 获取交易收据
async function getTransactionReceipt(txHash) {
try {
const receipt = await provider.getTransactionReceipt(txHash);
console.log('Transaction receipt:', receipt);
return receipt;
} catch (error) {
console.error('Error getting transaction receipt:', error);
return null;
}
}
// 获取链上信息
async function getChainInfo() {
try {
const network = await provider.getNetwork();
const blockNumber = await provider.getBlockNumber();
console.log('Network name:', network.name);
console.log('Chain ID:', network.chainId);
console.log('Current block:', blockNumber);
return {
name: network.name,
chainId: network.chainId,
blockNumber: blockNumber
};
} catch (error) {
console.error('Error getting chain info:', error);
return null;
}
}
// 示例用法
async function main() {
await getChainInfo();
const latestBlock = await provider.getBlockNumber();
await getBlock(latestBlock);
// 假设我们有一个交易哈希
// const txHash = '0x1234567890123456789012345678901234567890123456789012345678901234';
// await getTransaction(txHash);
// await getTransactionReceipt(txHash);
}
main();实践练习
连接以太坊网络:
- 安装Ethers.js库
- 连接到本地Ganache节点
- 连接到Infura的测试网络
- 检查连接状态和网络信息
钱包管理:
- 创建新钱包
- 从私钥和助记词恢复钱包
- 检查钱包余额
- 发送ETH到另一个账户
智能合约交互:
- 部署一个简单的智能合约
- 调用合约的读取方法
- 调用合约的写入方法
- 监听合约事件
交易操作:
- 估算交易Gas
- 获取当前Gas价格
- 发送交易并获取交易收据
- 验证交易是否成功
区块链查询:
- 获取最新区块信息
- 查询指定交易的详细信息
- 分析区块中的交易
- 监控网络状态
总结
Ethers.js是一个现代化的以太坊JavaScript库,它提供了与以太坊网络交互的完整功能,同时具有轻量级、易于使用的特点。通过Ethers.js,开发者可以:
- 连接到以太坊网络:无论是主网、测试网还是本地网络
- 管理钱包:创建钱包、签名交易、检查余额
- 与智能合约交互:部署合约、调用方法、监听事件
- 查询区块链数据:获取区块、交易和网络信息
Ethers.js的API设计更加简洁直观,类型安全支持良好,是构建Web3前端应用的理想选择。它与Web3.js相比,具有更小的体积和更现代的API设计,越来越受到开发者的青睐。
通过本集的学习,你应该能够理解Ethers.js的基本使用方法和核心功能,为开发Web3前端应用打下基础。