尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

wagmi React Hook useProof 完全指南:获取账户与存储槽位的 Merkle 证明

wagmi React Hook useProof 完全指南:获取账户与存储槽位的 Merkle 证明 wagmi React Hook useProof 完全指南获取账户与存储槽位的 Merkle 证明【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmiuseProof是 wagmi 提供的 React Hook用于获取指定账户的账户值与存储值包括对应 Merkle 证明其底层调用的是以太坊 JSON-RPC 的eth_getProof方法。本文将从基本用法、全部参数、TanStack Query 选项、返回值到源码实现逐层展开帮助你快速掌握在 React 应用中使用该 Hook 获取链上状态证明的完整方案。useProof 是什么useProof的官方定义为Hook for return the account and storage values of the specified account including the Merkle-proof即返回指定账户的账户值与存储值并附带用于验证这些值的 Merkle 证明。这在实践中常用于跨链桥、状态验证、轻客户端等场景——当你需要向外部系统证明某个地址在某条链上的余额/存储值为 X时useProof返回的accountProof与storageProof就是可被第三方独立验证的密码学证据。从 wagmi 的架构看它属于 core actions 中的getProof的 React 封装通过 TanStack Query 提供声明式的数据获取、缓存与状态管理能力。引入 Hookimport { useProof } from wagmi同时需要确认你的应用已经配置好WagmiProviderHook 默认会从最近的 Provider 上下文中读取config。基本用法最典型的调用方式是传入账户地址address与需要取证的存储键数组storageKeysimport { useProof } from wagmi function App() { const result useProof({ address: 0x4200000000000000000000000000000000000016, storageKeys: [ 0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99, ], }) }其中config的典型创建方式如下配置了主网与 Sepolia 测试网的 HTTP 传输import { createConfig, http } from wagmi import { mainnet, sepolia } from wagmi/chains export const config createConfig({ chains: [mainnet, sepolia], transports: { [mainnet.id]: http(), [sepolia.id]: http(), }, })参数详解useProof的参数类型为UseProofParameters可以从wagmi导入import { type UseProofParameters } from wagmiaddressAddress | undefined要获取证明的账户地址。该参数是查询能否执行的必要条件之一详见下文enabled逻辑。import { useProof } from wagmi function App() { const result useProof({ address: 0x4200000000000000000000000000000000000016, // [!code focus] storageKeys: [ 0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99, ], }) }storageKeys0x${string}[] | undefined需要取证并包含在返回结果中的存储键storage-keys数组。每个存储键对应账户存储 trie 中的一个槽位将作为storageProof逐项返回。import { useProof } from wagmi function App() { const result useProof({ address: 0x4200000000000000000000000000000000000016, storageKeys: [ // [!code focus:3] 0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99, ], }) }blockNumberbigint | undefined指定在某个区块高度上取证。当链上状态已经改变时通过固定区块高度可以保证证明的一致性。import { useProof } from wagmi function App() { const result useProof({ address: 0x4200000000000000000000000000000000000016, blockNumber: 42069n, // [!code focus] storageKeys: [ 0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99, ], }) }blockTaglatest | earliest | pending | safe | finalized | undefined指定在某个区块标签上取证。默认为latest最新已打包区块safe与finalized由支持相应概念的链如以太坊 PoS提供更适合对安全性要求较高的场景。import { useProof } from wagmi function App() { const result useProof({ address: 0x4200000000000000000000000000000000000016, blockTag: latest, // [!code focus] storageKeys: [ 0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99, ], }) }chainIdconfig[chains][number][id] | undefined指定对哪条链取证。默认使用当前激活链来自最近一次连接/切换的链也可显式指定例如针对 Optimismimport { useProof } from wagmi import { optimism } from wagmi/chains function App() { const result useProof({ chainId: optimism.id, // [!code focus] address: 0x4200000000000000000000000000000000000016, storageKeys: [ 0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99, ], }) }configConfig | undefined显式指定要使用的 Config即createConfig的返回值替代从最近的 WagmiProvider 中自动获取。适用于多配置实例或脱离 Provider 的场景。import { useProof } from wagmi import { config } from ./config // [!code focus] function App() { const result useProof({ config, // [!code focus] address: 0x4200000000000000000000000000000000000016, storageKeys: [ 0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99, ], }) }scopeKeystring | undefined将缓存限定到指定上下文。具有相同上下文即相同scopeKey及相同查询键的 Hook 会共享同一份缓存适合在需要隔离或复用缓存数据的场景中使用。import { useProof } from wagmi import { config } from ./config function App() { const result useProof({ scopeKey: foo // [!code focus] address: 0x4200000000000000000000000000000000000016, storageKeys: [ 0x4a932049252365b3eedbc5190e18949f2ec11f39d3bef2d259764799a1b27d99, ], }) }TanStack Query 选项queryuseProof基于 TanStack Query 实现因此支持大部分查询配置项。需要注意的是queryFn与queryKey由 wagmi 内部使用不允许覆盖其余选项均可用主要包括enabledboolean | undefined。设为false可禁用查询自动执行常用于依赖查询Dependent Queries。gcTimenumber | Infinity | undefined。默认5 * 60 * 10005 分钟SSR 期间为Infinity非活跃缓存数据在内存中的保留时间。initialDataTData | (() TData) | undefined。查询创建前的初始数据会持久化到缓存默认视为过期。initialDataUpdatedAtnumber | (() number | undefined) | undefined。initialData自身的最后更新时间。metaRecordstring, unknown | undefined。附加到查询缓存条目的额外信息。networkModeonline | always | offlineFirst | undefined。默认online。notifyOnChangePropsstring[] | all | (() string[] | all) | undefined。控制组件仅在指定属性变化时重新渲染。placeholderDataTData | ((previousValue, previousQuery) TData) | undefined。查询处于pending状态时展示的占位数据不持久化到缓存。queryClientQueryClient | undefined。自定义QueryClient否则使用最近上下文中的实例。refetchIntervalnumber | false | ((data, query) ...) | undefined。轮询刷新频率毫秒。refetchIntervalInBackgroundboolean | undefined。后台标签页是否继续轮询。refetchOnMountboolean | always | ((query) ...) | undefined。默认true。refetchOnReconnectboolean | always | ((query) ...) | undefined。默认true。refetchOnWindowFocusboolean | always | ((query) ...) | undefined。默认true。retryboolean | number | ((failureCount, error) boolean) | undefined。默认客户端3次、服务端0次。retryDelaynumber | ((retryAttempt, error) number) | undefined。重试间隔可配合指数退避算法。retryOnMountboolean | undefined。默认true。select((data: TData) unknown) | undefined。对返回数据做转换/选择不影响缓存内容。staleTimenumber | Infinity | undefined。默认0数据被视为过期的时间。structuralSharingboolean | ((oldData, newData) TData) | undefined。默认true控制查询结果间的结构共享。返回值详解useProof的返回类型为UseProofReturnTypeimport { type UseProofReturnType } from wagmi其核心返回值如下dataTData。最近一次成功解析的查询数据即getProof的返回值详见下文Action小节默认为undefined。dataUpdatedAtnumber。最近一次查询状态变为success的时间戳。errornull | TError。查询抛出的错误对象默认为null。errorUpdatedAt / errorUpdateCount错误时间戳与错误累计次数。failureCount / failureReason失败次数与失败原因成功时重置为0/null。fetchStatusfetching | idle | paused。表示查询函数的执行状态。isError / isPending / isSuccess由status派生的布尔变量。isFetched / isFetchedAfterMount是否已获取过数据后者仅在组件挂载后获取才为true可用于隐藏旧缓存数据。isFetching / isPaused / isLoading / isLoadingError / isRefetchError / isRefetching / isStale / isPlaceholderData各类查询状态的派生布尔量。refetch(options: { cancelRefetch?, throwOnError? }) Promise...。手动重新获取数据throwOnError控制失败时是否抛错cancelRefetch控制是否取消进行中的请求默认true。statuserror | pending | success。查询的总体状态。与 TanStack Query 的集成useProof基于 TanStack Query因此你还可以从wagmi/query导入与getProof相关的类型与工具函数实现选项复用、手动控制查询等高级用法import { type GetProofData, type GetProofOptions, type GetProofQueryFnData, type GetProofQueryKey, getProofQueryKey, getProofQueryOptions, } from wagmi/queryGetProofData查询数据类型等价于getProof的返回类型GetProofQueryFnData查询函数数据类型GetProofQueryKey/getProofQueryKey查询键类型与生成函数键的形态为[getProof, { address, storageKeys, chainId, ... }]GetProofOptions/getProofQueryOptions选项类型与选项构造器可配合useQuery在非 Hook 场景下使用相同的查询配置。底层 ActiongetProofuseProof是 core actiongetProof的 React 封装。在 packages/core/src/actions/getProof.ts 中getProof接收config与参数解析chainId后通过config.getClient({ chainId })获取对应链的 viem 客户端再委托 viem 的getProofaction 发起eth_getProofRPC 请求export async function getProofconfig extends Config( config: config, parameters: GetProofParametersconfig, ): PromiseGetProofReturnType { const { chainId, ...rest } parameters const client config.getClient({ chainId }) const action getAction(client, viem_getProof, getProof) return action(rest) }其返回类型GetProofReturnType即 viem 的证明结果典型结构包含address被取证账户accountProof账户状态的 Merkle 证明路径balance/nonce/codeHash/storageHash账户的余额、随机数、代码哈希与存储根storageProof存储槽位证明数组每项包含key、value与对应的proof路径。在 packages/core/src/query/getProof.ts 中getProofQueryOptions设置了该查询的关键行为enabled: Boolean( options.address options.storageKeys (options.query?.enabled ?? true), ), queryFn: async (context) { const [, { scopeKey: _, ...parameters }] context.queryKey if (!parameters.address || !parameters.storageKeys) throw new Error(address and storageKeys are required) return getProof(config, { ...parameters, address: parameters.address, storageKeys: parameters.storageKeys }) }, queryKey: getProofQueryKey(options),可以看出两点重要实现细节当address或storageKeys缺失时查询自动禁用enabled: false不会发起任何 RPC 请求而查询键[getProof, { address, storageKeys, chainId, ... }]决定了相同参数下缓存自动复用。Hook 内部实现原理在 packages/react/src/hooks/useProof.ts 中Hook 的实现非常简洁只有四步export function useProof config extends Config ResolvedRegister[config], selectData GetProofData, ( parameters: UseProofParametersconfig, selectData {}, ): UseProofReturnTypeselectData { const config useConfig(parameters) const chainId useChainId({ config }) const options getProofQueryOptions(config, { ...parameters, chainId: parameters.chainId ?? chainId, }) return useQuery(options) }useConfig(parameters)从最近的WagmiProvider上下文或显式config参数获取配置useChainId({ config })获取当前激活链 IDgetProofQueryOptions(...)合并参数未显式指定chainId时回退到当前链 ID构造查询选项useQuery(options)交给 TanStack Query 执行并返回带状态的结果对象。对应的单元测试见 packages/react/src/hooks/useProof.test.ts其中通过自定义 transport 模拟了eth_getProof的返回结果并验证了三个关键行为默认查询传入address与storageKeys后查询成功返回证明数据查询键为[getProof, { address, chainId: 1, storageKeys }]address 由 undefined 变为已定义初始状态下查询保持pending、不发起请求一旦address补齐查询自动执行并成功参数缺失时自动禁用useProof()不带任何参数时查询保持pending且不发起任何请求。这些测试从行为层面印证了上文提到的enabled判定逻辑——这也是useProof在钱包未连接、地址未知场景下依然安全可用的原因。小结useProof将繁琐的eth_getProof调用封装为声明式的 React Hook通过address、storageKeys两个必填参数缺失时自动禁用查询加blockNumber/blockTag/chainId等可选参数精确控制取证范围并借助 TanStack Query 获得缓存、重试、轮询与状态派生能力。无论是构建需要链上状态证明的跨链协议、验证服务还是需要读取账户存储的复杂 DApp它都是 wagmi 中获取 Merkle 证明的首选入口。【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表