如何使用 Ethers.js 将你的 Dapp 与 MetaMask 连接起来

  • QuickNode
  • 发布于 2025-02-18 13:19
  • 阅读 45

本文详细介绍了如何使用 React 框架和 Ethers.js 库构建一个连接 MetaMask 的去中心化应用(dApp)。文章从 dApp 的定义和 MetaMask 的安装讲起,逐步引导读者完成前端应用的构建,包括用户连接 MetaMask、显示钱包地址和余额等功能。通过清晰的代码示例和图形展示,读者能够轻松理解和实现这些功能。

概述

在我们的 dApp 中,我们将有一个简单的 React 用户界面,其中有一个 material 按钮,询问用户是否连接到 MetaMask。如果他们没有账户,可以创建一个账户或登录到他们的账户。然后,他们将查看在用户界面上显示的钱包余额和地址。

先决条件

  • 对 React.js 的基本知识
  • 对 Ethereum 和区块链的基本知识
  • NPM
  • Ethers.js 库(版本 5.7)

什么是 dApps

dApp 是在去中心化网络上构建的应用程序。它具有用户界面和 智能合约

dApps 运行在开源、去中心化的环境中,不受任何单一参与者的控制。例如,开发人员可以创建一个类似 Facebook 的应用程序,并在 Ethereum 区块链上运行,当任何用户发布内容时,没有人可以删除它。在去中心化应用中,没有一个人完全管理用户数据。

dApp 可以有一个用任何语言构建的前端。它可以运行在 IPFSSwarm 等去中心化服务器上。

什么是 MetaMask

MetaMask 是一个流行的浏览器扩展,它作为连接到 Ethereum 区块链的 加密货币钱包。MetaMask 是一个安全的钱包,使用户能够与 Ethereum 的 dApps 互动。它允许用户存储 Ether 和其他 ERC-20 代币。用户可以在游戏中花费这些代币,将它们质押在 DeFi 应用中,并在交易所进行交易。MetaMask 不仅存储 ERC-20 代币,还可以存储 ERC-721 代币。

在本文中,我们将连接我们的 dApp 与 MetaMask,以便用户可以连接到 Ethereum 区块链。

安装 MetaMask

我们需要在浏览器中安装 MetaMask 扩展以完成本教程。

要在 Chrome 浏览器中添加 MetaMask,请访问此 链接,如果你使用的是其他浏览器,则可以搜索你正在使用的浏览器的扩展。

为什么选择 Ethers.js

Ethers.js 是一个轻量级的 JavaScript 库,允许开发人员连接和与 Ethereum 区块链互动。该库包含实用函数,并具备以太坊钱包的所有功能。

Ethers.js 使得只需几行代码就能轻松连接到 Ethereum 区块链。

了解了这些背景知识,你现在已经掌握了 我们使用这些技术的原因。现在,你准备好开始编码所需的一切了!

使用 React 构建 dApp 前端

通过此应用程序,我们将探索 React 框架和区块链的基本概念。我们将创建与 Ethereum 区块链通信的路径,查询它并获取数据以在我们的 dApp 中呈现。

在本教程结束时,我们将有一个与 Ethereum 互动的工作网页。

运行命令 npx create-react-app ethersjs_meta 创建一个名为 ethersjs_meta 的新 React 应用程序。

接下来,运行命令:

npm install ethers@5.7

这将安装 Ethers.js(版本 5.7)库。

接下来,删除 App.js 文件中的虚拟代码,然后复制粘贴下面的代码。

function App() {
  return (
    <div className="App-header">
      <div className="centerCard">
        <div className = "card">
          <div className="App">
            <WalletCard/>
          </div>
        </div>
      </div>
    </div>
  );
}
export default App;

接下来,我们想在 src 文件夹中创建一个名为 WalletCard.js 的新文件。WalletCard.js 将包含我们项目的所有 UI 和逻辑。

import React, { useState } from 'react';
import { Button } from '@material-ui/core';
import Ethereum from './Ethereum.png'
import { ethers } from 'ethers';
const provider = new ethers.providers.Web3Provider(window.ethereum)
const WalletCard = () => {
    const [errorMessage, setErrorMessage] = useState(null);
    const [defaultAccount, setDefaultAccount] = useState(null);
    const [userBalance, setUserBalance] = useState(null);
    const connectwalletHandler = () => {
        if (window.ethereum) {
            provider.send("eth_requestAccounts", []).then(async () => {
                await accountChangedHandler(provider.getSigner());
            })
        } else {
            setErrorMessage("请安装 MetaMask!!!");
        }
    }
    const accountChangedHandler = async (newAccount) => {
        const address = await newAccount.getAddress();
        setDefaultAccount(address);
        const balance = await newAccount.getBalance()
        setUserBalance(ethers.utils.formatEther(balance));
        await getuserBalance(address)
    }
    const getuserBalance = async (address) => {
        const balance = await provider.getBalance(address, "latest")
    }
    return (
        <div className="WalletCard">
            <img src={Ethereum} className="App-logo" alt="logo" />
            <h3 className="h4">
                欢迎来到去中心化应用
            </h3>
            <Button
                style={{ background: defaultAccount ? "#A5CC82" : "white" }}
                onClick={connectwalletHandler}>
                {defaultAccount ? "已连接!!" : "连接"}
            </Button>
            <div className="displayAccount">
                <h4 className="walletAddress">地址:{defaultAccount}</h4>
                <div className="balanceDisplay">
                    <h3>
                        钱包金额: {userBalance}
                    </h3>
                </div>
            </div>
            {errorMessage}
        </div>
    )
}
export default WalletCard;

在上面的代码中,我们创建了一个常量变量 called provider,并将其分配给新的 ethers.providers.Web3Provider(window.ethereum),这是一个读取区块链数据的抽象。

我们可以通过 window.ethereum 访问整个以太坊 API,这就是我们将其作为参数传递给 Ethers web3 提供程序的原因。

在 WalletCard 组件内,我们创建了三个状态来修改应用程序。当发生错误、账户显示更改或用户余额更改时,我们更改状态。

const [errorMessage, setErrorMessage] = useState(null);
const [defaultAccount, setDefaultAccount] = useState(null);
const [userBalance, setUserBalance] = useState(null);

变量 errorMessage 接收状态设置器 setErrorMessage,因为这是修改应用程序状态的唯一方法,确实存在其他方法,但上面的代码的使用不那么复杂。

此方法在 React 中称为 状态钩子。我们为我们应用中发生的三(3)个事件设置状态。

创建与 MetaMask 的连接

接下来,我们将创建一个名为 connectwalletHandler 的函数,其中将包含连接 MetaMask 的权限请求。该函数包含以下内容。

const connectwalletHandler = () => {
    if (window.ethereum) {
        provider.send("eth_requestAccounts", [])
            .then(async () => {
                await accountChangedHandler(provider.getSigner());
            })
    } else {
        setErrorMessage("请安装 MetaMask!!!");
    }
}

在上面的代码中,我们进行了一个小检查以确认用户是否安装了 MetaMask;如果用户没有安装,应提示用户安装 MetaMask。如果已安装,应连接到 MetaMask。

构建连接按钮

我们将创建一个按钮,允许用户连接到 Ethereum。此按钮将在点击时调用该函数。点击此按钮时,我们将连接到 MetaMask。

<Button
  style={{ background: defaultAccount ? "#A5CC82" : "white" }}
  onClick={connectwalletHandler}>
    {defaultAccount ? "已连接!!" : "连接"}
</Button>

defaultAccount 显示钱包地址,我们使用钱包地址在地址可用时显示已连接。否则,它应该只显示连接。

连接时应该如下所示。

虽然 MetaMask 默认连接到公共节点,但如果你希望使用自己的 QuickNode 提供程序,你当然可以这样做。你可以按照此 指南 来适当地配置你的 MetaMask 钱包。

登录到 MetaMask

连接到 MetaMask 后,我们会被提示登录。

显示用户钱包地址

为了处理账户的钱包地址和余额,我们创建了一个 async 函数,等待传递作为参数的 provider.getSigner() 功能。accountChangedHandler 包含以下内容:

const accountChangedHandler = async (newAccount) => {
        const address = await newAccount.getAddress();
        setDefaultAccount(address);
    }

在上面的代码中的这个函数内,我们传递了一个新参数 newAccount,它被分配给 provider.signer() ,因此我们可以访问 getAddress() 函数并通过状态设置器 setDefaultAccount(address) 将地址传递给我们的状态变量。

要显示钱包地址,我们将调用 defaultAccount 变量。

<h4 className="walletAddress">地址:{defaultAccount}</h4>

显示用户钱包余额

本节将向我们展示如何从区块链获取用户余额。

const accountChangedHandler = async (newAccount) => {
        const address = await newAccount.getAddress();
        setDefaultAccount(address);
        const balance = await newAccount.getBalance()
        setUserBalance(ethers.utils.formatEther(balance));
        await getuserBalance(address)
    }

根据上述代码,我们可以使用传递的新账户的 provider.signer() 访问钱包的余额,通过 getBalance() 函数,但这将返回十六进制值,并且会非常大且难以读取,因此我们必须将其从 Wei 转换为 Ether(Wei 是 Ether 的最小单位)。为此,我们将执行以下操作:

setUserBalance(ethers.utils.formatEther(balance));

接下来,我们将地址传递给 getuserBalance(),以具体说明我们需要其余额的钱包。

const getuserBalance = async (address) => {
        const balance = await provider.getBalance(address, "latest")
    }

在 getuserBalance() 函数中,我们将地址传递给 provider.getBalance(),它接受地址和 blockTag 作为参数。要在我们的用户界面中呈现它,请使用以下代码:

<div className="balanceDisplay">
  <h3>
    钱包金额: {userBalance}
  </h3>
</div>

结论

在本教程中,我们展示了如何使用 Ethers.js 库和 React 框架构建去中心化应用程序。

你还可以扩展区块链概念以构建你自己的 DeFi 项目,在该项目中你可以创建一个钱包,让你能够在 Ethereum 区块链上发送和接收 Ethereum 或其他代币。

你可以查看 Ethers.js 库 以了解如何使用该库的其他功能在区块链上构建更高级的项目。

我们 ❤️ 反馈!

让我们知道 如果你有任何反馈或新主题请求。我们希望听到你的声音。

  • 原文链接: quicknode.com/guides/eth...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
QuickNode
QuickNode
江湖只有他的大名,没有他的介绍。