值的完整指南)
wagmi React 之 useStorageAt读取指定地址存储槽Storage Slot值的完整指南【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmiuseStorageAt是 wagmi 提供的 React Hook用于读取指定合约地址在特定存储槽storage slot位置的值返回值是一个 32 字节的十六进制字符串。本指南以该 Hook 的官方 API 文档为核心结合本仓库中wagmi/core的底层实现与测试用例系统讲解useStorageAt的导入方式、全部参数、返回值结构、TanStack Query 集成方式及其背后的执行链路帮助你在 React 应用中直接、可靠地读取链上原始存储数据。ImportuseStorageAt从wagmi包导出需要在use client环境下使用服务端组件中不可直接调用import { useStorageAt } from wagmi从源码结构看Hook 位于 packages/react/src/hooks/useStorageAt.ts其文件首行为use client说明它是为客户端 React 环境设计的交互式 Hook。Usage最基础的用法只需提供address合约地址与slot存储槽位import { useStorageAt } from wagmi function App() { const result useStorageAt({ address: 0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2, slot: 0x0, }) }该示例对应的最小运行环境配置见 site/snippets/react/config.ts其中使用createConfig创建了包含mainnet与sepolia两条链的配置并通过http()提供默认 RPC 传输层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(), }, })在真实应用中你还需要在组件树顶层挂载WagmiProvider参考 site/react/api/WagmiProvider.md使 Hook 能自动获取 Config。ParametersuseStorageAt的参数类型为UseStorageAtParametersimport { type UseStorageAtParameters } from wagmi从 packages/react/src/hooks/useStorageAt.ts 可以看出该类型是GetStorageAtOptionsconfig, selectData ConfigParameterconfig的组合既包含链上查询参数也包含 TanStack Query 参数与显式config参数。以下逐一说明。addressAddress | undefined要读取存储的合约地址。注意在 Hook 层该参数是可选的未提供时查询不会执行而在底层getStorageAtAction 中它是必填项。import { useStorageAt } from wagmi function App() { const result useStorageAt({ address: 0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2, // [!code focus] slot: 0x0, }) }slotHex | undefined要读取的存储位置必须是以十六进制编码的值如0x0、0x1等。它对应 EVM 世界状态中keccak256布局下的存储槽序号。import { useStorageAt } from wagmi function App() { const result useStorageAt({ address: 0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2, slot: 0x0, // [!code focus] }) }blockNumberbigint | undefined指定从某个区块高度读取存储。这对“历史状态查询”非常有用例如在某一笔交易发生前的区块检查存储值import { useStorageAt } from wagmi function App() { const result useStorageAt({ address: 0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2, blockNumber: 16280770n, // [!code focus] slot: 0x0, }) }注意blockNumber与blockTag互斥二者不能同时传入。blockTaglatest | earliest | pending | safe | finalized | undefined指定以哪个区块标签作为读取基准。默认跟随 RPC 节点的latest语义safe与finalized适用于需要规避链重组reorg风险的场景import { useStorageAt } from wagmi function App() { const result useStorageAt({ address: 0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2, blockTag: safe, // [!code focus] slot: 0x0, }) }chainIdconfig[chains][number][id] | undefined指定查询所在链的 ID。未传时Hook 会通过useChainId({ config })自动使用当前激活的链。下面的示例显式指定主网import { useStorageAt } from wagmi import { mainnet } from wagmi/core/chains function App() { const result useStorageAt({ chainId: mainnet.id, // [!code focus] address: 0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2, slot: 0x0, }) }在 packages/react/src/hooks/useStorageAt.ts 的实现中可以看到chainId的默认值是当前链 IDchainId: parameters.chainId ?? chainId。测试用例 packages/react/src/hooks/useStorageAt.test.ts 验证了在 OptimismchainId 10上同一地址、同一槽位会返回全零值说明同一存储槽在不同链上可能对应完全不同的数据跨链查询时务必显式指定chainId。configConfig | undefined指定要使用的Config实例覆盖从最近的WagmiProvider中自动获取的配置参见 site/react/api/createConfig.md。适用于多配置并存或需要在 Provider 之外使用 Hook 的场景import { useStorageAt } from wagmi import { config } from ./config // [!code focus] function App() { const result useStorageAt({ config, // [!code focus] address: 0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2, slot: 0x0, }) }scopeKeystring | undefined将缓存限定到给定上下文。具有相同scopeKey的 Hook 会共享同一份查询缓存不同scopeKey则可隔离缓存避免页面间数据串扰import { useStorageAt } from wagmi import { config } from ./config function App() { const result useStorageAt({ scopeKey: foo // [!code focus] address: 0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2, slot: 0x0, }) }scopeKey由ScopeKeyParameter定义并在查询键query key中参与序列化从而影响缓存的隔离粒度见 packages/core/src/query/getStorageAt.ts。queryUseQueryParameters | undefinedTanStack Query 的查询参数用于控制查询行为。Wagmi 内部使用queryFn与queryKey完成请求因此这两项不允许覆盖其余参数均可按需传入。常见可用参数包括enabled: boolean | undefined设为false可禁用查询自动执行常用于依赖查询Dependent Queries。gcTime: number | Infinity | undefined未使用/不活跃缓存数据的存活时间默认5 * 60 * 10005 分钟SSR 期间为Infinity。initialData查询尚未创建或缓存时用作初始数据会被持久化到缓存。staleTime: number | Infinity | undefined数据被判定为过期的时间默认0设为Infinity则永不视为过期。refetchInterval轮询刷新间隔毫秒可传函数按需计算。refetchOnWindowFocus窗口聚焦时是否在数据过期后重新拉取默认true。retry失败重试次数默认客户端为3、服务端为0。select对返回的data做变换不影响缓存中存储的原始数据。networkMode网络模式默认online。queryClient指定自定义QueryClient否则使用最近上下文中的实例。完整的参数清单可参考 site/shared/query-options.md。Return TypeuseStorageAt的返回值类型为UseStorageAtReturnType本质上是 TanStack Query 的UseQueryReturnTypeGetStorageAtData, GetStorageAtErrorTypeimport { type UseStorageAtReturnType } from wagmi其中GetStorageAtData即底层 Action 的返回类型GetStorageAtReturnType也就是Hex——32 字节存储槽值的十六进制表示详见 site/core/api/actions/getStorageAt.md。返回对象的核心字段完整列表见 site/shared/query-result.mddata: GetStorageAtData最近一次成功解析的数据默认undefined。dataUpdatedAt: number最近一次查询状态变为success的时间戳。error: null | GetStorageAtErrorType查询抛出的错误对象默认null。errorUpdatedAt / errorUpdateCount错误时间戳与错误累计次数。failureCount / failureReason失败次数与最近一次失败原因。fetchStatus: fetching | idle | paused查询拉取状态。isError / isPending / isSuccess由status派生的布尔值。isFetching / isRefetching / isLoading拉取中、后台刷新中、首次加载中的布尔值。isFetched / isFetchedAfterMount是否已拉取过、是否在挂载后拉取过。isLoadingError / isRefetchError首次加载失败 / 刷新失败标记。isPlaceholderData / isStale是否为占位数据 / 数据是否过期。refetch(options)手动重新拉取cancelRefetch默认true。status: error | pending | success查询整体状态。测试快照 packages/react/src/hooks/useStorageAt.test.ts 展示了真实返回值示例对0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2地址的0x0槽位成功返回0x7761676d6900000000000000000000000000000000000000000000000000000a同时queryKey序列化为[getStorageAt, { address, chainId: 1, slot }]。TanStack Query 集成useStorageAt底层复用 TanStack Query v5 的查询机制因此也可以直接使用底层的 query 构造函数便于在组件外预取、序列化或构建 query keyimport { type GetStorageAtData, type GetStorageAtOptions, type GetStorageAtQueryFnData, type GetStorageAtQueryKey, getStorageAtQueryKey, getStorageAtQueryOptions, } from wagmi/query这些导出对应 packages/core/src/query/getStorageAt.ts 中的实现getStorageAtQueryKey(options)根据参数过滤掉 query 相关字段生成稳定且可序列化的查询键形如[getStorageAt, { address, chainId, slot, ... }]getStorageAtQueryOptions(config, options)生成完整的查询选项对象其中queryFn负责调用getStorageAtActionGetStorageAtQueryKey / GetStorageAtQueryFnData / GetStorageAtData配套的类型工具。一个值得注意的实现细节是查询的启用条件packages/core/src/query/getStorageAt.tsenabled: Boolean( options.address options.slot (options.query?.enabled ?? true), )也就是说只有当address与slot都已提供且用户未显式禁用时查询才会真正发起。对应测试 packages/react/src/hooks/useStorageAt.test.ts 验证了在不传任何参数时 Hook 保持isPending、不会发请求而address从undefined变为有值后查询会自动触发并成功返回数据见同一测试文件第 204-290 行。这非常适合“地址异步加载后再读取存储”的典型场景。Action 调用链与底层原理useStorageAt是对核心 ActiongetStorageAt的响应式封装。其调用链如下useStorageAt通过useConfig(parameters)获取 Config通过useChainId({ config })解析当前链 ID调用getStorageAtQueryOptions组装 TanStack Query 选项查询触发后queryFn调用wagmi/core的getStorageAtAction源码见 packages/core/src/actions/getStorageAt.tsAction 内部根据chainId从 Config 取出对应客户端config.getClient({ chainId })再通过getAction(client, viem_getStorageAt, getStorageAt)复用 viem 的getStorageAtAction最终调用 RPC 节点的eth_getStorageAt方法并返回 32 字节的Hex值。这一分层结构意味着Hook 层负责响应式状态与缓存管理Action 层负责链交互与客户端解析viem 层负责 RPC 协议细节各层职责清晰、可独立测试与复用。如果你不需要 React 的响应式能力也可以直接使用核心包import { getStorageAt } from wagmi/core并按 site/core/api/actions/getStorageAt.md 中的方式传入config与参数调用。错误处理当查询失败如地址不存在、槽位越界、RPC 异常时error字段会携带类型为GetStorageAtErrorType的错误对象。该错误类型继承自 viem 的GetStorageAtErrorType见 packages/core/src/actions/getStorageAt.ts涵盖 RPC 请求、参数校验等常见错误类别。在组件中建议结合isError、isPending与data做完整的状态渲染function App() { const { data, isError, isLoading } useStorageAt({ address: 0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2, slot: 0x0, }) if (isLoading) return divLoading storage.../div if (isError) return divFailed to read storage slot/div return divStorage value: {data}/div }总结useStorageAt是 wagmi React 中读取链上原始存储数据的标准入口它把wagmi/core的getStorageAtAction 与 TanStack Query 的缓存、重试、轮询、依赖查询等能力无缝整合让开发者用最少的样板代码获取任意合约地址在任意存储槽位的值。掌握其address、slot、blockNumber、blockTag、chainId、config、scopeKey与query参数并理解其底层 Action 调用链与自动启用逻辑即可在合约调试、存储布局分析、链上数据监控等场景中稳定落地。【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考