当我尝试使用react.js使用hardhat在智能合约中输入数据时,这个错误不断出现
./src/BridgeData.js 中的错误 69:23-52 在“ethers”中找不到导出“ethers”。“providers”(导入为“ethers”)(可能的导出:AbiCoder、AbstractProvider、AbstractSigner、AlchemyProvider、AnkrProvider、BaseContract、BaseWallet、Block、BrowserProvider、ChainstackProvider、CloudflareProvider、ConstructorFragment、合同,ContractEventPayload,ContractFactory,ContractTransactionReceipt,ContractTransactionResponse,ContractUnknownEventPayload,EnsPlugin,EnsResolver,ErrorDescription,ErrorFragment,EtherSymbol,EtherscanPlugin,EtherscanProvider,EventFragment,EventLog,EventPayload,FallbackFragment,FallbackProvider,FeeData,FeeDataNetworkPlugin,FetchCancelSignal,FetchRequest,FetchResponse, FeeDataNetworkPlugin,固定数量,片段、FunctionFragment、GasCostPlugin、HDNodeVoidWallet、HDNodeWallet、索引、InfuraProvider、InfuraWebSocketProvider、接口、IpcSocketProvider、JsonRpcApiProvider、JsonRpcProvider、JsonRpcSigner、LangEn、Log、LogDescription、MaxInt256、MaxUint256、MessagePrefix、MinInt256、助记符、MulticoinProviderPlugin、N、片段、网络、 NetworkPlugin, NonceManager, ParamType, PocketProvider, QuickNodeProvider, Result, Signature, SigningKey, SocketBlockSubscriber, SocketEventSubscriber, SocketPendingSubscriber, SocketProvider, SocketSubscriber, StructFragment, Transaction, TransactionDescription, TransactionReceipt, TransactionResponse, Typed, TypedDataEncoder, UndecodedEventLog, UnmanagedSubscriber, Utf8ErrorFuncs, VoidSigner, Wallet, WebSocketProvider、WeiPerEther、Wordlist、WordlistOwl、WordlistOwlA、ZeroAddress、ZeroHash、accessListify、断言、assertArgument、assertArgumentCount、assertNormalize、assertPrivate、checkResultErrors、computeAddress、computeHmac、concat、copyRequest、dataLength、dataSlice、decodeBase58、decodeBase64、decodeBytes32String、decodeRlp、decryptCrowdsaleJson、解密KeystoreJson、decryptKeystoreJsonSync、defaultPath、defineProperties、dnsEncode、encodeBase58、encodeBase64、encodeBytes32String、encodeRlp、encryptKeystoreJson、encryptKeystoreJsonSync、ensNormalize、formatEther、formatUnits、fromTwos、getAccountPath、getAddress、getBigInt、getBytes、getBytesCopy、getCreate2Address、getCreateAddress、 getIcapAddress、getIndexedAccountPath、 getNumber、getUint、hashMessage、hexlify、id、isAddress、isAddressable、isBytesLike、isCallException、isCrowdsaleJson、isError、isHexString、isKeystoreJson、isValidName、keccak256、锁、makeError、掩码、namehash、parseEther、parseUnits、pbkdf2、randomBytes、recoverAddress、resolveAddress、 solveProperties、ripemd160、scrypt、scryptSync、sha256、sha512、showThrottleMessage、solidityPacked、solidityPackedKeccak256、solidityPackedSha256、stripZerosLeft、toBeArray、toBeHex、toBigInt、toNumber、toQuantity、toTwos、toUtf8Bytes、toUtf8CodePoints、toUtf8String、 dV4、verifyMessage、verifyTypedData、版本、单词列表、 ZeroPadBytes、zeroPadValue)
以下是react.js中使用的脚本
import { ethers } from "ethers";
const contractAddress = "0x5fc8d32690cc91d4c39d9d3abcbd16989f875707"; // Replace with your contract address
const contractABI = [
// ABI of the BridgeData contract
{
"inputs": [
{"internalType": "uint256", "name": "bridgeId", "type": "uint256"},
{"internalType": "string", "name": "name", "type": "string"},
{"internalType": "string", "name": "location", "type": "string"},
{"internalType": "uint256", "name": "length", "type": "uint256"},
{"internalType": "uint256", "name": "height", "type": "uint256"},
{"internalType": "uint256", "name": "yearBuilt", "type": "uint256"}
],
"name": "addBridge",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [{"internalType": "uint256", "name": "bridgeId", "type": "uint256"}],
"name": "getBridge",
"outputs": [
{"internalType": "string", "name": "", "type": "string"},
{"internalType": "string", "name": "", "type": "string"},
{"internalType": "uint256", "name": "", "type": "uint256"},
{"internalType": "uint256", "name": "", "type": "uint256"},
{"internalType": "uint256", "name": "", "type": "uint256"}
],
"stateMutability": "view",
"type": "function"
}
];
const getBridgeDataContract = () => {
const provider = new ethers.providers.Web3Provider(window.ethereum);
const signer = provider.getSigner();
return new ethers.Contract(contractAddress, contractABI, signer);
};
export { getBridgeDataContract };
import React, { useState } from "react";
import { getBridgeDataContract } from "./BridgeData";
const BridgeForm = () => {
const [bridgeId, setBridgeId] = useState("");
const [name, setName] = useState("");
const [location, setLocation] = useState("");
const [length, setLength] = useState("");
const [height, setHeight] = useState("");
const [yearBuilt, setYearBuilt] = useState("");
const handleSubmit = async (event) => {
event.preventDefault();
const contract = getBridgeDataContract();
await contract.addBridge(
bridgeId,
name,
location,
length,
height,
yearBuilt
);
console.log("Bridge data added successfully!");
};
return (
<form onSubmit={handleSubmit}>
<div>
<label>Bridge ID:</label>
<input
type="number"
value={bridgeId}
onChange={(e) => setBridgeId(e.target.value)}
required
/>
</div>
<div>
<label>Name:</label>
<input
type="text"
value={name}
onChange={(e) => setName(e.target.value)}
required
/>
</div>
<div>
<label>Location:</label>
<input
type="text"
value={location}
onChange={(e) => setLocation(e.target.value)}
required
/>
</div>
<div>
<label>Length (meters):</label>
<input
type="number"
value={length}
onChange={(e) => setLength(e.target.value)}
required
/>
</div>
<div>
<label>Height (meters):</label>
<input
type="number"
value={height}
onChange={(e) => setHeight(e.target.value)}
required
/>
</div>
<div>
<label>Year Built:</label>
<input
type="number"
value={yearBuilt}
onChange={(e) => setYearBuilt(e.target.value)}
required
/>
</div>
<button type="submit">Add Bridge</button>
</form>
);
};
export default BridgeForm;
// BridgeDisplay.js
import React, { useState } from "react";
import { getBridgeDataContract } from "./BridgeData";
const BridgeDisplay = () => {
const [bridgeId, setBridgeId] = useState("");
const [bridge, setBridge] = useState(null);
const handleSubmit = async (event) => {
event.preventDefault();
const contract = getBridgeDataContract();
const bridgeData = await contract.getBridge(bridgeId);
setBridge({
name: bridgeData[0],
location: bridgeData[1],
length: bridgeData[2],
height: bridgeData[3],
yearBuilt: bridgeData[4]
});
};
return (
<div>
<form onSubmit={handleSubmit}>
<div>
<label>Bridge ID:</label>
<input
type="number"
value={bridgeId}
onChange={(e) => setBridgeId(e.target.value)}
required
/>
</div>
<button type="submit">Get Bridge Data</button>
</form>
{bridge && (
<div>
<h2>Bridge Data</h2>
<p>Name: {bridge.name}</p>
<p>Location: {bridge.location}</p>
<p>Length: {bridge.length} meters</p>
<p>Height: {bridge.height} meters</p>
<p>Year Built: {bridge.yearBuilt}</p>
</div>
)}
</div>
);
};
export default BridgeDisplay;
// App.js
import React from "react";
import BridgeForm from "./BridgeForm";
import BridgeDisplay from "./BridgeDisplay";
function App() {
return (
<div className="App">
<h1>Bridge Data Management</h1>
<BridgeForm />
<BridgeDisplay />
</div>
);
}
export default App;
我尝试了以前的脚本,每次都会遇到相同的错误。
您可能已经安装了
ethers v6
但使用了 ethers v5
实现。来自迁移指南
// v5
provider = new ethers.providers.Web3Provider(window.ethereum)
// v6:
provider = new ethers.BrowserProvider(window.ethereum)
以及来自文档
let signer = null;
let provider;
if (window.ethereum == null) {
// If MetaMask is not installed, we use the default provider,
// which is backed by a variety of third-party services (such
// as INFURA). They do not have private keys installed,
// so they only have read-only access
console.log("MetaMask not installed; using read-only defaults")
provider = ethers.getDefaultProvider()
} else {
// Connect to the MetaMask EIP-1193 object. This is a standard
// protocol that allows Ethers access to make all read-only
// requests through MetaMask.
provider = new ethers.BrowserProvider(window.ethereum)
// It also provides an opportunity to request access to write
// operations, which will be performed by the private key
// that MetaMask manages for the user.
signer = await provider.getSigner();
}