Next.js+Ethereum项目首次启动报ABI BUFFER_OVERRUN错误如何解决?
问题原因定位
这个BUFFER_OVERRUN错误本质是ABI解码器尝试读取超过返回数据长度的内容导致的,结合你报错栈同时出现ethers和web3的编解码调用、首次启动报错刷新后正常的特征,具体原因可按以下优先级排查解决:
解决方法
统一合约交互依赖库
你当前项目同时引入了web3和ethers两个区块链交互库,两者的ABI编解码实现版本不兼容,会导致返回数据解析异常。请移除其中一个库,所有合约调用逻辑统一使用同一个库实现:如果之前用web3初始化factory实例,就卸载所有ethers相关依赖;反之则用ethers替换web3的所有调用。调整合约实例初始化位置
不要在页面模块顶层初始化web3实例和factory合约实例,Next.js服务端渲染的顶层代码会在项目启动阶段执行一次,此时可能RPC连接未建立、ABI未加载完成,导致首次调用拿到无效返回值。请将factory初始化逻辑移入getServerSideProps方法内部,确保每次执行调用前合约实例是初始化完成的有效实例。增加返回值边界校验
对getCampaignCounts的返回值增加校验逻辑,确认返回值为正整数后再执行后续批量查询:export async function getServerSideProps(context) { let campaigns = []; try { // 此处新增factory初始化逻辑,不要放在模块顶层 const web3 = new Web3(/* 你的RPC地址 */); const factory = new web3.eth.Contract(/* 你的合约ABI */, /* 合约地址 */); const campaignsCount = await factory.methods.getCampaignCounts().call(); const count = parseInt(campaignsCount); // 校验返回值合法性 if (isNaN(count) || count <= 0) { return { props: { campaigns: [] } }; } campaigns = await Promise.all( Array(count) .fill() .map((_, index) => factory.methods.getDeployedCampaign(index).call()) ); } catch (e) { console.log("error in index server", e); } return { props: { campaigns }, }; }增加RPC调用重试逻辑
首次启动时RPC节点连接可能不稳定,导致合约调用返回异常短的错误信息(你报错里的length=3就是异常返回的长度,正常ABI编码的uint最少是32字节),可给合约调用增加重试逻辑,首次失败后自动重试1-2次。
内容的提问来源于stack exchange,提问作者Yilmaz
相关产品推荐
相关产品推荐

