使用WAGMI连接本地私链报错HttpRequestError: HTTP请求失败
本地私链下Wagmi无法连接调用合约的问题解决
在Goerli测试网使用Wagmi调用合约一切正常,但切换到本地8545端口的私链后,启动网站执行合约调用时出现HTTP请求失败错误。MetaMask可正常连接私链并显示余额,但Wagmi始终无法连接私链。
错误信息
ContractFunctionExecutionError: HTTP request failed. URL: http://127.0.0.1:8545 Request body: {"method":"eth_call","params":[{"data":"0x2e64cec1","to":"0x654717d19E9EF3dA2b15940053Ef02dD185f9795"},"latest"]} Raw Call Arguments: to: 0x654717d19E9EF3dA2b15940053Ef02dD185f9795 data: 0x2e64cec1 Contract Call: address: 0x654717d19E9EF3dA2b15940053Ef02dD185f9795 function: retrieve() Docs: https://viem.sh/docs/contract/readContract.html Details: Failed to fetch Version: viem@1.2.15
现有配置与代码
初始_app.js配置
const { chains, publicClient, webSocketPublicClient } = configureChains( [localhost], [publicProvider()] ) const config = createConfig({ autoConnect: true, connectors, //I use rainbowKit publicClient, webSocketPublicClient, });
修改后的_app.js配置(改用jsonRpcProvider)
const { chains, publicClient, webSocketPublicClient } = configureChains( [localhost], [ jsonRpcProvider({ rpc: (chain) => ({ http: `http://127.0.0.1:8545`, }), }), ], )
合约调用代码(index.js)
const data = await readContract({ address:'0x654717d19E9EF3dA2b15940053Ef02dD185f9795', abi: [ {"inputs":[],"name":"retrieve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"} ], functionName: 'retrieve', }) // more code const handleClick = () => { console.log(data) }
合约代码(contract.sol)
//SPDX-License-Identifier: MIT pragma solidity ^0.8.0; contract SimpleContract{ uint256 public value = 5; uint256 public value_ = 7; function set(uint256 number) public returns(uint256) { value = number; return value; } function retrieve() view public returns(uint256) { return value; } function retrievebyindex(uint8 index) view public returns(uint256) { if(index == 0) return value; else return value_; } fallback() external{} }
解决步骤
- 配置私链节点跨域权限:前端请求本地节点会触发跨域限制,启动Geth时添加
--http.corsdomain "*"参数;如果用Hardhat节点,在hardhat.config.js中添加跨域配置:module.exports = { networks: { hardhat: { chainId: 1337, url: "http://127.0.0.1:8545", cors: true } } }; - 验证私链节点可用性:在终端执行以下命令,检查节点是否正常响应:
若返回包含curl http://127.0.0.1:8545 -X POST -H "Content-Type: application/json" -d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":1}'result的JSON,说明节点正常;否则检查节点是否启动、端口是否被占用。 - 确保链ID匹配:Wagmi的localhost链默认ID是1337,需和本地私链的链ID一致。如果私链链ID不同,自定义链配置:
const localChain = { id: 1337, // 替换为你的私链链ID name: "Local Chain", network: "local", nativeCurrency: { name: "Ether", symbol: "ETH", decimals: 18 }, rpcUrls: { default: { http: ["http://127.0.0.1:8545"] }, }, blockExplorers: { default: { name: "None", url: "" }, }, }; const { chains, publicClient, webSocketPublicClient } = configureChains( [localChain], [jsonRpcProvider({ rpc: (chain) => ({ http: chain.rpcUrls.default.http[0] }) })] ); - 核对合约部署地址:确认
0x654717d19E9EF3dA2b15940053Ef02dD185f9795是合约在本地私链的正确部署地址,重新部署合约后地址可能变更。 - 调整合约调用时机:避免在组件初始化时立即调用
readContract,改为在用户交互时执行,确保Wagmi完成连接:const handleClick = async () => { const data = await readContract({ address:'0x654717d19E9EF3dA2b15940053Ef02dD185f9795', abi: [{"inputs":[],"name":"retrieve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}], functionName: 'retrieve', }); console.log(data); }
内容的提问来源于stack exchange,提问作者NekoshimaTama
相关产品推荐
相关产品推荐

