任务: 在前端开发一个查询UI,查询当前用户账户的ETH余额和指定ERC20合约中的余额
目标:
- UI框架指定使用 MUI (https://mui.com)
- 需要查询到当前账户的ETH余额并展示在UI界面上
- 需要输入ERC20合约地址后,查询到到当前账户在此ERC20合约中的余额,并展示在UI界面上
提示:
- 需要安装 Metamask 插件
- 链接到 Sepolia 网络
- ERC20 合约地址 0x7939C9b7cE8BFFc6cb791eCB129f4c385e05727a
时间要求:24小时内给出相应网页,可以部署到github或其他托管平台,也可以通过腾讯会议运行demo代码演示
参考资料
- https://web3camp.us/
- https://github.com/web3camp-labs
实现:
首先,确保安装了MUI库和Web3.js库:
npm install @mui/material @emotion/react @emotion/styled web3
你可以创建一个JavaScript文件,并编写如下代码:
import React, { useState } from "react";
import Web3 from "web3";
import { Container, TextField, Button, Typography } from "@mui/material";
// 创建Web3实例连接到以太坊网络
const web3 = new Web3(window.ethereum);
// 定义要查询的ERC20合约地址
// const erc20ContractAddress = "0x7939C9b7cE8BFFc6cb791eCB129f4c385e05727a";
export default function Web3View() {
const [ethBalance, setEthBalance] = useState(null);
const [erc20Balance, setERC20Balance] = useState(null);
const [erc20Address, setERC20Address] = useState("");
// 检查是否有提供者可用
if (typeof window.ethereum !== "undefined") {
// 使用以太坊提供者进行初始化
web3.setProvider(window.ethereum);
} else {
console.error("无可用的以太坊提供者");
}
// 查询当前用户账户的ETH余额
async function handleGetEthBalance() {
try {
// 获取当前用户的账户地址
const accounts = await web3.eth.requestAccounts();
const account = accounts[0];
// 使用web3.eth.getBalance方法查询ETH余额
const balanceWei = await web3.eth.getBalance(account);
// 将余额从Wei转换为ETH单位
const balanceEth = web3.utils.fromWei(balanceWei, "ether");
setEthBalance(balanceEth);
} catch (error) {
console.error("获取ETH余额失败:", error);
}
}
// 查询指定ERC20合约中的余额
async function handleGetERC20Balance() {
try {
// 获取当前用户的账户地址
const accounts = await web3.eth.requestAccounts();
const account = accounts[0];
// 加载ERC20合约的ABI(应用二进制接口)
const erc20ABI = [
// 方法1:获取代币总供应量
{
constant: true,
inputs: [],
name: "totalSupply",
outputs: [
{
name: "",
type: "uint256",
},
],
payable: false,
stateMutability: "view",
type: "function",
},
// 方法2:获取指定地址的代币余额
{
constant: true,
inputs: [
{
name: "_owner",
type: "address",
},
],
name: "balanceOf",
outputs: [
{
name: "balance",
type: "uint256",
},
],
payable: false,
stateMutability: "view",
type: "function",
},
// 方法3:转账代币到指定地址
{
constant: false,
inputs: [
{
name: "_to",
type: "address",
},
{
name: "_value",
type: "uint256",
},
],
name: "transfer",
outputs: [
{
name: "",
type: "bool",
},
],
payable: false,
stateMutability: "nonpayable",
type: "function",
},
]; // ERC20合约的ABI定义
// 创建ERC20合约实例
const erc20Contract = new web3.eth.Contract(erc20ABI, erc20Address);
// 使用合约实例的balanceOf方法查询余额
const balance = await erc20Contract.methods.balanceOf(account).call();
setERC20Balance(balance.toString());
} catch (error) {
console.error("获取ERC20合约余额失败:", error);
}
}
return (
<Container maxWidth="sm">
<Typography variant="h4" align="center" gutterBottom>
查询账户余额
</Typography>
<Button variant="contained" onClick={handleGetEthBalance}>
查询ETH余额
</Button>
{ethBalance && (
<Typography variant="body1" gutterBottom>
当前ETH余额:{ethBalance} ETH
</Typography>
)}
<TextField
label="ERC20合约地址"
value={erc20Address}
onChange={(e) => setERC20Address(e.target.value)}
fullWidth
margin="normal"
/>
<Button variant="contained" onClick={handleGetERC20Balance}>
查询ERC20余额
</Button>
{erc20Balance !== null && (
<Typography variant="body1" gutterBottom>
当前ERC20余额:{erc20Balance}
</Typography>
)}
</Container>
);
}
效果图: