Next.js getServerSideProps调用Solidity合约函数报Bad Response错误
问题分析与解决方案
相关代码
import React, { Component } from "react"; import factory from "../ethereum/factory"; import { ethers } from "ethers"; class CampaignIndex extends Component { render() { return <div>campaigns{this.props.campaigns}</div>; } } export async function getServerSideProps() { const campaigns = await factory.getDeployedCampaigns(); await campaigns.wait(); console.log(campaigns); return { campaigns }; } export default CampaignIndex;
背景说明
- factory是已部署合约的实例
getDeployedCampaigns()是合约中的只读函数,返回地址数组- 使用Next.js v12.3.1
问题描述
在getServerSideProps中调用getDeployedCampaigns()时返回“bad request”错误,但在其他位置调用该函数可得到预期结果,需排查Next.js环境下的异常原因并解决。
修复方案
1. 移除不必要的.wait()调用
getDeployedCampaigns()是只读合约调用(view/pure类型),这类调用不会触发链上交易,直接返回结果。.wait()方法仅用于发送交易(修改链上状态的操作),在只读调用后使用会导致类型错误,进而引发请求异常。
修复后的getServerSideProps代码:
export async function getServerSideProps() { const campaigns = await factory.getDeployedCampaigns(); console.log(campaigns); // 必须用props对象包裹返回数据,否则组件无法接收 return { props: { campaigns } }; }
2. 检查合约实例的Provider配置
服务端渲染环境中,不能使用仅适用于浏览器的Provider(如window.ethereum),否则会因服务端无window对象导致请求失败。需为服务端和客户端分别配置Provider:
// ethereum/factory.js import { ethers } from "ethers"; import CampaignFactory from "./build/CampaignFactory.json"; let factory; const CONTRACT_ADDRESS = "你的合约部署地址"; if (typeof window !== "undefined") { // 客户端环境:使用浏览器钱包Provider const provider = new ethers.providers.Web3Provider(window.ethereum); const signer = provider.getSigner(); factory = new ethers.Contract(CONTRACT_ADDRESS, CampaignFactory.abi, signer); } else { // 服务端环境:使用节点Provider(如Alchemy/Infura) const provider = new ethers.providers.JsonRpcProvider("你的节点RPC地址"); factory = new ethers.Contract(CONTRACT_ADDRESS, CampaignFactory.abi, provider); } export default factory;
3. 确认返回格式合规
Next.js的getServerSideProps要求返回值必须包含props字段,原代码直接返回{ campaigns }会导致组件无法接收到数据,间接引发异常。必须严格按照{ props: { 你的数据 } }格式返回。
内容的提问来源于stack exchange,提问作者Mahip Parekh
相关产品推荐
相关产品推荐

