跳转到内容

与合约交互

与合约交互

本页内容正在整理中,欢迎贡献

概述

智能合约部署到链上后,你可以通过 JavaScript/TypeScript 库与其交互——读取状态、发送交易、监听事件。本文介绍两大主流库:viem(现代、类型安全)和 ethers.js(历史悠久、生态丰富)的基本用法。

主要内容

两大库对比

特性viemethers.js v6
类型安全极强(基于 TypeScript)良好
Bundle 大小更小(Tree-shakeable)较大
性能更高标准
学习曲线稍陡平缓
生态兼容性wagmi 原生支持广泛支持
推荐场景新项目、React 应用现有项目维护

使用 viem

安装

Terminal window
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

安装

Terminal window
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);

监听合约事件

// viem
const unwatch = client.watchContractEvent({
address: CONTRACT_ADDRESS,
abi,
eventName: "GreetingUpdated",
onLogs: (logs) => {
console.log("新事件:", logs);
},
});
// ethers.js
contract.on("GreetingUpdated", (newGreeting, event) => {
console.log("问候语已更新:", newGreeting);
});

在浏览器中连接 MetaMask

// 使用 viem + window.ethereum
import { 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),
});

下一步