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

资讯详情

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

wagmi useBytecode Hook 使用指南:在 React 中读取合约地址字节码

wagmi useBytecode Hook 使用指南:在 React 中读取合约地址字节码 wagmi useBytecode Hook 使用指南在 React 中读取合约地址字节码【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmiuseBytecode是 wagmi 提供的 React Hook用于以声明式方式读取指定地址通常是合约地址上的字节码bytecode并自动接入 TanStack Query 的缓存、重试与状态管理机制。本文将围绕 useBytecode 官方文档 的完整参数体系展开结合 wagmi 仓库中 React Hook、core Action 与查询层的真实源码实现帮助你掌握从基础调用、历史区块查询到查询缓存控制的全套实战能力。一、useBytecode 是什么能做什么字节码是部署在链上地址处的 EVM 机器码以0x开头的十六进制字符串。通过读取字节码你可以实现一系列关键判断判断地址是否为已部署的合约对 EOA外部账户地址调用会返回null而对合约地址会返回非空字节码校验合约是否已存在或已被自毁查询历史区块可验证某地址在特定时间点是否仍持有代码实现合约存在性的展示与守卫逻辑例如在 DApp 中标记“该地址是合约”或提示“合约已不存在”。在 wagmi 中useBytecode只是wagmi/core中 getBytecode Action 的 React 响应式封装它把 Action 接入 TanStack Query自动完成请求触发、状态追踪、缓存共享与重渲染。二、导入与基础用法从wagmi包导入import { useBytecode } from wagmi最简用法只需传入目标地址import { useBytecode } from wagmi function App() { const result useBytecode({ address: 0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2, }) if (result.isPending) return divLoading bytecode…/div if (result.isError) return divError: {result.error?.message}/div return divBytecode: {result.data?.slice(0, 20)}…/div }示例中的0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2是官方文档与测试共用的 Wagmi Mint Example 合约地址见 useBytecode.test.ts可直接替换为你自己的合约地址。使用前需要配置WagmiProvider与createConfig参考仓库中的标准配置示例 site/snippets/react/config.tsimport { 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 包裹组件树useBytecode会自动从最近的 Provider 中取出配置。三、参数详解useBytecode的参数类型为UseBytecodeParametersimport { type UseBytecodeParameters } from wagmi该类型由GetBytecodeOptionsconfig, selectData ConfigParameterconfig组合而成见 useBytecode.ts其中既包含链上查询参数也包含 TanStack Query 的查询选项。address必选查询的核心键Address | undefined要读取字节码的合约地址。注意该参数是查询是否启用的决定性条件——在 core 查询层的实现中enabled: Boolean(options.address (options.query?.enabled ?? true)),见 packages/core/src/query/getBytecode.ts当address为空时查询自动处于禁用状态不会发起任何网络请求。import { useBytecode } from wagmi function App() { const result useBytecode({ address: 0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2, }) }blockNumberbigint | undefined指定要查询字节码的历史区块号以bigint字面量书写末尾带nimport { useBytecode } from wagmi function App() { const result useBytecode({ address: 0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2, blockNumber: 16280770n, }) }在 useBytecode.test.ts 中blockNumber: 15564163n合约部署之前的查询成功返回data: null正好印证了“历史区块上地址尚无字节码时返回null”的行为。注意blockNumber与blockTag互斥不能同时指定。blockTaglatest | earliest | pending | safe | finalized | undefined指定要查询字节码的区块标签默认由链客户端决定通常为latestimport { useBytecode } from wagmi function App() { const result useBytecode({ address: 0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2, blockTag: safe, }) }常用取值含义值含义latest最新已挖出的区块earliest创世区块pending待打包的交易所在区块safe已被多数验证者确认的安全区块PoS 链finalized已最终敲定的区块PoS 链测试中以blockTag: earliest查询同样得到data: null因为创世区块上该地址尚不存在任何代码。chainIdconfig[chains][number][id] | undefined指定在哪个链上查询。不传时默认使用WagmiProvider上下文中的当前链import { useBytecode } from wagmi import { mainnet } from wagmi/chains function App() { const result useBytecode({ chainId: mainnet.id, address: 0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2, }) }在 React Hook 源码中chainId 的默认值解析逻辑如下const config useConfig(parameters) const chainId useChainId({ config }) const options getBytecodeQueryOptions(config, { ...parameters, chainId: parameters.chainId ?? chainId, })见 useBytecode.ts即显式传入的chainId优先于当前激活链。测试中传入chain.optimism.id10时查询在 Optimism 链上执行且queryKey中chainId为 10见 useBytecode.test.ts。configConfig | undefined指定要使用的 createConfig 配置替代从最近的 WagmiProvider 中自动获取。适用于多配置或脱离 Provider 上下文的场景import { useBytecode } from wagmi import { config } from ./config function App() { const result useBytecode({ config, address: 0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2, }) }scopeKeystring | undefined将缓存限定在给定上下文中的作用域键。上下文即参数组合完全相同的 Hook 会共享同一份缓存而scopeKey不同则视为不同查询import { useBytecode } from wagmi import { config } from ./config function App() { const result useBytecode({ scopeKey: foo, address: 0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2, }) }从实现看scopeKey会被写入查询键[getBytecode, filterQueryOptions(options)]见 packages/core/src/query/getBytecode.ts并在 queryFn 执行前从参数中剥离不会透传给链上 RPC。四、TanStack Query 查询选项queryuseBytecode透传 TanStack Query 的query选项类型如下import { type UseBytecodeParameters } from wagmi需要注意wagmi 内部会占用queryFn与queryKey这两项不能被覆盖其余官方支持的选项均可用详见 query-options.md。常用选项选项类型说明enabledboolean \| undefined设为false禁用自动查询可用于依赖查询Dependent Queries。注意useBytecode的enabled恒等于address存在与否与该项的布尔与gcTimenumber \| Infinity \| undefined未被使用/非激活缓存数据在内存中的保留时间默认5 * 60 * 10005 分钟SSR 期间为Infinity设为Infinity关闭垃圾回收initialDataGetBytecodeData \| (() GetBytecodeData) \| undefined查询创建前的初始数据会持久化进缓存函数形式仅调用一次未设置staleTime时默认视为过期initialDataUpdatedAtnumber \| (() number) \| undefinedinitialData自身的最后更新时间戳毫秒metaRecordstring, unknown \| undefined附加在查询缓存条目上的元信息可在queryFn的上下文中访问networkModeonline \| always \| offlineFirst \| undefined网络模式默认onlinenotifyOnChangePropsstring[] \| all \| (() string[] \| all) \| undefined限制触发组件重渲染的属性列表默认基于访问跟踪placeholderDataGetBytecodeData \| ((prev) GetBytecodeData) \| undefined查询处于pending时的占位数据不持久化到缓存queryClientQueryClient \| undefined自定义 QueryClient否则使用最近上下文中的实例refetchIntervalnumber \| false \| ((data, query) number \| false) \| undefined轮询重取间隔毫秒refetchIntervalInBackgroundboolean \| undefined标签页在后台时是否继续轮询refetchOnMountboolean \| always \| ((query) boolean \| always) \| undefined挂载时若数据过期是否重取默认truerefetchOnReconnectboolean \| always \| ((query) boolean \| always) \| undefined网络重连时是否重取默认truerefetchOnWindowFocusboolean \| always \| ((query) boolean \| always) \| undefined窗口聚焦时是否重取默认trueretryboolean \| number \| ((failureCount, error) boolean) \| undefined失败重试次数客户端默认3服务端默认0retryDelaynumber \| ((retryAttempt, error) number) \| undefined重试延迟可用指数退避函数retryOnMountboolean \| undefined挂载时若查询含错误是否重试默认trueselect((data: GetBytecodeData) unknown) \| undefined对返回数据做转换/选取只影响返回值不影响缓存内容staleTimenumber \| Infinity \| undefined数据过期时间默认0设为Infinity永不过期structuralSharingboolean \| ((oldData, newData) GetBytecodeData) \| undefined查询结果间的结构共享默认true示例只查询一次、失败不重试、结果只取前 10 个字符const result useBytecode({ address: 0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2, query: { enabled: true, retry: 0, select: (data) data?.slice(0, 10), }, })五、返回值Return Type与状态字段返回类型为import { type UseBytecodeReturnType } from wagmi即UseQueryReturnTypeGetBytecodeData, GetBytecodeErrorType见 useBytecode.ts其本质是 TanStack Query 的useQuery结果完整字段见 query-result.md。核心字段dataGetBytecodeData即Hex | nullGetBytecodeReturnType见 packages/core/src/actions/getBytecode.ts。包含合约地址返回以0x开头的字节码十六进制字符串EOA 或历史区块上无代码的地址返回null查询层会把undefined归一化为null见 getBytecode.ts请求尚未完成默认undefined。status 与派生布尔量status: pending | error | successisPending/isError/isSuccess由status派生isLoading等价于isFetching isPending首次请求进行中isFetching/isPaused由fetchStatus派生fetchStatus取值为fetching | idle | paused。与缓存相关的字段isStale缓存数据过期或被失效时为trueisFetched/isFetchedAfterMount是否已获取过数据后者可用于不展示旧缓存isRefetching后台重取进行中等价于isFetching !isPendingisPlaceholderData当前展示的是否为占位数据isLoadingError/isRefetchError首次加载失败 / 重取失败dataUpdatedAt/errorUpdatedAt最近一次成功 / 失败的时间戳errorUpdateCount/failureCount/failureReason错误累计与失败计数信息。手动控制refetch(options?: { cancelRefetch?: boolean; throwOnError?: boolean })手动重新查询cancelRefetch默认为true先取消进行中的请求再发起新请求。从测试快照useBytecode.test.ts可以看到一次成功查询的典型返回status: success、data: /^0x.*/、isStale: true以及由[getBytecode, { address, chainId }]构成的queryKey。六、响应式行为依赖缺失时自动禁用useBytecode是响应式的当参数变化时查询键随之变化并自动重新执行。仓库测试覆盖了以下关键行为见 useBytecode.test.tsaddress由undefined变为具体地址初次渲染时status: pending、isPending: true、不发起请求重渲染传入地址后自动触发查询并成功返回字节码完全不传参数查询保持禁用状态isPending恒为true因为enabled在address缺失时为false。因此如果你的目标地址来自异步数据如从 ENS 解析、从路由参数加载可以直接把尚未就绪的变量传入 Hook无需手动管理enabled开关。七、TanStack Query 底层工具进阶除了 Hook 本身wagmi 还从wagmi/query导出底层查询工具便于在非 React 场景如服务端、事件处理器复用同一套缓存逻辑import { type GetBytecodeData, type GetBytecodeOptions, type GetBytecodeQueryFnData, type GetBytecodeQueryKey, getBytecodeQueryKey, getBytecodeQueryOptions, } from wagmi/query对应 query-imports.md其中getBytecodeQueryOptions(config, options)生成完整查询配置queryFn、queryKey、enabledgetBytecodeQueryKey(options)生成查询键例如[getBytecode, { address: 0x…, chainId: 1 }]。八、底层调用链从 Hook 到 RPC整个调用链清晰体现了 wagmi 的分层架构React 层useBytecode通过useConfig与useChainId解析配置与当前链组合出完整参数packages/react/src/hooks/useBytecode.ts查询层getBytecodeQueryOptions构造queryKey与queryFn并在queryFn中调用 core Actionpackages/core/src/query/getBytecode.tscore 层getBytecode通过config.getClient({ chainId })获取对应链的 viem 客户端再用getAction包装 viem 的getBytecode并执行packages/core/src/actions/getBytecode.tsviem 层最终由 viem 的getBytecode对应以太坊eth_getCodeRPC完成链上读取。九、常见陷阱与最佳实践blockNumber与blockTag互斥同时传入会引发 viem 参数校验错误二者只能取其一返回值是null而非空字符串EOA、未部署地址或历史区块上无代码时返回null判断合约存在性时用data ! null而不是data的真值判断0x长度为 2 的十六进制前缀仍为真值select不会修改缓存转换只作用于 Hook 返回值其他 Hook 共享的仍是原始字节码字节码可能很大完整合约字节码可达数千字节渲染时建议截断展示或仅在需要时如校验data ! null使用避免大字符串引发不必要的重渲染合理设置staleTime合约字节码几乎不变对存在性展示可设staleTime: Infinity或较长轮询间隔减少重复 RPC 请求。十、相关资源useBytecode React Hook 源码useBytecode 测试用例getBytecode core Action 文档 与 源码getBytecode 查询层实现createConfig 文档 与 WagmiProvider 文档React 配置示例官方文档原文useBytecode.md至此你已经可以从“读取某个地址的字节码”这一基础能力出发自由组合历史区块查询、多链指定、缓存控制与错误处理在 DApp 中构建可靠且高效的合约存在性判断逻辑。【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表