教程:创建由以太坊支持的 Web3 聊天
在本文中,我们将学习如何将以太坊智能合约连接到React应用程序,并使用户能够与之交互。
先决条件
- 要在浏览器中安装MetaMask扩展
- 一个代码编辑器
- 关于以下主题的一些知识:以太坊,MetaMask, React, TypeScript
在以太坊主网上工作要花真金白银!
在本教程中,我假设的是你的MetaMask设置为使用Rinkeby。Rinkeby是一个复制主网的测试网络,允许我们免费部署和使用智能合约。
项目
我们将为这个基于区块链的聊天建立一个界面,如下所示:
- 左边的侧边栏包含一个按钮,用于连接到聊天或指示连接用户的地址。
- 右侧的聊天框,显示消息和输入栏。
在这篇文章中,我们不会关注如何让UI更漂亮,我们的目标是关注如何用最直接的方式与智能合约交互。
我已尽力使本教程易于理解,但如果有些东西还是不甚清晰,也不用灰心,你会在本文的最后找到一个包含已完成项目的 GitHub 存储库的链接。
智能合约
首先,我们要连接到前端的智能合约,如下所示:
// SPDX-License-Identifier: MIT
pragma solidity 0.8.12;contract BlockchainChat {
event NewMessage(address indexed from, uint timestamp, string message); struct Message {
address sender;
string content;
uint timestamp;
} Message[] messages; function sendMessage(string calldata _content) public {
messages.push(Message(msg.sender, _content, block.timestamp));
emit NewMessage(msg.sender, block.timestamp, _content);
} function getMessages() view public returns (Message[] memory) {
return messages;
}
}
event
,`emit 这些东西是什么?
event 用于通知外部用户区块链上发生的事情。
在我们的例子中,“外部用户”是我们的前端应用程序,它将监听发送到智能合约的新消息,因此我们可以立即在我们的UI中显示它们。
前端
我准备了一个样板,这样你就可以马上开始编码了。
以下是启动项目的Github链接:
https://github.com/thmsgbrt/web3-chat-powered-by-ethereum-starter
一旦你克隆了项目,使用npm install安装依赖项,并用npm start启动了它,那么花几分钟检查几个文件以了解应用是如何构造的,也是有必要的。这是非常基本的React,就不在此赘述了。
以下是我们的行动计划:
A-允许用户通过MetaMask连接到聊天
B-在我们的前端实例化智能合约
C-从我们的智能合约中获取消息并显示它们
D-允许用户在聊天中发布消息
E-收听新信息
A - 允许用户通过MetaMask连接到聊天
要做到这一点,我们首先需要确保MetaMask扩展安装在了浏览器上。
让我们创建一个Hook来实现这一点:
const useIsMetaMaskInstalled = () => {
const { ethereum } = window;
return Boolean(ethereum && ethereum.isMetaMask);
};
export default useIsMetaMaskInstalled;
./src/useIsMetaMaskInstalled.ts
解释:
MetaMask在window.ethereum注入了一个全局API。该API允许网站请求用户的以太坊账户,从用户连接的区块链读取数据,并建议用户签署消息和交易。
现在我们已经准备好了Hook,转向Sidebar.tsx,这样我们就可以利用它:
import React from "react";
import useIsMetaMaskInstalled from "../useIsMetaMaskInstalled";
interface Props {
setAccount: React.Dispatch<React.SetStateAction<string | undefined>>;
account?: string;
}
const Sidebar = ({ setAccount, account }: Props) => {
// Use our hook here
const isMetaMaskInstalled = useIsMetaMaskInstalled();
return (
<div className="sidebar">
{account && (
<>
<b>Connected as:</b>
<br />
<small>{account}</small>
</>
)}
{!account && (
<button disabled={!isMetaMaskInstalled}>Connect With MetaMask</button>
)}
{!isMetaMaskInstalled && <p>Please install MetaMask</p>}
</div>
);
};
export default Sidebar;
./src/components/Sidebar.tsx
以现在,我们有一种方法来检测是否安装了MetaMask,如果没有安装MetaMask,我们可以警告用户,他们需要在浏览器上安装MetaMask。
接下来,让我们为“Connect With MetaMask”按钮添加一个onClick处理程序:
import React from "react";
import { ethers } from "ethers";
import useIsMetaMaskInstalled from "../useIsMetaMaskInstalled";
interface Props {
setAccount: React.Dispatch<React.SetStateAction<string | undefined>>;
account?: string;
}
const Sidebar = ({ setAcc