hardhat&react本地调试智能合约

本教程供 Web3 初学者使用,将演示如何使用 hardhat 创建一个简单的智能合约,并部署到本地,使用 react 调用测试。

创建智能合约

首先创建一个空文件夹helloWeb3 来存放本次演示项目

mkdir helloWeb3 && cd helloWeb3

接下来初始化项目

npm init -y
yarn add hardhat

初始化 hardhat 项目(根据自己的需求选择对应的选项,本次演示一路回车选择默认)

npx hardhat

安装依赖

yarn add @nomicfoundation/hardhat-toolbox
yarn add "@ethersproject/providers@^5.4.7" "@nomicfoundation/hardhat-network-helpers@^1.0.0" "@nomicfoundation/hardhat-chai-matchers@^1.0.0" "@nomiclabs/hardhat-ethers@^2.0.0" "@nomiclabs/hardhat-etherscan@^3.0.0" "@types/chai@^4.2.0" "@types/mocha@>=9.1.0" "@typechain/ethers-v5@^10.1.0" "@typechain/hardhat@^6.1.2" "chai@^4.2.0" "ethers@^5.4.7" "hardhat-gas-reporter@^1.0.8" "solidity-coverage@^0.8.1" "ts-node@>=8.0.0" "typechain@^8.1.0" "typescript@>=4.5.0"

编写简单智能合约(Hello World)

编写代码之前,我们先了解一下 hardhat 的目录结构

contracts 用于存放我们的智能合约源文件.sol
    --Lock.sol
node_modules 存放项目依赖
    --
scripts 存放脚本文件
    --deploy.js 默认的部署脚本
test 合约测试文件
    --Lock.js
.gitignore
hardhat.config.js hardhat配置文件
package.json

我们进入 contracts 文件夹,新建一个 Hello.sol 文件并写入以下代码开始我们入门之旅

// SPDX-License-Identifier: MIT

pragma solidity 0.8.17;

contract Hello {
    string public message = "Hello Web3";
}

上面代码中我们初始化了一个智能合约文件,并声明了一个变量 message 赋值为 ”Hello Web3“

本地部署智能合约

Ganache 是一个可以运行在本地的个人区块链,使用它可以让我们很方便地部署调试智能合约。

npm i -g ganache-cli

启动 ganache

ganache-cli

做好以上准备,我们就可以开始部署我们的智能合约了,首先要修改一下项目中默认的部署脚本 scripts/deploy.js

const hre = require("hardhat");

async function main() {
  const Hello = await hre.ethers.getContractFactory("Hello");
  const hello = await Hello.deploy();

  await hello.deployed();

  console.log(`合约部署完成,地址为:${hello.address}`);
}

// We recommend this pattern to be able to use async/await everywhere
// and properly handle errors.
main().catch((error) => {
  console.error(error);
  process.exitCode = 1;
});

运行部署脚本

npx hardhat run --network localhost scripts/deploy.js

运行完以上脚本可以看到控制台输出如下

合约部署完成,地址为:0x93337cB92F377693d9C9790751d6a8f4E55f3751

并且生成了一个 artifacts 文件夹,里面是我们合约的 ABI 文件,待会我们使用 react 调用合约的时候会用到

创建 react 项目

到这里我们已经完成了简单的智能合约编写,并且已经部署到本地了。接下来我们尝试使用 react 调用我们刚刚部署的智能合约。

使用 vite 快速创建 react项目,可以按照自己的需求选择,本教程选择 react + typescript

yarn create vite web
cd web && yarn
yarn add ethers

artifacts 文件夹下的 Hello.json 复制到 web 下的 src/assets 目录下,修改 App.tsx 文件

import { useEffect, useState } from "react";
import { ethers } from "ethers";

// 之前生成的 ABI 文件
import helloContract from "./assets/Hello.json"; 

// 之前获取的合约部署地址
const CONTRACTADDRESS = "0x93337cB92F377693d9C9790751d6a8f4E55f3751"; 

export default function App() {
  const [message, setMessage] = useState("");

  const init = async () => {
    const provider = new ethers.providers.Web3Provider(window.ethereum);
    const signer = provider.getSigner();

    const contract = new ethers.Contract(
      CONTRACTADDRESS,
      helloContract.abi,
      signer
    );

    try {
      const res = await contract.message();
      setMessage(res);
    } catch (err) {
      console.log(err);
    }
  };

  useEffect(() => {
    init();
  }, []);

  return <>{message}</>;
}

编写以上代码的过程中可能遇到语法警告

const provider = new ethers.providers.Web3Provider(window.ethereum);

Property 'ethereum' does not exist on type 'Window & typeof globalThis'

解决方法是在 src 下新建 types/index.d.ts 文件写入以下代码

import { MetaMaskInpageProvider } from "@metamask/providers";

declare global {
  interface Window {
    ethereum?: MetaMaskInpageProvider;
  }
}

运行测试

yarn dev

在浏览器中打开 http://127.0.0.1:5173/,我们就可以在浏览器中看到 Hello Web3,这说明我们的 react 应用已经成功地调用了智能合约并获取到了 message 变量的值。

本文链接:

https://www.55geek.cn/index.php/archives/133/
1 + 3 =
快来做第一个评论的人吧~