一颗比特币都要上 10 万美金了,你还不会 Web3 开发?我来教你,10 分钟包会

1,021 阅读7分钟

话不多说,直接开始开发。按照我的步骤来,快速认知 Web3 DApp 前端开发。会一边引导你开发,一边介绍 Web3 的知识。 🏃

课程使用 umiAnt Design,都是大家熟悉的配方。另外还有一个我们迭代了一年的库 Ant Design Web3 可以快速搭建一个 DApp。

太长不看版本:Ant Design Web3 提供了一些列组件帮你快速开发 DApp,100 行代码就完成了 NFT 的 mint 和显示,可以先 Star https://github.com/ant-design/ant-design-web3

第一步:初始化脚手架

直接参考 umi 官方的文档初始化一个 umi 的脚手架,在任意位置执行下面命令就可以:

npx create-umi@latest

速度不行的同学可以设置下国内镜像,运行下 npm config set registry https://registry.npmmirror.com就行。

image.png

你可以输入一个你喜欢的文件夹名字,我这里输入了 antd-web3-umi-demo,然后选择 Simple App

包管理工具可以按照你自己的喜好选择,我选了 npm,接下来就等代码初始化完成:

image.png

你会得到这样的代码:

image.png

初始化完成后会自动帮你安装好,然后执行 npm run dev就可以启动了,效果如下:

image.png

第二步:支持连接 Web3 钱包

Web3 应用相比 Web2 应用最大的差异就是 Web3 应用的核心数据是在区块链上的,核心逻辑是在区块链上的智能合约中运行的。前端不再调用后端,而是调用智能合约接口。

那如何调用智能合约接口呢?智能合约的权限不再通过中心化的服务端保证,而是通过密码学保证。所以需要我们的 APP 先连接上用户的加密钱包,钱包里面保存的用户的私钥。APP 连接钱包后就可以请求钱包对请求消息做签名,签名之后的消息发送到链上就可以调用智能合约完成加密货币转账等功能了。

这一步就需要 Ant Design 和 Ant Design Web3 了,我们先安装这两个库和它们的一些 peerDependencies:

npm install antd @ant-design/web3 @ant-design/web3-wagmi wagmi viem @tanstack/react-query --save

然后参考 Ant Design Web3 连接以太坊的 Demo web3.ant.design/components/… 把整个代码复制过去替换掉原来的 src/pages/index.tsx中的内容(需要注意的是代码里面 walletConnect相关那几行行需要删掉,这个是支持手机钱包扫码连接的,需要申请一个 id 才能用,我们先去掉),你可以直接复制下面这段我已经处理好的代码:

import { ConnectButton, Connector } from "@ant-design/web3";
import {
  Mainnet,
  MetaMask,
  OkxWallet,
  TokenPocket,
  WagmiWeb3ConfigProvider,
} from "@ant-design/web3-wagmi";
import { QueryClient } from "@tanstack/react-query";
import { http } from "wagmi";

const queryClient = new QueryClient();

const App: React.FC = () => {
  return (
    <WagmiWeb3ConfigProvider
      eip6963={{
        autoAddInjectedWallets: true,
      }}
      ens
      chains={[Mainnet]}
      transports={{
        [Mainnet.id]: http(),
      }}
      wallets={[
        MetaMask(),
        TokenPocket({
          group: "Popular",
        }),
        OkxWallet(),
      ]}
      queryClient={queryClient}
    >
      <Connector
        modalProps={{
          mode: "simple",
        }}
      >
        <ConnectButton quickConnect />
      </Connector>
    </WagmiWeb3ConfigProvider>
  );
};

export default App;
    

保存后再打开页面看你就好了,页面中出现了一个按钮,点击之后就可以唤起用户钱包请求连接了:

image.png

Ant Design Web3 会自动识别用户安装了哪些钱包,可以选择自己需要的钱包连接。

什么?你还没有钱包?那你看到的就是这样:

image.png

你可以点击后出现弹窗,然后选一个钱包点击进去(比如我们选 TokenPocket 或者 OKX,都是华人团队做的钱包,体验很不错,当然 MetaMask 和其它安全靠谱的钱包都可以):

image.png

然后选择它的 Chrome 插件版本钱包安装:

image.png

安装好之后按照它的提示创建一个钱包(记得如果后面要用这个钱包的话请备份好助记词或者私钥)。

然后你再回到我们的 DApp 你就可以连接你自己的钱包了。

第三步:试试调用合约,理解 DApp 的逻辑

最后,我们试一试调用合约。当然,调用合约是需要付款加密货币的(充当交易费用,也就是 Web3 说的 GAS),不过有测试网可以使用。

测试网的代币也不是默认就有的,我们需要借助 Web3 的一些水龙头服务来获取测试用的代币。

比如大家可以访问 ZAN 的水龙头服务 zan.top/cn/faucet,ZAN 的水龙头服务对新人比较友好,全新的啥都没有的钱包都可以领取测试网代币。

image.png

输入你的钱包地址后点击领取就可以领取 0.01 个测试网的 ETH 了。

然后我们修改我们的代码,添加测试网 Sepolia(我们顺便添加一下 balance 配置,看看我们领取的测试代币是否到账,当然你钱包里面也可以看到):

import { ConnectButton, Connector } from "@ant-design/web3";
import {
  Mainnet,
+  Sepolia,
  MetaMask,
  OkxWallet,
  TokenPocket,
  WagmiWeb3ConfigProvider,
} from "@ant-design/web3-wagmi";
import { QueryClient } from "@tanstack/react-query";
import { http } from "wagmi";

const queryClient = new QueryClient();

const App: React.FC = () => {
  return (
    <WagmiWeb3ConfigProvider
      eip6963={{
        autoAddInjectedWallets: true,
      }}
      ens
-      chains={[Sepolia]}
+      chains={[Mainnet, Sepolia]}
+     balance
      transports={{
        [Mainnet.id]: http(),
+       [Sepolia.id]: http(),
      }}
      wallets={[
        MetaMask(),
        TokenPocket({
          group: "Popular",
        }),
        OkxWallet(),
      ]}
      queryClient={queryClient}
    >
      <Connector
        modalProps={{
          mode: "simple",
        }}
      >
        <ConnectButton quickConnect />
      </Connector>
    </WagmiWeb3ConfigProvider>
  );
};

export default App;

你会看到这样的结果(记得切换到 Sepolia 测试网):

image.png

接下来让我们新建一个 CallTest组件,放一个按钮,点击后调用 sepolia.etherscan.io/address/0x4… 这个测试网合约的 awardItem 方法,获得一个 NFT。

完整的代码如下,你可以直接复制,主要就是使用了 wagmi 这个 react hooks 库的 useWriteContract Hook:

import { ConnectButton, Connector, useAccount } from "@ant-design/web3";
import {
  Mainnet,
  Sepolia,
  MetaMask,
  OkxWallet,
  TokenPocket,
  WagmiWeb3ConfigProvider,
} from "@ant-design/web3-wagmi";
import { QueryClient } from "@tanstack/react-query";
import { http, useWriteContract } from "wagmi";
import { Button, message } from "antd";

const queryClient = new QueryClient();

const CallTest = () => {
  const { writeContract } = useWriteContract();
  const { account } = useAccount();

  return (
    <Button
      onClick={() => {
        writeContract(
          {
            abi: [
              {
                type: "function",
                name: "awardItem",
                inputs: [
                  { internalType: "address", name: "player", type: "address" },
                  { internalType: "string", name: "tokenURI", type: "string" },
                ],
                outputs: [
                  { internalType: "uint256", name: "", type: "uint256" },
                ],
              },
            ],
            address: "0x46371b97f1f67b4851f3103a131dc3f690cbf7cd",
            functionName: "awardItem",
            args: [
              account.address,
              "https://api.our-metaverse.xyz/api/meta/42",
            ],
          },
          {
            onError: (err) => {
              message.error(err.message);
            },
          }
        );
      }}
    >
      mint
    </Button>
  );
};

const App: React.FC = () => {
  return (
    <WagmiWeb3ConfigProvider
      eip6963={{
        autoAddInjectedWallets: true,
      }}
      ens
      chains={[Mainnet, Sepolia]}
      balance
      transports={{
        [Mainnet.id]: http(),
        [Sepolia.id]: http(),
      }}
      wallets={[
        MetaMask(),
        TokenPocket({
          group: "Popular",
        }),
        OkxWallet(),
      ]}
      queryClient={queryClient}
    >
      <Connector
        modalProps={{
          mode: "simple",
        }}
      >
        <ConnectButton quickConnect />
      </Connector>
      <CallTest />
    </WagmiWeb3ConfigProvider>
  );
};

export default App;

点击 mint 按钮,会唤起钱包发起交易:

image.png

点击确认就可以了,接下来你可以在 sepolia.etherscan.io/address/0x4… 区块链浏览器上查看交易是否成功:

image.png

你可以点击具体的交易中查看你获得的 NFT 的 ID:

接下来我们把这个 NFT 通过 Ant Design Web3 的 NFTCard 组件显示出来:

    <NFTCard
      address="0x46371b97f1f67b4851f3103a131dc3f690cbf7cd"
      tokenId={1}
      />

最后你会看到这样的效果:

image.png

图片描述等信息都是我们在 Mint NFT 的时候传入的,内容就在调用合约方法是传入的 api.our-metaverse.xyz/api/meta/42 这个 JSON 里面。

至此,我们就完成了前端所有的代码开发,完整的代码在 github.com/yutingzhao1…

如果你感觉这篇文章对你有帮助,请给我们来个 Star 吧! https://github.com/ant-design/ant-design-web3 感谢支持开源! ❤️

扩展学习:开发部署一个 NFT 合约

在上面,我们用一个已经部署好的合约来调用。那能不能自己部署一个合约呢?这样就变成全栈开发了!

当然可以,而且很简单。

首先,我们使用 chainide.com/zh-CN/ 这个在线的 IDE 来开发和部署合约。

进去直接点快速开始(你可以用你的 Github 账号登录),然后点新建项目,直接选 ERC721 的模板:

image.png

ERC721 是以太坊的一个规范,符合这个规范就是一个 NFT 合约。

新建好之后会得到下面这样的合约,你可以啥都不用改,也可以像我这样改一下名字:

image.png

然后编译合约,右上角点击编译菜单,选择一个 0.8+ 的 solidity 合约编译器版本,点击编译:

image.png

成功后会看到编译后的结果,ABI 是合约接口描述文件,BYTE CODE 就是编译后的内容:

image.png

然后就是部署,我们把合约部署到测试网上试一试,部署前需要连接钱包:

image.png

连接后部署合约:

image.png

我这里用的是 OKX 的钱包,大家可以用自己的钱包,但是要注意选择正确的测试网络,不要不小心花费了主网的 ETH。

image.png

部署成功后会看到相关信息,比如我这里就是在 sepolia.etherscan.io/tx/0xb0a090… 这个交易中部署成功了,然后可以拿到一个新的合约地址:

image.png 这个地址替换掉上面的对应的地址就可以啦!恭喜你完成了完整的 DApp 入门开发!可以去投简历了哈哈。🚀