使用ThirdWeb调用Goerli众筹合约报错:目标地址非智能合约
问题排查:ThirdWeb调用合约提示“地址不是智能合约”
核心问题
在Goerli测试网部署众筹合约(地址:0x3A1e1F275E50810EE30b19517938D5d23a991802)后,使用React+ThirdWeb的useContractWrite调用createCampaign函数时,触发错误:“你尝试发送交易的地址不是智能合约,请确认网络和合约地址正确”,已尝试查阅文档、重新部署合约仍未解决。
合约与前端代码片段
Solidity合约关键函数
function createCampaign( address _owner, string memory _title, string memory _description, uint256 _target, uint256 _deadline, string memory _image ) public returns (uint256) { Campaign storage campaign = campaigns[numberOfCampaigns]; require( campaign.deadline < block.timestamp, "The deadline should be a date in the future." ); campaign.owner = _owner; campaign.title = _title; campaign.description = _description; campaign.target = _target; campaign.deadline = _deadline; campaign.amountCollected = 0; campaign.image = _image; numberOfCampaigns++; return numberOfCampaigns - 1; }
前端关键代码
const { contract } = useContract( "0x3A1e1F275E50810EE30b19517938D5d23a991802", ABI ); const { mutateAsync: createCampaign } = useContractWrite( contract, "createCampaign" ); const address = useAddress(); const connect = useMetamask(); const publishCampaign = async (form) => { console.log(`Address : ${address}`); try { const data = await createCampaign([ address, // owner form.title, // title form.description, // description form.target, new Date(form.deadline).getTime(), // deadline, form.image, ]); console.log("contract call success", data); } catch (error) { console.log("contract call failure", error); } }; // 组件内调用 await createCampaign({ ...form, target: ethers.utils.parseUnits(form.target, 18), });
排查与解决步骤
1. 确认合约地址与网络匹配
- 直接在Goerli区块浏览器输入合约地址
0x3A1e1F275E50810EE30b19517938D5d23a991802,检查是否显示为智能合约:- 如果浏览器提示“不是合约地址”,说明部署过程失败,需重新部署并确认部署交易成功上链;
- 如果是合约地址,检查前端连接的网络是否确实是Goerli:
- 确认MetaMask当前网络为Goerli;
- 检查
ThirdwebProvider的activeChain设置为"goerli"。
2. 检查ABI的正确性
- 确保传入
useContract的ABI是完整且正确的合约ABI:- 不要只传入
createCampaign函数的片段,必须是编译合约后生成的完整ABI; - 重新编译合约,从Hardhat/Truffle/Remix等工具中复制最新的ABI替换前端变量。
- 不要只传入
3. 修正useContractWrite的调用参数格式
- 前端代码中两处
createCampaign调用的参数格式不一致,ThirdWeb的mutateAsync要求参数需用args字段包裹,正确调用方式如下:// 数组形式传参 await createCampaign({ args: [ address, form.title, form.description, ethers.utils.parseUnits(form.target, 18), new Date(form.deadline).getTime(), form.image ] }); - 注意:
target参数必须转换为Wei(用parseUnits),之前publishCampaign中的form.target未做转换,会导致参数错误。
4. 修复合约逻辑错误(避免后续功能异常)
- 合约中
createCampaign的require条件逻辑错误,刚创建的campaign.deadline默认是0,0 < block.timestamp永远为真,无法起到校验作用,修正为:require( _deadline > block.timestamp, "The deadline should be a date in the future." );
5. 确认ThirdWeb版本与环境配置
- 检查
@thirdweb-dev/react和@thirdweb-dev/sdk为最新稳定版,避免版本兼容问题; - 确保项目根组件已用
ThirdwebProvider包裹并指定Goerli链:import { ThirdwebProvider } from "@thirdweb-dev/react"; function App() { return ( <ThirdwebProvider activeChain="goerli"> {/* 应用组件 */} </ThirdwebProvider> ); }
内容的提问来源于stack exchange,提问作者Hrithik Raj
相关产品推荐
相关产品推荐

