译文出自:登链翻译计划[1] 译者:翻译小组[2] 校对:Tiny 熊[3]
也许你刚刚用solidity[4]、rust 编写了一个链上程序,但是如果没有一个很好的前端交互,几乎没有人可以使用它。
在这篇文章中,我们将了解如何在前端应用中,使用 HTML 和 JavaScript 与链上应用(智能合约或其他应用)交互。
并通过六种不同的方式,将你的 Metamask、Phantom 或其他区块链钱包地址连接到前端。最后,我们将看看有哪些流行的 Nextjs / React 前端软件包,可以辅助我们进行 web3 应用开发。
那么,让我们开始吧。
介绍
为了让 web3 体验友好,我们需要有用户友好的前端网站。全栈软件工程师在刚进入区块链领域可能会遇到一些挑战:
- 如何将Metamask[5](或Walletconnect[6], Phantom[7], 等等)连接到用户界面?
- 如何在网站上调用我的智能合约执行交易?
- 最好的实践都在做什么工具?
我在问自己这个问题时,看了几乎所有最流行的解决方案,并试图弄清楚应该向开发者推荐什么。因此,在这篇文章中,我们将了解到:
- 了解当我们想与区块链交互或向区块链发送交易时,浏览器中发生了什么。
- 看一下六种最流行的方法,来连接到我们的 web3 应用程序。
- 给出代码示例,并展示该领域所有最大的参与者在使用的哪些工具,这样我们也可以使用同样的工具。
如果你想看看现在一些专业的前端是什么样子,可以看一下Aave[8]或Uniswap[9]网站。
兴奋吗?我也是。我们开始吧。
如何将使用 Metamask 连接到智能合约
当然也可以是其他的钱包,如浏览器中的另一个钱包,如 Phantom、Walletconnect 等。
大多数区块链应用程序使用Hardhat[10]、Brownie[11]、DappTools[12]、Anchor[13]或Foundry[14]等框架构建(或者Remix[15] 工具)。而前端则使用在传统 web2 开发里学到的哪些东西:HTML、JavaScript、CSS,以及NextJS[16]、React[17]和Angular[18]等框架。
因此,如果你熟悉传统的网络开发,你就会走在别人的前面!
在浏览器中使用 Metamask
现在,跟上步伐,先安装Metamask[19],观看这个视频[20]以获得更深入的了解,安装完成之后,在页面右键单击,然后点击”检查(inspect)“:
右击屏幕,点击 检查(inspect)
或 检查元素(inspect element)
之后,可以看到像如下的内容:
他们是显示渲染网站页面的代码。然后,如果你点击顶部栏中的 sources
,会看到如下图内容。(如果你找到sources
,你可以点击>>
按钮来显示更多选项)。
如果你在浏览器中安装了 Metamask,你会在左边看到一个 Metamask
文件。如果你安装了 Phantom,你会看到一个 Phantom
。
他们是浏览器插件做的一些有趣的事情,它们自动 注入
你的浏览器,并作为你所在网站的一部分显示出来,让网站有机会与它们交互。
每个浏览器中都有一个 window
对象。我们可以通过点击console(控制台)
,进入 JavaScript 控制台[21], 输入 window,查看这个对象:
让我们继续输入window
,看看我们得到什么。
我们在浏览器中看到了 JavaScript 的window
对象。因为我们安装了Metamask
,此时会有一个ethereum
属性附加到window
对象上。输入window.ethereum
,看看返回了什么(如果你有 Phantom,你可以试试 window.solana
)。
你会看到返回了一个对象! 如果你没有 Metamask,你会得到一个undefined
。每个浏览器的钱包都会给 window 对象添加自己的属性,你通常可以在各自钱包的文档中找到它。这里是Metamask 文档[22],明确的介绍了window.ethereum
。
注意:在以前的版本中,为
window.web3
,后来改为window.ethereum
。
这就是所谓的区块链提供者(provider),那么我们为什么需要这个呢?
区块链连接与提供者(Provider)
每当我们想从区块链上读取数据,调用函数,或进行交易时,都需要连接到区块链网络。如果我们发送交易,还需要将签名的交易发送到一个区块链节点,这样它就可以将其发送到网络中的所有其他区块链节点。
你可能曾经在区块链应用程序中使用过Alchemy[23]、Infura[24]或Moralis Speedy Nodes[25]的RPC URL[26]。这些都是 ”节点即服务(node-as-a-service)“提供者,他们会提供我们一个 HTTP 端点来向区块链节点发送请求。加密货币钱包也是如此,Metamasks 内置有一个与区块链节点的连接。事实上,如果你去Metamask `network`标签[27],你可以看到 Metamask 正在使用的 RPC URL!
因此,每当我们用 Metamask 做一些事情,都会通过这个 RPC URL 进行 API 调用。
用 HTML 和 JavaScript 连接到加密货币钱包
我们将首先展示这一切是如何在 HTML 和 JavaScript 中完成的,然后我们将转向使用 Nextjs/React 例子。在我的 Github 这里[28]有一个使用 HTML/JavaScript 连接到加密货币钱包的完整例子,所有例子的列表也在我的 GitHub 里。[29]
首先,让我们创建一个标准的 HTML 文档,我们会给它一个连接(connect)
按钮:
<!DOCTYPE html>
<html>
<head>
<title>Javascript Test</title>
</head><body>
<button id="connectButton">Connect</button>
</body>
</html>
可以给我们的按钮添加一些功能,添加一个script
标签,并创建一个 JavaScript 函数,寻找window.ethereum
,如果找到它,就发出连接请求:
<!DOCTYPE html>
<head>
<title>Javascript Test</title>
</head>
<body>
<button id="connectButton" onclick="connect()">Connect</button>
</body>
<script>
async function connect() {
if (typeof window.ethereum !== "undefined") {
try {
await window.ethereum.request({ method: "eth_requestAccounts" });
} catch (error) {
console.log(error);
}
}}
</script>
</html>
这就是连接需要的全部代码。 eth_requestAccounts
直接来自Metamask 文档[30]。如果你把文件命名为index.html
并在浏览器中运行,你的 metamask 就会弹出要求连接:
发送交易
现在已经连接了 Metamask,是时候发送一个交易了。这时我们可以使用ethersjs[31]和web3js[32]等包来连接我们的提供者,然后发送一个交易。通常情况下,在 JavaScript 中执行一个函数/发送一个交易的 JavaScript 类似于这样:
代码语言:javascript复制const etheres = require("ethers")
contractAddress = "0x5FbDB2315678afecb367f032d93F642f64180aa3";
const abi = // some big javascript ABI here...
const provider = new ethers.providers.JsonRpcProvider(/* alchemy or infura */)
const wallet = new ethers.Wallet(/* Private key */, provider)
const contract = new ethers.Contract(contractAddress, abi, wallet)
const contractWithSigner = contract.connect(wallet)
const transactionResponse = contract.someFunction()
在浏览器中发送交易的唯一区别是,我们将提供者改为window.ethereum
,现在wallet
将直接来provider
。由于 Metamask 即是我们的提供者也是钱包(或签名者),代码将看起来像这样:
const etheres = require("ethers")
contractAddress = "0x5FbDB2315678afecb367f032d93F642f64180aa3";
const abi = // some big javascript ABI here...
const provider = new ethers.providers.Web3Provider(window.ethereum)
const signer = provider.getSigner();
const contract = new ethers.Contract(contractAddress, abi, signer)
const contractWithSigner = contract.connect(wallet)
const transactionResponse = contract.someFunction()
你会注意到,只有中间的两行改变了,现在从window.ethereum
获得钱包,我们的签名者(signer)来自提供者(即 metamask)。
现在,这里有一个问题。我们的浏览器无法识别require
(有时import
也有问题),所以需要添加一些包来帮助我们。
因为我不希望这里变成一个介绍前端的文章,你可以参看我的html-js-ethers-connect[33]的例子,它向我们展示了如何自己运行示例。你只需要安装以下东西就可以了:
- Git[34]
- NodeJS[35]
- Yarn[36]
- 以及Metamask[37]
然后,你可以按照README.md[38]中的说明进行初始化,用纯 HTML 和 JavaScript 做一个完整的例子,在浏览器中发送交易!
你将拥有一个与智能合约一起工作的简约的前端!
5 个最佳前端 Web3 的实践
没有特别的顺序
现在,让我们开始为全栈应用提供所需的工具。这些配置将包括:
- 如何初始化
- 极简的演示
- 真实世界的例子
你可以选择最适合你的那一个! 我们用NextJS[39]来做这些工作,因为ReactJS[40]是目前地球上最流行的前端框架,而 NextJS 是建立在它之上的,在我看来,它比原始的 ReactJS 更方便使用。然而,你 100%可以用 Angular、Svelte 或其他方式工作。
你可以找到我所有的简约代码示例full-stack-web3-metamask-connectors[41]仓库,其中链接出所有的演示。
初始化一个基本的 NextJS 项目
为了方便入门,所有这些项目都将从一个基本的 NextJS 项目开始。需要安装Node[42]、Git[43]和Yarn[44]才能继续。你还可以跟随nextjs 入门文档[45]。
运行以下命令:
代码语言:javascript复制yarn create next-app full-stack-web3
cd full-stack-web3
现在有了一个基本的项目框架,现在可以运行yarn dev
,看看现在的网站会是什么样子。最后,删除所有开始时的 示例代码
,进入index.js
文件,删除所有内容,仅保留:
export default function Home() {
return <div>Hi</div>;
}
现在前端就显示一个 Hi
。
设置本地 Hardhat 区块链和合约
现在,由于我们要测试函数交互,因此需要一个区块链来发送交易,以及相应的智能合约。代码已经为准备好了,在代码库hardhat-simple-storage GitHub[46]。你可以按照README.md
来进行设置,或者新开一个命令终端(与前端不同的终端)运行以下程序。
git clone https://github.com/PatrickAlphaC/hardhat-simple-storage
cd hardhat-simple-storage
yarn
yarn hardhat node
此时会启动一个本地区块链,给你一些临时私钥(账号),可用于部署 SimpleStorage
合约,合约有一个 store
函数。它接收一个uint256 _favoriteNumber
作为输入参数,并将该数字存储到一个公共变量中。在SimpleStorage.sol
文件中可以查看该合约代码。
用本地区块链设置你的 MetaMask
现在,要将 Metamask 连接到我们的本地区块链。这样就可以快速发送交易和测试。本地区块链和真实的区块链类似,但这个区块链是我们可以控制的。如果你愿意,你也可以使用测试网,跳过这一步,但你必须等待很长的时间来处理交易,这是没有人愿意的。
在区块链节点运行的终端,你会看到一个类似的输出:Started HTTP and WebSocket JSON-RPC server at http://127.0.0.1:8545/
。这就是 RPC URL,类似于 Alchemy。
现在,在 Metamask 中(请永远不要使用有真实资金的 Metamask 进行开发。最好创建一个新的浏览器账号配置(Profile)或下载另一个有 Metamask 插件的浏览器)点击顶部的网络按钮,然后 添加网络(Add Network)
。
按如下内容设置它,然后点击保存,然后确保你切换到该网络(在网络下拉列表中选择刚设置的网络)。
现在,点击右上方的大圆圈(账号),然后点击 导入账户(import account)
。
然后从 yarn hardhat node
命令的输出中添加一个私钥。之后,你应该看到一个账户,在本地网络上,并且有一些测试 ETH。Metamask 应该看起来像这样:
然后我们就可以开始了 :)
重要提示:如果你遇到了
nonce
被关闭的问题,或者交易不能正常发送。在 metamask 中,去右上方的圆圈->设置->高级->重置账户。就可以消除 nonce 的问题。
使用原始 Ethers
完整代码在这里[47]
最简单的方法是使用一些你已经熟悉的工具,比如 Ethers,我们可以从复制粘贴在 HTML 设置中的内容到index.js
文件中:
import styles from "../styles/Home.module.css";
import { ethers } from "ethers";
import { useEffect, useState } from "react";
export default function Home() {
const [isConnected, setIsConnected] = useState(false);
const [hasMetamask, setHasMetamask] = useState(false);
const [signer, setSigner] = useState(undefined);
useEffect(() => {
if (typeof window.ethereum !== "undefined") {
setHasMetamask(true);
}
});
async function connect() {
if (typeof window.ethereum !== "undefined") {
try {
await ethereum.request({ method: "eth_requestAccounts" });
setIsConnected(true);
const provider = new ethers.providers.Web3Provider(window.ethereum);
setSigner(provider.getSigner());
} catch (e) {
console.log(e);
}
} else {
setIsConnected(false);
}
}
async function execute() {
if (typeof window.ethereum !== "undefined") {
const contractAddress = "0x5FbDB2315678afecb367f032d93F642f64180aa3";
const abi = [
{
inputs: [
{
internalType: "string",
name: "_name",
type: "string",
},
{
internalType: "uint256",
name: "_favoriteNumber",
type: "uint256",
},
],
name: "addPerson",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
{
inputs: [
{
internalType: "string",
name: "",
type: "string",
},
],
name: "nameToFavoriteNumber",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
name: "people",
outputs: [
{
internalType: "uint256",
name: "favoriteNumber",
type: "uint256",
},
{
internalType: "string",
name: "name",
type: "string",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [],
name: "retrieve",
outputs: [
{
internalType: "uint256",
name: "",
type: "uint256",
},
],
stateMutability: "view",
type: "function",
},
{
inputs: [
{
internalType: "uint256",
name: "_favoriteNumber",
type: "uint256",
},
],
name: "store",
outputs: [],
stateMutability: "nonpayable",
type: "function",
},
];
const contract = new ethers.Contract(contractAddress, abi, signer);
try {
await contract.store(42);
} catch (error) {
console.log(error);
}
} else {
console.log("Please install MetaMask");
}
}
return (
<div>
{hasMetamask ? (
isConnected ? (
"Connected! "
) : (
<button onClick={() => connect()}>Connect</button>
)
) : (
"Please install metamask"
)}
{isConnected ? <button onClick={() => execute()}>Execute</button> : ""}
</div>
);
}
为此,我们添加了一些额外的功能,以便在连接或用户没有 Metamask 时显示 请安装Metamask
或 已连接
。你还会看到像useState
和useEffect
这样的命令,这些被称为 React Hooks,你可以从这个Fireship 视频[48]或react docs.[49]中了解它们的全部内容。虽然没有它们,这个应用也可以正常工作,只是我们无法在渲染之间保存应用的状态。
优点
- 直接使用 Ethers 对 UI 进行最精细的控制
缺点
- 我们必须写很多自己的代码,包括Contexts[50]。
- 如果支持更多的钱包连接会比较麻烦。
使用示例
Nader Dabit Explainer[51]
另外,在下面的例子中,我打算从另一个文件中导入abi
,这样就不会让文章的内容臃肿了。
使用 Web3Modal
完整代码在这里[52]
将基于 EVM 的区块链应用程序连接到钱包的另一种最流行的方式是使用Walletconnect[53]。我将要展示的所有例子(包括原始 Ethers 的例子)都可以连接到 Walletconnect(而且应该连接),使用 Web3Modal 并不是唯一可选的工具。Walletconnect 团队成员创建的创建了这个奇妙的Web3Modal[54]工具,它允许使用一个框架来连接到任何 Provider,包括Ledger[55]、WalletConnect、Torus[56]、Coinbase Wallet[57],等等。
我们只需要导入这个包,之后index.js
可能看起来像这样:
import styles from "../styles/Home.module.css";
import Web3Modal from "web3modal";
import { useState, useEffect } from "react";
import { ethers } from "ethers";
import WalletConnectProvider from "@walletconnect/web3-provider";
import { abi } from "../constants/abi";
let web3Modal;
const providerOptions = {
walletconnect: {
package: WalletConnectProvider, // required
options: {
rpc: { 42: process.env.NEXT_PUBLIC_RPC_URL }, // required
},
},
};
if (typeof window !== "undefined") {
web3Modal = new Web3Modal({
cacheProvider: false,
providerOptions, // required
});
}
export default function Home() {
const [isConnected, setIsConnected] = useState(false);
const [hasMetamask, setHasMetamask] = useState(false);
const [signer, setSigner] = useState(undefined);
useEffect(() => {
if (typeof window.ethereum !== "undefined") {
setHasMetamask(true);
}
});
async function connect() {
if (typeof window.ethereum !== "undefined") {
try {
const web3ModalProvider = await web3Modal.connect();
setIsConnected(true);
const provider = new ethers.providers.Web3Provider(web3ModalProvider);
setSigner(provider.getSigner());
} catch (e) {
console.log(e);
}
} else {
setIsConnected(false);
}
}
async function execute() {
if (typeof window.ethereum !== "undefined") {
const contractAddress = "0x5FbDB2315678afecb367f032d93F642f64180aa3";
const contract = new ethers.Contract(contractAddress, abi, signer);
try {
await contract.store(42);
} catch (error) {
console.log(error);
}
} else {
console.log("Please install MetaMask");
}
}
return (
<div>
{hasMetamask ? (
isConnected ? (
"Connected! "
) : (
<button onClick={() => connect()}>Connect</button>
)
) : (
"Please install metamask"
)}
{isConnected ? <button onClick={() => execute()}>Execute</button> : ""}
</div>
);
}
你会看到,我们设置了一些providerOptions
来告诉前端要支持哪些钱包,以及我们要支持哪些链以及需要设置一个NEXT_PUBLIC_RPC_URL
,它指向一个 RPC_URL 来连接到区块链。如果我们使用 walletconnect,我们实际上不使用用户的 metamasks 的内置区块链节点。
优点
- 易于整合多个钱包
- Ethers 很好集成
缺点
- 仍然没有内置的上下文组件
使用示例
- Web3Modal-Example[58]
- Scaffold-ETH[59]
- create-eth-app[60]
如果你想看看 Web3Modal、区块链等的一些前沿的前端使用,可以查看 Scaffold-ETH。这是一个了不起的学习工具,由Austin Griffith[61]编写,你可以用来解构一些最佳实践。
Moralis
完整代码在这里[62]
Moralis(或者更具体地说,react-moralis[63])是第一个包含上下文管理组件的软件包,它是非常有用的。它允许整个应用在组件之间轻松地共享状态,这是必要的,因为我们需要传递 Metamask 的授权。
Moralis 是由Ivan on Tech[64]及其团队创建,不仅可以帮助开发者连接到 Metamask,还可以帮助开发其他后端系统(全栈应用可能需要)。Etherscan[65]和Opensea[66]都是 web3 应用程序的例子,它们仍然需要后台和数据库。为什么呢?因为很多时候,你想添加大量的功能,在链上做起来会花费太多 Gas!所以你仍然想有一个后台和数据库。
因此,你仍然让智能合约做主要工作,而 Moralis 可以做所有围绕它的一些工作。下面是使用 Moralis 的代码:
代码语言:javascript复制import styles from "../styles/Home.module.css";
import { useMoralis, useWeb3Contract } from "react-moralis";
import { abi } from "../constants/abi";
import { useState, useEffect } from "react";
export default function Home() {
const [hasMetamask, setHasMetamask] = useState(false);
const { enableWeb3, isWeb3Enabled } = useMoralis();
const { data, error, runContractFunction, isFetching, isLoading } =
useWeb3Contract({
abi: abi,
contractAddress: "0x5FbDB2315678afecb367f032d93F642f64180aa3", // your contract address here
functionName: "store",
params: {
_favoriteNumber: 42,
},
});
useEffect(() => {
if (typeof window.ethereum !== "undefined") {
setHasMetamask(true);
}
});
return (
<div>
{hasMetamask ? (
isWeb3Enabled ? (
"Connected! "
) : (
<button onClick={() => enableWeb3()}>Connect</button>
)
) : (
"Please install metamask"
)}
{isWeb3Enabled ? (
<button onClick={() => runContractFunction()}>Execute</button>
) : (
""
)}
</div>
);
}
你会看到 Moralis 带有强大的 Hook 函数,如useWeb3Contract
,使获得状态和与合约交互更加容易,而且不需要 ethers。
Moralis 还提供的enableWeb3
函数代替了自己编写的connect
函数。
此外,在_app.js
中,需要用一个 Context 提供者来包装整个应用程序:
import "../styles/globals.css";
import { MoralisProvider } from "react-moralis";
function MyApp({ Component, pageProps }) {
return (
<MoralisProvider initializeOnMount={false}>
<Component {...pageProps} />
</MoralisProvider>
);
}
export default MyApp;
Morlais 有内置的属性选项,例如:可以用数据库设置前端,然而,如果你只想使用钩子和函数,你可以把initializeOnMount
设置为 false,等将来需要时才设置服务器
优点
- 有上下文提供者
- 内置与智能合约交互功能
- 可以选择引入后端,以获得更丰富的前端功能
缺点
- 必须手动添加自己的钱包
真实案例
- 以太坊 Boilerplate[67]
Web3-React
完整代码在这里[68]
Uniswap 工程负责人 Noah Zinsmeister 和朋友们建立了一个优秀的软件包,叫做web3-react[69]。这是被Uniswap[70]、Aave[71]和Compound[72]等顶级项目最广泛使用的包之一。它还包含了一个上下文组件管理器和一些令人难以置信的强大的 Hook 函数,让你可以直接上手并开始工作,还内置了一些 web3 钱包连接。
以下是index.js
修改后的代码:
import styles from "../styles/Home.module.css";
import { useWeb3React } from "@web3-react/core";
import { InjectedConnector } from "@web3-react/injected-connector";
import { abi } from "../constants/abi";
import { useState, useEffect } from "react";
import { ethers } from "ethers";
export const injected = new InjectedConnector();
export default function Home() {
const [hasMetamask, setHasMetamask] = useState(false);
useEffect(() => {
if (typeof window.ethereum !== "undefined") {
setHasMetamask(true);
}
});
const {
active,
activate,
chainId,
account,
library: provider,
} = useWeb3React();
async function connect() {
if (typeof window.ethereum !== "undefined") {
try {
await activate(injected);
setHasMetamask(true);
} catch (e) {
console.log(e);
}
}
}
async function execute() {
if (active) {
const signer = provider.getSigner();
const contractAddress = "0x5FbDB2315678afecb367f032d93F642f64180aa3";
const contract = new ethers.Contract(contractAddress, abi, signer);
try {
await contract.store(42);
} catch (error) {
console.log(error);
}
} else {
console.log("Please install MetaMask");
}
}
return (
<div>
{hasMetamask ? (
active ? (
"Connected! "
) : (
<button onClick={() => connect()}>Connect</button>
)
) : (
"Please install metamask"
)}
{active ? <button onClick={() => execute()}>Execute</button> : ""}
</div>
);
}
_app.js
代码:
import "../styles/globals.css";
import { Web3ReactProvider } from "@web3-react/core";
import { Web3Provider } from "@ethersproject/providers";
const getLibrary = (provider) => {
return new Web3Provider(provider);
};
function MyApp({ Component, pageProps }) {
return (
<Web3ReactProvider getLibrary={getLibrary}>
<Component {...pageProps} />
</Web3ReactProvider>
);
}
export default MyApp;
正如你所看到的,我们仍然使用 ethers 与智能合约交互,但我们使用 Hook 函数来启用 Metamask 和任何其他想要的钱包 Provider
优点
- 上下文提供者
- 内置与智能合约交互的功能
- 内置钱包连接
缺点
- 不像 web3modal 那样容易设置钱包
- 需要编写或使用自己的 Hook 来与智能合约交互。
真实案例
- Web3 React 示例[73]
- Aave[74]
- Uniswap[75]
使用 Dapp
完整代码的代码在这里[76]
Ethworks 和最流行的测试框架 waffle[77] , 他们背后是同一个团队,waffle 被hardhat[78]使用。现在他们又做了一个类似 moralis 的框架,你可以利用所有的 Hooks 和工具来构建一个前端,还包括一个上下文提供者。
下面是使用 Ethworks 后index.js
的代码:
import styles from "../styles/Home.module.css";
import { useEthers, useContractFunction } from "@usedapp/core";
import { useState, useEffect } from "react";
import { ethers } from "ethers";
import { abi } from "../constants/abi";
export default function Home() {
const { activateBrowserWallet, account } = useEthers();
const [hasMetamask, setHasMetamask] = useState(false);
useEffect(() => {
if (typeof window.ethereum !== "undefined") {
setHasMetamask(true);
}
});
async function connect() {
await activateBrowserWallet();
}
const contractAddress = "0x5FbDB2315678afecb367f032d93F642f64180aa3";
const contract = new ethers.Contract(contractAddress, abi);
const { send, state } = useContractFunction(contract, "store", {
transactionName: "store",
});
useEffect(() => {
console.log(`State: ${state.status}`);
}, [state]);
return (
<div>
{hasMetamask ? (
account ? (
"Connected! "
) : (
<button onClick={() => connect()}>Connect</button>
)
) : (
"Please install metamask"
)}
{account ? <button onClick={() => send(42)}>Execute</button> : ""}
</div>
);
}
_app.js
如下:
import "../styles/globals.css";
import { DAppProvider } from "@usedapp/core";
const config = {
multicallAddresses: ["0x5FbDB2315678afecb367f032d93F642f64180aa3"],
};
function MyApp({ Component, pageProps }) {
return (
<DAppProvider config={config}>
<Component {...pageProps} />
</DAppProvider>
);
}
export default MyApp;
向应用程序传递参数,用于配置如:支持的区块链和其他连接属性。与 Moralis 类似,useDapp
带有activateBrowserWallet
功能,用来激活 metamask/浏览器钱包,以及像useContractFunction
这样的 hook 函数,与智能合约交互(你不必使用 ethers)。
优点
- 上下文提供者
- 内置智能合约交互功能
缺点
- 不像 web3modal 那样容易设置钱包
- 没有内置数据库的选项
真实案例
- defi-stake-yield-brownie[79]
小结
每个工具都有其各自的优缺点,你可以根据自己的喜好、醒目的需求进行选择。
编码愉快!
本翻译由 Duet Protocol[80] 赞助支持。
原文:https://betterprogramming.pub/everything-you-need-to-know-about-fullstack-web3-94c0f1b18019
参考资料
[1]
登链翻译计划: https://github.com/lbc-team/Pioneer
[2]
翻译小组: https://learnblockchain.cn/people/412
[3]
Tiny 熊: https://learnblockchain.cn/people/15
[4]
solidity: https://learnblockchain.cn/docs/solidity/
[5]
Metamask: https://metamask.io/
[6]
Walletconnect: https://walletconnect.com/
[7]
Phantom: https://phantom.app/
[8]
Aave: https://app.aave.com/#/dashboard
[9]
Uniswap: https://app.uniswap.org/#/swap?chain=mainnet
[10]
Hardhat: https://hardhat.org/
[11]
Brownie: https://eth-brownie.readthedocs.io/en/stable/
[12]
DappTools: https://medium.com/@patrick.collins_58673/how-to-use-dapptools-code-like-makerdao-fed9909d055b
[13]
Anchor: https://project-serum.github.io/anchor/getting-started/introduction.html
[14]
Foundry: https://github.com/gakonst/foundry
[15]
Remix: https://remix.ethereum.org/
[16]
NextJS: https://nextjs.org/docs/api-reference/create-next-app
[17]
React: https://reactjs.org/
[18]
Angular: https://angular.io/
[19]
Metamask: https://metamask.io/
[20]
观看这个视频: https://www.youtube.com/watch?v=Af_lQ1zUnoM
[21]
JavaScript控制台: https://javascript.info/debugging-chrome#console
[22]
Metamask文档: https://docs.metamask.io/guide/mobile-best-practices.html#the-provider-window-ethereum
[23]
Alchemy: https://alchemy.com/?r=7d60e34c-b30a-4ffa-89d4-3c4efea4e14b
[24]
Infura: https://infura.io/
[25]
Moralis Speedy Nodes: https://moralis.io/speedy-nodes/
[26]
RPC URL: https://eth.wiki/json-rpc/API
[27]
Metamask network
标签: https://metamask.zendesk.com/hc/en-us/articles/360056196151-Using-custom-networks-with-MetaMask
[28]
我的Github这里: https://github.com/PatrickAlphaC/html-js-ethers-connect
[29]
也在我的GitHub里。: https://github.com/PatrickAlphaC/full-stack-web3-metamask-connectors
[30]
Metamask文档: https://docs.metamask.io/guide/rpc-api.html#table-of-contents
[31]
ethersjs: https://learnblockchain.cn/docs/ethers.js/
[32]
web3js: https://learnblockchain.cn/docs/web3.js/
[33]
html-js-ethers-connect: https://github.com/PatrickAlphaC/html-js-ethers-connect/tree/7fd43da59ff0c6ba4cf2c3dae0395bc6b8df03ad
[34]
Git: https://git-scm.com/book/en/v2/Getting-Started-Installing-Git
[35]
NodeJS: https://nodejs.org/en/
[36]
Yarn: https://classic.yarnpkg.com/lang/en/docs/install/
[37]
Metamask: https://metamask.io/
[38]
README.md: https://github.com/PatrickAlphaC/html-js-ethers-connect
[39]
NextJS: https://nextjs.org/
[40]
ReactJS: https://reactjs.org/
[41]
full-stack-web3-metamask-connectors: https://github.com/PatrickAlphaC/full-stack-web3-metamask-connectors
[42]
Node: https://nodejs.org/en/download/
[43]
Git: https://git-scm.com/downloads
[44]
Yarn: https://classic.yarnpkg.com/en/docs/cli/install/
[45]
nextjs入门文档: https://nextjs.org/docs/getting-started
[46]
hardhat-simple-storage GitHub: https://github.com/PatrickAlphaC/hardhat-simple-storage
[47]
完整代码在这里: https://github.com/PatrickAlphaC/nextjs-ethers-metamask-connect
[48]
Fireship视频: https://www.youtube.com/watch?v=TNhaISOUy6Q
[49]
react docs.: https://reactjs.org/docs/hooks-overview.html
[50]
Contexts: https://reactjs.org/docs/context.html
[51]
Nader Dabit Explainer: https://dev.to/dabit3/the-complete-guide-to-full-stack-ethereum-development-3j13
[52]
完整代码在这里: https://github.com/PatrickAlphaC/nextjs-ethers-metamask-connect
[53]
Walletconnect: https://walletconnect.com/
[54]
Web3Modal: https://github.com/Web3Modal/web3modal
[55]
Ledger: https://www.ledger.com/
[56]
Torus: https://app.tor.us/
[57]
Coinbase Wallet: https://www.coinbase.com/wallet
[58]
Web3Modal-Example: https://github.com/ChangoMan/web3modal-example
[59]
Scaffold-ETH: https://github.com/scaffold-eth/scaffold-eth
[60]
create-eth-app: https://github.com/paulrberg/create-eth-app
[61]
Austin Griffith: https://austingriffith.com/
[62]
完整代码在这里: https://github.com/PatrickAlphaC/nextjs-moralis-metamask-connect
[63]
react-moralis: https://github.com/MoralisWeb3/react-moralis
[64]
Ivan on Tech: https://www.youtube.com/channel/UCrYmtJBtLdtm2ov84ulV-yg
[65]
Etherscan: https://etherscan.io/
[66]
Opensea: https://opensea.io/
[67]
以太坊 Boilerplate: https://github.com/ethereum-boilerplate/ethereum-boilerplate
[68]
完整代码在这里: https://github.com/PatrickAlphaC/nextjs-web3-react-metamask-connect/tree/e9fd7e1c1f78441bc25347c37f581170aab14c40
[69]
web3-react: https://github.com/NoahZinsmeister/web3-react
[70]
Uniswap: https://uniswap.org/
[71]
Aave: https://aave.com/
[72]
Compound: https://compound.finance/
[73]
Web3 React 示例: https://github.com/NoahZinsmeister/web3-react/tree/main/packages/example
[74]
Aave: https://github.com/aave/aave-ui
[75]
Uniswap: https://github.com/Uniswap/interface
[76]
完整代码的代码在这里: https://github.com/PatrickAlphaC/nextjs-usedapp-metamask-connect
[77]
waffle: https://github.com/EthWorks/Waffle
[78]
hardhat: https://hardhat.org/
[79]
defi-stake-yield-brownie: https://github.com/PatrickAlphaC/defi-stake-yield-brownie
[80]
Duet Protocol: https://duet.finance/?utm_souce=learnblockchain