进阶 docs.web3js.org 2026-10-19 02:32:30 · 10 阅读

第22章 从 Web3.js 迁移到 Viem

从 Web3.js 迁移到 Viem 本指南将帮助你从 Web3.js v4 迁移到 Viem v2,以便与 Ethereum 区块链交互。指南中会同时提供两个库的代码示例,方便你完成过渡。 安装 开始迁移前,先安装 Viem 包: npm install viem@2 Provider 从 Web3.js 迁移到 Viem 时,第一步是更新连接 Ethereum 网络的方式。两个库都使用 provider,但初始化方式有所不同。 import Web3 from 'web3'; const web3 = new Web3(providerURL); 迁移到 Viem 时,需要改用 createPublicClient()。这个函数会创建一个用于与 Ethereum 网络交互的客户端。 import { createPublicClient, http } from 'viem'; const client = createPublicClient({ transport: http(providerURL) }); 浏览器注入的 Provider 对于 MetaMask 这类浏览器钱包的连接,需要更新处理注入 provider 的方式。 const web3 = new Web3(window.ethereum); 迁移到 Viem 时,不需要再创建新的 Web3 实例,而是使用 createWalletClient() 配合 custom()。 import { createWalletClient, custom } from 'viem'; import { mainnet } from 'viem/chains'; const client = createWalletClient({ chain: mainnet, transport: custom(window.ethereum), }); 钱包与账户 - 生成私钥 如果你的代码会生成私钥,迁移方式如下。在 web3.js 中你可能这样写: const privateKey = web3.eth.accounts.create().privateKey; console.log(privateKey); 迁移到 Viem 时,使用 'viem/accounts' 模块中的 generatePrivateKey() 函数。 import { generatePrivateKey } from 'viem/accounts'; const privateKey = generatePrivateKey(); console.log(privateKey); 钱包与账户 - 创建钱包 从 Web3.js 迁移到 Viem 时,创建和管理钱包的方式也需要更新。两个库向钱包添加账户的流程并不相同。在 web3.js 中: const web3 = new Web3(); const wallet = web3.eth.accounts.wallet.add(privateKey); console.log(wallet[0].address); 迁移到 Viem 时,先用 privateKeyToAccount() 创建账户,再将其传入 createWalletClient(),就可以配合客户端使用了。 import { createWalletClient, http } from 'viem'; import { privateKeyToAccount } from 'viem/accounts'; import { mainnet } from 'viem/chains'; const account = privateKeyToAccount(privateKey);

const client = createWalletClient({
account,
chain: mainnet,
transport: http(),
});
消息签名 更新消息签名的处理方式,以下是 web3.js 的示例: const signature = web3.eth.accounts.sign('Some data', privateKey).signature;
console.log(signature);
使用 Viem 进行消息签名时,可以调用 signMessage() 方法。 import { createWalletClient, custom } from 'viem'
import { mainnet } from 'viem/chains'

const walletClient = createWalletClient({
chain: mainnet,
transport: custom(window.ethereum!),
});

const [account] = await walletClient.getAddresses();

const signature = await walletClient.signMessage({
account,
message: 'Some data',
});

交易 迁移交易发送代码时,需要更新交易的签名和发送方式。 const tx = await web3.eth.sendTransaction({
from: account,
to: '0x92d3267215Ec56542b985473E73C8417403B15ac',
value: web3.utils.toWei('0.001', 'ether'),
});
Viem 提供了 sendTransaction() 函数,可通过 walletClient 使用。 import { createWalletClient, custom, parseEther } from 'viem'
import { mainnet } from 'viem/chains'

const walletClient = createWalletClient({
chain: mainnet,
transport: custom(window.ethereum!),
});

const [account] = await walletClient.getAddresses();

const hash = await walletClient.sendTransaction({
account,
to: '0x92d3267215Ec56542b985473E73C8417403B15ac',
value: parseEther('0.001')
});

合约 部署合约 迁移合约部署代码时,需要更新 Web3.js 的部署和发送模式: // use existing web3 instance connected with provider
const contract = new web3.eth.Contract(abi);
const deployTx = await contract
.deploy({
data: bytecode,
arguments: ['constructor param'],
})
.send({
from: account,
gas: '1000000',
});
console.log(deployTx.options.address);
Viem 提供了 deployContract() 函数用于部署合约。 //import { deployContract } from 'viem'
import { createWalletClient, custom } from 'viem';
import { mainnet } from 'viem/chains';

const walletClient = createWalletClient({
chain: mainnet,
transport: custom(window.ethereum),
});

const hash = await walletClient.deployContract({
abi,

account, //给定的账户
args: ['构造器参数'],
bytecode: bytecode,
});

合约方法调用​

迁移合约方法调用时,需要将 Web3.js 的 contract.methods.someFunction().call() 更新为: const contract = new web3.eth.Contract(ABI, CONTRACT_ADDRESS);
const result = await contract.methods.someFunction().call();
console.log(result);

在 Viem 中,可以使用 readContract() 函数进行方法调用。 const data = await publicClient.readContract({
address: '0x92d3267215Ec56542b985473E73C8417403B15ac',
abi: wagmiAbi,
functionName: 'tokenTotalSupply',
});

合约事件​

迁移事件处理代码时,需要将 Web3.js 的事件代码更新为: const event = contract.events.SomeEvent({ fromBlock: 0 });
event.on('data', resolve);
event.on('error', reject);

在 Viem 中,可以使用 watchContractEvent() 函数。 const unwatch = publicClient.watchContractEvent({
address: '0x92d3267215Ec56542b985473E73C8417403B15ac',
abi: wagmiAbi,
eventName: 'Transfer',
args: { from: '0x34d3267215Ec56542b985473E73C8417403B1533' },
onLogs: logs => func(logs),
});

工具方法​

哈希计算​

迁移计算 Keccak-256 哈希值的代码时,需要将 Web3.js 的工具方法更新为: // keccak256 方法在 web3.js 中支持更广泛的输入类型
const hash = web3.utils.keccak256('hello world');

在 Viem 中,可以使用 keccak256() 函数计算 keccak256。 import { keccak256 , toHex } from 'viem'

keccak256(toHex('hello world'));

评论 (0)