web3 第八章 (hardhat 本地开发和调试)

907 阅读3分钟

本地开发和调试合约

  • 如何本地开发和调试合约,以及编写单元测试来验证智能合约的逻辑。

初始化项目

使用 hardhat 搭建本地开发环境,本地运行合约。

参考 hardhat getting started 初始化项目


pnpx hardhat init

image.png

这里选择了 TypeScript + View

初始化后得到一个这样目录的项目

image.png

  • contracts: 存放 Solidity 合约代码
  • test: 测试代码
  • ignition: 合约部署脚本, 比如定义合约部署的参数
  • hardhat.config.ts: Hardhat 配置文件

本地开发和调试

编译合约

npx hardhat compile

image.png

编译后的资源在 artifacts 目录下

image.png

执行测试样例

npx hardhat test

image.png

本地启动一个用于调试的测试网络

npx hardhat node

image.png

接下来将合约部署到本地节点上

npx hardhat ignition deploy ./ignition/modules/Lock.ts --network localhost

部署成功后,可以在本地的测试网络日志中看到相关的交易信息。

image.png

部署 NFT 合约

复制之前的 NFT 合约 MyToken.sol 放到 contracts 目录下, 删除原有的 Lock.sol 示例代码。 合约中依赖了 @openzeppelin/contracts。 安装依赖

pnpm add @openzeppelin/contracts -S

部署合约到

npx hardhat ignition deploy ./ignition/modules/MyToken.ts --network localhost

部署之后复制,部署后合约的地址

image.png

在代码中添加 Hardhat 网络

- import { mainnet, goerli, polygon } from "wagmi/chains";
+ import { mainnet, goerli, polygon, hardhat } from "wagmi/chains";
import {
  WagmiWeb3ConfigProvider,
  MetaMask,
  Goerli,
  Polygon,
+  Hardhat,
  WalletConnect,
} from "@ant-design/web3-wagmi";

// ...

const config = createConfig({
-  chains: [mainnet, goerli, polygon],
+  chains: [mainnet, goerli, polygon, hardhat],
  transports: {
    [mainnet.id]: http(),
    [goerli.id]: http(),
    [polygon.id]: http(),
+    [hardhat.id]: http("http://127.0.0.1:8545/"),
  },
  connectors: [
    injected({
      target: "metaMask",
    }),
    walletConnect({
      projectId: "c07c0051c2055890eade3556618e38a6",
      showQrModal: false,
    }),
  ],
});

const contractInfo = [
  {
    id: 1,
    name: "Ethereum",
    contractAddress: "0xe7f1725E7734CE288F8367e1Bb143E90bb3F0512",
  },
  {
    id: 5,
    name: "Goerli",
    contractAddress: "0x418325c3979b7f8a17678ec2463a74355bdbe72c",
  },
  {
    id: 137,
    name: "Polygon",
    contractAddress: "0x418325c3979b7f8a17678ec2463a74355bdbe72c",
  },
+  {
+    id: hardhat.id,
+    name: "Hardhat",
+    contractAddress: "0x5FbDB2315678afecb367f032d93F642f64180aa3", // 这里需要替换为你本地部署后获得的地址
+  },
];

// ...

export default function Web3() {
  return (
    <WagmiWeb3ConfigProvider
      config={config}
      wallets={[MetaMask(), WalletConnect()]}
      eip6963={{
        autoAddInjectedWallets: true,
      }}
      chains={[
        Goerli,
        Polygon,
+       Hardhat,
      ]}
    >
      <Address format address="0xEcd0D12E21805803f70de03B72B1C162dB0898d9" />
      <NFTCard
        address="0xEcd0D12E21805803f70de03B72B1C162dB0898d9"
        tokenId={641}
      />
      <Connector>
        <ConnectButton />
      </Connector>
      <CallTest />
    </WagmiWeb3ConfigProvider>
  );
}

对应的在 MetaMask 中添加该网络。具体操作可以查看 Web3 第二章(Dapp 转账功能)

然后打开本地启动的前端页面,切换网络到 Hardhat,就可以愉快的 Mint NFT 了。

image.png

如果 MetaMask 连接本地 RPC 是出现类似 Received invalid block tag 1. Latest block number is 0 这样的错误,你需要在 MetaMask 的账号高级设置中点击 清除活动和 nonce 数据 来修复该问题。