
使用 wagmi/vue 的 useBytecode在 Vue 应用中获取链上合约字节码的完整指南【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmiuseBytecode是wagmi/vue提供的一个响应式组合式函数Composable用于在 Vue 应用中查询指定地址上的合约字节码Bytecode。本文以 site/vue/api/composables/useBytecode.md 为核心结合仓库中wagmi/vue、wagmi/core的源码实现与测试用例系统讲解useBytecode的导入方式、基础用法、全部参数address、blockNumber、blockTag、chainId、config、scopeKey、TanStack Query 扩展选项、返回值结构以及底层调用链帮助你快速判断一个地址是否为已部署合约、校验合约部署状态或排查链上合约是否存在。一、useBytecode 是什么useBytecode是一个 Vue 组合式函数Composable封装了对链上地址字节码的查询逻辑。它基于wagmi/core的getBytecodeaction 与 TanStack Querytanstack/vue-query构建返回响应式的查询状态data、error、status等当链 ID、地址或区块参数发生变化时查询结果会自动失效并重新获取。在真实业务中useBytecode常见的应用场景包括判断某个地址是否部署了合约无合约的地址返回空字节码0x校验合约部署结果例如在部署交易确认后确认链上已存在代码结合blockNumber/blockTag回溯历史区块检查某区块高度时合约是否存在配合chainId在多链应用中按指定链查询。二、导入方式在 Vue 项目中从wagmi/vue包中导入useBytecodeimport { useBytecode } from wagmi/vue该组合式函数的类型定义位于仓库源码 packages/vue/src/composables/useBytecode.tsexport type UseBytecodeParameters config extends Config Config, selectData GetBytecodeData, Compute DeepMaybeRefGetBytecodeOptionsconfig, selectData ConfigParameterconfig export type UseBytecodeReturnTypeselectData GetBytecodeData UseQueryReturnTypeselectData, GetBytecodeErrorType可见它的参数类型UseBytecodeParameters是GetBytecodeOptions与ConfigParameter的组合并支持DeepMaybeRef——这意味着所有参数都可以是 Vue 的ref/reactive响应式值这在动态切换查询目标时非常有用。三、基础用法useBytecode最基本的使用方式是指定一个合约地址返回的data即为该地址的字节码0x开头的十六进制字符串script setup langts import { useBytecode } from wagmi/vue const { data: byteCode } useBytecode({ address: 0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2, }) /script template Byte Code: {{ byteCode }} /template在调用前需要先创建并注入 Wagmi 配置。仓库中的配置示例site/snippets/vue/config.ts如下import { createConfig, http } from wagmi/vue import { mainnet, sepolia } from wagmi/vue/chains export const config createConfig({ chains: [mainnet, sepolia], transports: { [mainnet.id]: http(), [sepolia.id]: http(), }, })然后在应用入口通过WagmiPluginVue 包中对应 React 的WagmiProvider注入该配置useBytecode便会从最近的插件上下文中自动获取config。关于配置的详细说明可参考 site/vue/api/createConfig.md 与 site/vue/api/WagmiPlugin.md。四、参数详解useBytecode接收一个对象参数类型为UseBytecodeParameters。以下是文档与源码确认的全部参数。1.address类型Address | undefined说明要查询字节码的合约地址。script setup langts import { useBytecode } from wagmi/vue const { data: byteCode } useBytecode({ address: 0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2, }) /script template Byte Code: {{ byteCode }} /template值得注意的是address是必填项。从 packages/core/src/query/getBytecode.ts 的源码可以看到查询的启用条件与校验都依赖于它enabled: Boolean(options.address (options.query?.enabled ?? true)), queryFn: async (context) { const [, { scopeKey: _, ...parameters }] context.queryKey if (!parameters.address) throw new Error(address is required) ... }也就是说未提供address时查询不会执行enabled为false即使强制执行queryFn也会抛出address is required错误。2.blockNumber类型bigint | undefined说明指定在哪个区块高度上查询字节码可用于回溯历史状态。script setup langts import { useBytecode } from wagmi/vue const { data: byteCode } useBytecode({ address: 0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2, blockNumber: 16280770n, }) /script template Byte Code: {{ byteCode }} /template3.blockTag类型latest | earliest | pending | safe | finalized | undefined说明指定在哪个区块标签上查询字节码。其中safe与finalized通常用于 Layer 2如 OP Stack链表示已安全确认或已最终确定的区块。script setup langts import { useBytecode } from wagmi/vue const { data: byteCode } useBytecode({ address: 0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2, blockTag: safe, }) /script template Byte Code: {{ byteCode }} /template注意blockNumber与blockTag是互斥的区块定位参数二选一使用。4.chainId类型config[chains][number][id] | undefined说明指定在哪个链上查询。未传入时默认使用当前激活的链 ID由useChainId提供。这使多链应用可以针对不同链分别查询同一地址的字节码。script setup langts import { useBytecode } from wagmi/vue import { mainnet } from wagmi/vue/chains const { data: byteCode } useBytecode({ address: 0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2, chainId: mainnet.id, }) /script template Byte Code: {{ byteCode }} /template5.config类型Config | undefined说明显式指定要使用的[Config](https://link.gitcode.com/i/5ca64b4729193ab1f573ebad3e7e5953)实例而不是从最近的WagmiPlugin上下文中获取。适合在测试或需要绕过全局上下文注入的场景中使用。script setup langts import { useBytecode } from wagmi/vue import { config } from ./config const { data: byteCode } useBytecode({ address: 0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2, config, }) /script template Byte Code: {{ byteCode }} /template6.scopeKey类型string | undefined说明将查询缓存限定到指定上下文。具有相同scopeKey与相同其他参数的组合式函数会共享同一份缓存从而避免不同业务场景之间互相污染查询状态。script setup langts import { useBytecode } from wagmi/vue import { config } from ./config const { data: byteCode } useBytecode({ address: 0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2, scopeKey: foo, }) /script template Byte Code: {{ byteCode }} /template7.queryTanStack Query 扩展参数除上述业务参数外useBytecode还支持通过query子对象透传 TanStack Query 的选项详见 site/shared/query-options.md。常用选项包括参数类型说明与默认值enabledboolean \| undefined设为false可禁用查询自动执行常用于依赖查询Dependent QueriesgcTimenumber \| Infinity \| undefined未使用/非活跃缓存数据的保留时间默认5 * 60 * 10005 分钟SSR 期间为InfinityinitialDataGetBytecodeData \| (() GetBytecodeData) \| undefined初始缓存数据初始数据默认视为过期除非设置了staleTimestaleTimenumber \| Infinity \| undefined数据被视为过期的毫秒数默认0设为Infinity则永不过期refetchIntervalnumber \| false \| function \| undefined轮询刷新频率毫秒可用于监控合约部署状态retryboolean \| number \| function \| undefined失败重试次数客户端默认3服务端默认0networkModeonline \| always \| offlineFirst \| undefined网络模式默认onlineselect((data: GetBytecodeData) unknown) \| undefined对返回数据做变换仅影响返回的data不影响缓存内容一个组合示例仅在地址存在且组件挂载后才发起查询并对结果做长度判断script setup langts import { useBytecode } from wagmi/vue import { ref } from vue const address ref0x${string} | undefined() const { data: byteCode, isLoading, isError } useBytecode({ address, query: { enabled: () Boolean(address.value), }, }) /script说明Wagmi 内部使用queryFn与queryKey来驱动查询因此这两个 TanStack Query 参数不支持用户覆盖。五、返回值useBytecode的返回值类型为UseBytecodeReturnType即UseQueryReturnTypeGetBytecodeData, GetBytecodeErrorType本质上是 TanStack Query 的观察者结果详见 site/shared/query-result.md主要包括dataGetBytecodeData最后一次成功解析的数据字节码0x开头的十六进制字符串若地址无合约data为null——见下文源码说明默认为undefinederrornull | GetBytecodeErrorType查询失败时的错误对象默认为nullstatuserror | pending | success查询状态fetchStatusfetching | idle | paused是否正在抓取派生布尔值isError、isPending、isSuccess、isLoading、isFetching、isRefetching、isStale等refetch手动重新执行查询的函数failureCount/failureReason失败次数与失败原因dataUpdatedAt/errorUpdatedAt数据与错误最近一次更新的时间戳。在模板中常用的组合方式是script setup langts import { useBytecode } from wagmi/vue const { data: byteCode, isLoading, isError } useBytecode({ address: 0xFBA3912Ca04dd458c843e2EE08967fC04f3579c2, }) /script template div v-ifisLoadingLoading…/div div v-else-ifisErrorFailed to load bytecode/div div v-else {{ byteCode ? Contract deployed (${byteCode.length} hex chars) : No contract at address }} /div /template六、源码原理从 composable 到链上 RPCuseBytecode的调用链清晰且分层明确理解它有助于排查问题和进行二次封装。1. Vue 组合式函数层源码 packages/vue/src/composables/useBytecode.ts 的核心逻辑如下export function useBytecode config extends Config ResolvedRegister[config], selectData GetBytecodeData, ( parameters: UseBytecodeParametersconfig, selectData {}, ): UseBytecodeReturnTypeselectData { const params computed(() deepUnref(parameters)) const config useConfig(params) const chainId useChainId({ config }) const options computed(() getBytecodeQueryOptions(config as any, { ...params.value, chainId: params.value.chainId ?? chainId.value, }), ) return useQuery(options as any) as any }它依次完成四件事用deepUnref将ref/reactive形式的参数深度解包为普通值并包装为computed保证参数变化时自动重建查询通过useConfig获取配置优先取显式传入的config否则取插件上下文中的全局配置通过useChainId获取当前链 ID并在未显式传入chainId时作为默认值调用getBytecodeQueryOptions生成查询选项交由useQuery对tanstack/vue-query的封装见 packages/vue/src/utils/query.ts执行。2. 查询选项层query key / enabled / queryFnpackages/core/src/query/getBytecode.ts 负责构建查询export function getBytecodeQueryOptions config extends Config, selectData GetBytecodeData, (config: config, options: GetBytecodeOptionsconfig, selectData {}) { return { ...options.query, enabled: Boolean(options.address (options.query?.enabled ?? true)), queryFn: async (context) { const [, { scopeKey: _, ...parameters }] context.queryKey if (!parameters.address) throw new Error(address is required) const bytecode await getBytecode(config, { ...(parameters as any), address: parameters.address, }) return (bytecode ?? null) as any }, queryKey: getBytecodeQueryKey(options), } } export function getBytecodeQueryKeyconfig extends Config(options {}) { return [getBytecode, filterQueryOptions(options)] as const }要点缓存键queryKey为[getBytecode, { address, chainId, blockNumber, blockTag, scopeKey }]。只要这些参数变化就会产生新的缓存条目并在chainId等变化时自动重新查询enabled逻辑address存在且用户未显式禁用时才执行查询空字节码处理底层若返回undefined如 EOA 地址或不存在合约的地址会统一归一化为null方便在模板中做v-if判断。3. 底层 action 层最终请求由 core 层的getBytecodeaction 发出packages/core/src/actions/getBytecode.tsexport async function getBytecodeconfig extends Config( config: config, parameters: GetBytecodeParametersconfig, ): PromiseGetBytecodeReturnType { const { chainId, ...rest } parameters const client config.getClient({ chainId }) const action getAction(client, viem_getBytecode, getBytecode) return action(rest) }它从config中按chainId取出对应的 viem Client并通过getAction调用 viem 的getBytecode方法最终走 RPC 的eth_getCode。这与 site/core/api/actions/getBytecode.md 中记录的 core action 一一对应。七、测试验证查询选项与 action 的行为契约仓库为getBytecode提供了完整的单元测试可用于验证上述行为packages/core/src/query/getBytecode.test.ts 验证了查询选项的构建默认情况下enabled为true且queryKey会精确反映address、chainId、blockNumber、blockTag等参数例如传入chainId: 456时queryKey 中出现chainId: 456传入blockNumber: 1234567890n时以bigint形式出现在 queryKey 中packages/core/src/actions/getBytecode.test.ts 则覆盖了 action 层的default、blockNumber、blockTag、chainId四类调用场景确认这些参数都会正确透传给底层 viem action。八、注意事项与最佳实践address为必填未提供时查询不会执行且queryFn会抛错因此建议配合响应式ref在地址确定后再渲染组件或再启用查询。空地址/EOA 的处理地址上不存在合约时data为null可用v-else分支提示该地址无合约而不要用!data简单判断。区块定位参数互斥blockNumber与blockTag二选一同时传入可能导致不符合预期的查询。多链场景显式传chainId虽然默认会跟随当前激活链但在多链 UI 中建议显式传入目标chainId避免用户切换网络时数据发生跳变。善用query扩展项如需轮询合约部署进度可设置refetchInterval如需与其他查询联动可使用enabled实现依赖查询。类型导入相关的GetBytecodeData、GetBytecodeOptions、GetBytecodeQueryKey、getBytecodeQueryOptions、getBytecodeQueryKey等类型与工具函数定义于wagmi/core/queryVue 侧通过wagmi/vue暴露在编写自定义查询或测试时可从wagmi/vue/query导入。总结useBytecode是wagmi/vue中一个小而精的查询组合式函数参数层覆盖了地址、区块定位、链选择、配置注入与缓存隔离查询层由 TanStack Query 提供缓存、重试、轮询等能力底层则由wagmi/core的getBytecodeaction 与 viem 的eth_getCode支撑。通过本文的参数表、可运行示例与源码调用链分析你可以直接在 Vue 应用中接入合约字节码查询用于合约存在性校验、部署状态监控与历史区块回溯等场景。【免费下载链接】wagmiReactive primitives for Ethereum apps项目地址: https://gitcode.com/GitHub_Trending/wa/wagmi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考