WTF Ethers极简教程:深入理解合约信息读取
在区块链开发中,与智能合约交互是最核心的操作之一。本文将深入讲解如何使用ethers.js库读取链上合约信息,帮助开发者快速掌握这一关键技能。
合约交互基础
在区块链生态中,智能合约是存储在区块链上的可执行代码。要与这些合约交互,我们需要使用特定的工具和方法。ethers.js提供了一个强大的Contract
类,专门用于与部署在区块链网络上的合约进行交互。
Contract类的两种形态
ethers.js中的Contract
类分为两种类型:
- 只读Contract:只能执行合约中的
view
和pure
函数(即不改变链上状态的读取操作) - 可读写Contract:既能读取合约信息,也能发送交易修改合约状态
创建这两种Contract实例的方式略有不同:
// 只读Contract
const readOnlyContract = new ethers.Contract(address, abi, provider);
// 可读写Contract
const writableContract = new ethers.Contract(address, abi, signer);
实战:读取合约信息
准备工作
首先,我们需要设置一个Provider来连接区块链网络。这里我们使用Infura提供的节点服务:
import { ethers } from "ethers";
const INFURA_ID = '你的Infura API Key';
const provider = new ethers.JsonRpcProvider(`https://mainnet.infura.io/v3/${INFURA_ID}`);
创建合约实例
创建合约实例需要三个关键信息:合约地址、合约ABI和Provider。其中ABI(应用二进制接口)是与合约交互的桥梁,它定义了如何调用合约函数以及如何解析返回数据。
ethers.js提供了两种定义ABI的方式:
方法1:完整ABI
直接从合约编译结果或区块浏览器复制完整的ABI:
const abiWETH = [...]; // 完整的WETH合约ABI
const addressWETH = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2';
const contractWETH = new ethers.Contract(addressWETH, abiWETH, provider);
方法2:人类可读ABI(推荐)
ethers.js创新性地引入了人类可读的ABI格式,开发者只需声明需要使用的函数签名:
const abiERC20 = [
"function name() view returns (string)",
"function symbol() view returns (string)",
"function totalSupply() view returns (uint256)",
"function balanceOf(address) view returns (uint)",
];
const addressDAI = '0x6B175474E89094C44Da98b954EedeAC495271d0F';
const contractDAI = new ethers.Contract(addressDAI, abiERC20, provider);
这种方法更加简洁,可读性更强,特别适合只需要与合约部分功能交互的场景。
读取合约数据
创建合约实例后,我们可以轻松地调用合约的view和pure函数:
async function readContractData() {
// 读取WETH合约信息
const nameWETH = await contractWETH.name();
const symbolWETH = await contractWETH.symbol();
const totalSupplyWETH = await contractWETH.totalSupply();
console.log("WETH合约信息:");
console.log(`名称: ${nameWETH}`);
console.log(`代号: ${symbolWETH}`);
console.log(`总供应量: ${ethers.formatEther(totalSupplyWETH)} ETH`);
// 读取Vitalik的WETH余额
const vitalikBalance = await contractWETH.balanceOf('vitalik.eth');
console.log(`Vitalik的WETH持仓: ${ethers.formatEther(vitalikBalance)}`);
// 同样的方法可以读取DAI合约信息...
}
实用技巧与注意事项
- ABI处理:对于复杂合约,建议使用人类可读ABI,只包含需要交互的函数
- 错误处理:合约调用可能失败,务必添加try-catch块处理潜在错误
- 单位转换:区块链数值通常以wei为单位,使用
ethers.formatEther()
转换为更易读的ETH单位 - ENS支持:ethers.js内置支持ENS域名,如'vitalik.eth'会自动解析为地址
验证数据准确性
读取链上数据后,建议通过区块浏览器验证结果的准确性。例如,可以通过以下方式验证Vitalik的WETH余额:
- 在区块浏览器中查找WETH合约
- 使用合约的
balanceOf
方法查询Vitalik的地址 - 比较查询结果与程序输出是否一致
这种验证方式可以确保我们的代码正确无误地读取了链上数据。
总结
通过本文,我们系统地学习了如何使用ethers.js的Contract类与智能合约交互,重点掌握了:
- 创建只读和可读写Contract实例的方法
- 两种定义ABI的方式及其适用场景
- 调用合约view/pure函数读取链上数据
- 数据验证和错误处理的最佳实践
掌握这些基础知识后,开发者可以轻松构建与区块链智能合约交互的DApp前端,为用户提供丰富的区块链数据展示和交互功能。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考