[英]Web3 - Provider not set or invalid
I'm trying to connect my frontend (Nextjs) with my contract on the Rinkeby Network ( token on etherscan ).我正在尝试将我的前端(Nextjs)与我在 Rinkeby 网络上的合同(etherscan 上的令牌)连接起来。 I'm new to the crypto space, so I'm not sure what provider it's talking about... I thought the connection was made with the useWeb3 hook, and everything was handled by Infura.我是加密领域的新手,所以我不确定它在说什么提供者......我认为连接是使用 useWeb3 钩子建立的,一切都由 Infura 处理。 I also want to note that I can connect to the Ethereum network with this setup, but not to my token on the Ethereum network.我还想指出,我可以使用此设置连接到以太坊网络,但不能连接到我在以太坊网络上的令牌。
I have this setup on my frontend:我的前端有这个设置:
./src/pages/index.tsx
: ./src/pages/index.tsx
:
import type { NextPage } from "next";
import React, { useEffect, useState } from "react";
import { useWeb3 } from "@openzeppelin/network/react";
import { createContract } from "../lib/herbie";
const Index: NextPage<IndexProps> = () => {
const { networkId, networkName, providerName, accounts, lib } = useWeb3(
`wss://rinkeby.infura.io/ws/v3/${process.env.INFURA_PROJECT_ID}`
);
useEffect(() => {
const fetchContract = async (): Promise<any> => {
if (networkId === 4 && accounts.length > 0) {
const contract = await createContract();
console.log({ contract });
console.log(contract.methods.balanceOf(accounts[0]).call()); // ERROR HERE
}
};
fetchContract();
}, [accounts, networkId]);
return (
<div>
<p>
{JSON.stringify({
networkId,
networkName,
providerName,
accounts,
})}
</p>
</div>
);
};
export default Index;
./src/lib/herbie.ts
: ./src/lib/herbie.ts
:
import Web3 from "web3";
const getAbi = async (): Promise<string> => {
const abi = await (await fetch("/abi.json")).json();
return abi;
};
const createContract = async (): Promise<any> => {
const herbieContract = new Web3().eth.Contract;
return new herbieContract(
(await getAbi()) as any,
"0xe71c56d861f90bf96c9f006d25ce91da97ddb238"
);
};
export { getAbi, createContract };
I get the following error:我收到以下错误:
My metamask:我的元掩码:
Thanks谢谢
You need to pass the provider into the contract instance as it says in thedocumentation您需要按照文档中的说明将提供程序传递到合同实例中
const contract = new Web3().eth.Contract(abi, address);
Contract.setProvider(`wss://rinkeby.infura.io/ws/v3/${process.env.INFURA_PROJECT_ID}`);
Almost all production code uses ethersjs instead of web3js btw.几乎所有的生产代码都使用 ethersjs 而不是 web3js 顺便说一句。
It looks like this instead:它看起来像这样:
const contract = new Contract(address, abi, library);
You are getting abi and address to create the contract but to be able to interact with the blockchain, you need a provider.您正在获取 abi 和地址来创建合同,但要能够与区块链交互,您需要一个提供者。 provider
is kinda a bridge that connects your contract to the blockchain. provider
有点像一座将你的合约连接到区块链的桥梁。
to load the provider you could use @metamask/detect-provider , you can get the provider in one line:要加载可以使用@metamask/detect-provider 的提供程序,您可以在一行中获取提供程序:
import detectEthereumProvider from '@metamask/detect-provider'
const provider = await detectEthereumProvider()
I manually load the provider to show what happens behind the scene:我手动加载提供程序以显示幕后发生的事情:
const [web3Api, setWeb3Api] = useState({
provider: null,
web3: null,
contract:contract
})
useEffect(() => {
const loadProvider = async () => {
// I assume your code to load contract is working
const contract= await createContract()
let provider = null;
// early metamask injects ethereum
if (window.ethereum) {
provider = window.ethereum;
try {
await provider.enable();
} catch {
console.error("User denied accounts access!")
}
}
// new version metamask injects web3
else if (window.web3) {
provider = window.web3.currentProvider
}
else if (!process.env.production) {
// this is ganache provider in development
provider = new Web3.providers.HttpProvider("http://localhost:7545")
}
if (provider) {
setWeb3Api({
web3: new Web3(provider),
provider,
contract
})
} else {
console.error("Please, install Metamask.")
}
}
loadProvider()
}, [])
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.