公共客户端
公共客户端是一个面向公众JSON-RPC API方法的接口,如检索区块高度,交易,从智能合约读取数据等等。访问Public Actions。
通过createPublicClient
函数来创建一个客户端,并赋予Transport来配置Chain。
导入
import { createPublicClient } from 'viem'
import { createPublicClient } from 'viem'
用例
使用您想要的Chain(例如mainnet
)和Transport(例如http
)初始化客户端。
import { createPublicClient, http } from 'viem'
import { mainnet } from 'viem/chains'
const client = createPublicClient({
chain: mainnet,
transport: http()
})
import { createPublicClient, http } from 'viem'
import { mainnet } from 'viem/chains'
const client = createPublicClient({
chain: mainnet,
transport: http()
})
然后开始使用公共操作:
const blockNumber = await client.getBlockNumber()
const blockNumber = await client.getBlockNumber()
优化
公共客户端还支持eth_call
聚合来提高性能。
eth_call
聚合 (通过 Multicall)
公共客户端支持将 eth_call
请求聚合为单个多调用 (aggregate3
) 请求。
这意味着对于任何使用 eth_call
请求的方法(如 readContract
),公共客户端会打包请求,然后通过单一multicall请求发送到RPC提供者。这就可以显著提高网络性能,并减少Alchemy、Infura 等 RPC 提供商使用的计算单元 (CU) 数量。
公共客户端会在一段时间内把eth_call请求聚合起来。通常在默认情况下,viem会在当前JavaScript消息队列的末尾执行这些批量请求,但是用户可以设置自定义等待事时间(以毫秒计)
你可以通过设置batch.multicall
字段为 true
来启用eth_call
:
const client = createPublicClient({
batch: {
multicall: true,
},
chain: mainnet,
transport: http(),
})
const client = createPublicClient({
batch: {
multicall: true,
},
chain: mainnet,
transport: http(),
})
也可以自定义
multicall
选项。
现在,当你使用readContract
方法,公共客户端会打包,然后公共客户端将在消息队列末尾(或自定义时间段)在单个“eth_call”多调用请求中批量发送这些请求:
const contract = getContract({ address, abi })
// 下面的示例将只会向 RPC 提供者发送单个请求。
const [name, totalSupply, symbol, tokenUri, balance] = await Promise.all([
contract.read.name(),
contract.read.totalSupply(),
contract.read.symbol(),
contract.read.tokenURI([420n]),
contract.read.balanceOf([address]),
])
const contract = getContract({ address, abi })
// 下面的示例将只会向 RPC 提供者发送单个请求。
const [name, totalSupply, symbol, tokenUri, balance] = await Promise.all([
contract.read.name(),
contract.read.totalSupply(),
contract.read.symbol(),
contract.read.tokenURI([420n]),
contract.read.balanceOf([address]),
])
阅读更多合约实例.
参数
transport
- Type: Transport
公共客户端的中的Transport。
const client = createPublicClient({
chain: mainnet,
transport: http(),
})
const client = createPublicClient({
chain: mainnet,
transport: http(),
})
chain(可选的)
- Type: Chain
公共客户端的中的Chain。
const client = createPublicClient({
chain: mainnet,
transport: http(),
})
const client = createPublicClient({
chain: mainnet,
transport: http(),
})
batch(可选的)
用于批处理设置的标识
batch.multicall(可选的)
- Type:
boolean | MulticallBatchOptions
- Default:
false
切换来启用eth_call
多次调用聚合.
const client = createPublicClient({
batch: {
multicall: true,
},
chain: mainnet,
transport: http(),
})
const client = createPublicClient({
batch: {
multicall: true,
},
chain: mainnet,
transport: http(),
})
batch.multicall.batchSize(可选的)
- Type:
number
- Default:
1_024
每个多次调用的调用数据块的最大值(使用bytes计算)。
注意:有一些RPC Providers限制单个请求中可以被发送的数据大小,最好是检查一下RPC Provider,你的
eth_call
请求中是否有calldata
大小限制
const client = createPublicClient({
batch: {
multicall: {
batchSize: 512,
},
},
chain: mainnet,
transport: http(),
})
const client = createPublicClient({
batch: {
multicall: {
batchSize: 512,
},
},
chain: mainnet,
transport: http(),
})
batch.multicall.wait(可选的)
- Type:
number
- Default:
0
(zero delay)
发送批处理请求之前等待的最大毫秒数。
const client = createPublicClient({
batch: {
multicall: {
wait: 16,
},
},
chain: mainnet,
transport: http(),
})
const client = createPublicClient({
batch: {
multicall: {
wait: 16,
},
},
chain: mainnet,
transport: http(),
})
cacheTime(可选的)
- Type:
number
- Default:
client.pollingInterval
缓存数据在内存中保留的时间(以毫秒为单位)。
const client = createPublicClient({
cacheTime: 10_000,
chain: mainnet,
transport: http(),
})
const client = createPublicClient({
cacheTime: 10_000,
chain: mainnet,
transport: http(),
})
key(可选的)
- Type:
string
- Default:
"public"
客户端中的key。
const client = createPublicClient({
chain: mainnet,
key: 'public',
transport: http(),
})
const client = createPublicClient({
chain: mainnet,
key: 'public',
transport: http(),
})
name(可选的)
- Type:
string
- Default:
"Public Client"
客户端的名字。
const client = createPublicClient({
chain: mainnet,
name: 'Public Client',
transport: http(),
})
const client = createPublicClient({
chain: mainnet,
name: 'Public Client',
transport: http(),
})
pollingInterval(可选的)
- Type:
number
- Default:
4_000
轮询启用的操作的间隔时间(毫秒)
const client = createPublicClient({
chain: mainnet,
pollingInterval: 10_000,
transport: http(),
})
const client = createPublicClient({
chain: mainnet,
pollingInterval: 10_000,
transport: http(),
})
例子
在下面的公共客户端示例 查看createPublicClient
的用例: