与合约交互
与合约交互
本页内容正在整理中,欢迎贡献。
概述
智能合约部署到链上后,你可以通过 JavaScript/TypeScript 库与其交互——读取状态、发送交易、监听事件。本文介绍两大主流库:viem(现代、类型安全)和 ethers.js(历史悠久、生态丰富)的基本用法。
主要内容
两大库对比
| 特性 | viem | ethers.js v6 |
|---|---|---|
| 类型安全 | 极强(基于 TypeScript) | 良好 |
| Bundle 大小 | 更小(Tree-shakeable) | 较大 |
| 性能 | 更高 | 标准 |
| 学习曲线 | 稍陡 | 平缓 |
| 生态兼容性 | wagmi 原生支持 | 广泛支持 |
| 推荐场景 | 新项目、React 应用 | 现有项目维护 |
使用 viem
安装
npm install viem读取合约状态(publicClient)
import { createPublicClient, http } from "viem";import { sepolia } from "viem/chains";
const client = createPublicClient({ chain: sepolia, transport: http("https://eth-sepolia.g.alchemy.com/v2/YOUR_KEY"),});
// ABI 片段(只需要用到的函数)const abi = [ { name: "getGreeting", type: "function", stateMutability: "view", inputs: [], outputs: [{ type: "string" }], },] as const;
const CONTRACT_ADDRESS = "0xYourContractAddress";
const greeting = await client.readContract({ address: CONTRACT_ADDRESS, abi, functionName: "getGreeting",});
console.log("问候语:", greeting);发送交易(walletClient)
import { createWalletClient, http } from "viem";import { privateKeyToAccount } from "viem/accounts";import { sepolia } from "viem/chains";
const account = privateKeyToAccount("0xYOUR_PRIVATE_KEY");
const walletClient = createWalletClient({ account, chain: sepolia, transport: http("https://eth-sepolia.g.alchemy.com/v2/YOUR_KEY"),});
const hash = await walletClient.writeContract({ address: CONTRACT_ADDRESS, abi, functionName: "setGreeting", args: ["你好,viem!"],});
console.log("交易 Hash:", hash);
// 等待确认const receipt = await client.waitForTransactionReceipt({ hash });console.log("已确认,区块:", receipt.blockNumber);使用 ethers.js v6
安装
npm install ethers读取合约状态
import { ethers } from "ethers";
const provider = new ethers.JsonRpcProvider( "https://eth-sepolia.g.alchemy.com/v2/YOUR_KEY");
const abi = ["function getGreeting() view returns (string)"];const contract = new ethers.Contract(CONTRACT_ADDRESS, abi, provider);
const greeting = await contract.getGreeting();console.log("问候语:", greeting);发送交易
const privateKey = process.env.PRIVATE_KEY!;const wallet = new ethers.Wallet(privateKey, provider);const contractWithSigner = contract.connect(wallet);
const tx = await contractWithSigner.setGreeting("你好,ethers.js!");console.log("交易 Hash:", tx.hash);
const receipt = await tx.wait();console.log("已确认,区块:", receipt.blockNumber);监听合约事件
// viemconst unwatch = client.watchContractEvent({ address: CONTRACT_ADDRESS, abi, eventName: "GreetingUpdated", onLogs: (logs) => { console.log("新事件:", logs); },});
// ethers.jscontract.on("GreetingUpdated", (newGreeting, event) => { console.log("问候语已更新:", newGreeting);});在浏览器中连接 MetaMask
// 使用 viem + window.ethereumimport { createWalletClient, custom } from "viem";import { sepolia } from "viem/chains";
const [account] = await window.ethereum.request({ method: "eth_requestAccounts",});
const walletClient = createWalletClient({ account, chain: sepolia, transport: custom(window.ethereum),});