Hardhat本地部署Solidity合约后,React调用view函数报CALL_EXCEPTION错误
使用Hardhat在本地部署Solidity合约后,在React项目中调用合约的view函数时触发CALL_EXCEPTION错误,同时Hardhat本地节点控制台输出:
Warning: Calling an account which is not a contract
React调用代码:
const GetMessage = async () => { try { const {ethereum} = window; if (ethereum) { const provider = new ethers.providers.Web3Provider(ethereum); const signer = provider.getSigner(); const supplyChainContract = new ethers.Contract( contractAddress, contractABI, signer ); let count = await supplyChainContract.GetCount(); console.log(count.toNumber()); } else setMessage("Ethereum Not Found"); } catch (error) { console.log(error); return null; } };
Solidity合约代码:
pragma solidity ^0.8.17; import "../node_modules/hardhat/console.sol"; contract SupplyChain { uint256 public count; function GetCount() public view returns (uint256){ return count + 1; } }
以下是几个最可能的原因及对应解决方法:
合约地址错误:确认React代码中的
contractAddress完全匹配Hardhat部署时输出的合约地址。部署时Hardhat控制台会打印类似SupplyChain deployed to: 0x...的日志,直接复制该地址替换contractAddress,不要使用示例地址或旧地址。网络不匹配:检查钱包(如MetaMask)连接的网络是否为本地Hardhat节点。Hardhat默认本地节点的RPC地址是
http://localhost:8545,链ID为31337,如果钱包连接的是主网、测试网或其他节点,会导致找不到本地部署的合约。合约未成功部署:重新执行部署命令,确保部署过程无报错:
npx hardhat run scripts/deploy.js --network localhost部署完成后确认控制台输出合约地址及部署成功的提示。
ABI不匹配:确保React中使用的
contractABI是合约最新编译生成的ABI文件。如果合约代码有修改,需要重新执行npx hardhat compile生成新的ABI,替换旧的ABI内容。优化view函数调用方式:view函数属于只读调用,不需要签名者(signer),直接使用provider调用即可,避免不必要的签名流程问题。修改React代码如下:
const GetMessage = async () => { try { const {ethereum} = window; if (ethereum) { const provider = new ethers.providers.Web3Provider(ethereum); // 无需signer,直接用provider初始化合约 const supplyChainContract = new ethers.Contract( contractAddress, contractABI, provider ); let count = await supplyChainContract.GetCount(); console.log(count.toNumber()); } else setMessage("Ethereum Not Found"); } catch (error) { console.log(error); return null; } };
内容的提问来源于stack exchange,提问作者Surya M D G

