使用thirdweb-dev/react调用合约报错:无法解析元数据,contract为undefined
问题:thirdweb-react 连接合约时 contract 为 undefined,且无法解析合约元数据
我正在使用 thirdweb-dev/react 与智能合约交互,遇到两个问题:
- 代码中
contract始终为undefined - 报错提示:
could not resolve metadata for contract at 0xE4ffC734cfa5f3E33f9Da662D0e562155Ad37c6C
合约上下文代码(context.js)
import React, { useContext, createContext } from 'react'; import { useAddress, useContract, useMetamask, useContractWrite } from '@thirdweb-dev/react'; import { ethers } from 'ethers'; const StateContext = createContext(); export const StateContextProvider = ({ children }) => { const { contract } = useContract('0xE4ffC734cfa5f3E33f9Da662D0e562155Ad37c6C'); const { mutateAsync: createCampaign } = useContractWrite(contract, 'createCampaign'); const address = useAddress(); const connect = useMetamask(); const publishCampaign = async (form) => { try{ const data = await createCampaign([ address, //owner form.title, form.description, form.target, new Date(form.deadline).getTime(), form.image ]) console.log("contract call success",data); } catch(error) { console.log("contract call failure",error); } } return( <StateContext.Provider value={{ address, contract, connect, createCampaign: publishCampaign, }} > {children} </StateContext.Provider> ) } export const useStateContext = () => useContext(StateContext);
入口文件代码(main.js)
import React from 'react'; import ReactDOM from 'react-dom/client'; import { BrowserRouter as Router } from 'react-router-dom'; import { ChainId, ThirdwebProvider } from '@thirdweb-dev/react'; import { StateContextProvider } from './context'; import App from './App'; import './index.css'; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <ThirdwebProvider activeChainId="Goerli"> <Router> <StateContextProvider> <App /> </StateContextProvider> </Router> </ThirdwebProvider> )
解决方案
1. 修复合约元数据解析问题
thirdweb 依赖合约元数据生成实例,报错说明无法自动获取目标合约的元数据,可按以下步骤排查:
- 确认合约确实部署在 Goerli 测试网,地址完全正确
- 如果是自定义合约,部署时未上传元数据的话,需手动在
useContract中传入ABI:// 替换为你的合约ABI const CONTRACT_ABI = [...]; const { contract } = useContract('0xE4ffC734cfa5f3E33f9Da662D0e562155Ad37c6C', CONTRACT_ABI); - 检查钱包是否切换到 Goerli 网络,网络不匹配会导致元数据获取失败
2. 修复 contract 为 undefined 的问题
useContract 是异步加载的,组件初始化阶段 contract 会是 undefined,直接传给 useContractWrite 会出错。解决方法:
- 利用
useContract返回的isLoading状态,或给useContractWrite添加启用条件:const { contract, isLoading } = useContract('0xE4ffC734cfa5f3E33f9Da662D0e562155Ad37c6C'); // 只有合约加载完成后才初始化 useContractWrite const { mutateAsync: createCampaign } = useContractWrite(contract, 'createCampaign', { enabled: !!contract, }); - 或者在调用合约方法前先判断合约是否存在:
const publishCampaign = async (form) => { if (!contract) { console.log("合约未加载完成"); return; } // 后续逻辑不变 }
3. 修复 ThirdwebProvider 链ID配置
activeChainId 需传入枚举值或数字,不能用字符串 "Goerli",修改 main.js:
// 方式1:使用 ChainId 枚举 <ThirdwebProvider activeChainId={ChainId.Goerli}> // 方式2:直接传入链ID数字(Goerli的链ID是5) <ThirdwebProvider activeChainId={5}>
内容的提问来源于stack exchange,提问作者syed rahman
相关产品推荐
相关产品推荐

