"工欲善其事,必先利其器",在正式开发Solidity智能合约之前,我们先熟悉了解一下几个常用的开发IDE, 本篇主要介绍Hardhat 。你可以把 Hardhat 理解为以太坊(区块链)开发的 "瑞士军刀"或一体化开发环境,它帮你处理了从编写、编译、测试到部署智能合约的所有繁琐工作。
核心概念:为什么选择 Hardhat?
在 Hardhat 出现之前,开发者需要手动组合多个工具。Hardhat 将它们整合在一起,并带来了两大核心优势:
-
内置的本地开发网络(Hardhat Network):在本地内存中模拟一个真实的以太坊区块链,交易秒级确认,无需消耗真实的测试币,极速调试。
-
强大的智能合约测试框架:使用你熟悉的 JavaScript/TypeScript 和成熟的测试库(如 Mocha, Waffle)来编写自动化测试,这是开发可靠合约的生命线。
第一步:环境搭建与项目初始化
让我们从零开始创建一个 Hardhat 项目。
1. 安装 Node.js 和 npm
Hardhat 基于 Node.js,请确保已安装 Node.js(建议使用 LTS 版本)。安装后,在终端运行以下命令验证:
bash
bash
node --version
npm --version
2. 初始化一个新的 Hardhat 项目
打开终端,进入你准备存放代码的目录,然后执行:
bash
mkdir my-hardhat-project
cd my-hardhat-project
npm init -y
npm install --save-dev hardhat
3. 启动 Hardhat 并选择项目模板
安装后,运行:
bash
npx hardhat init
你将看到一个交互式菜单。对于初学者,强烈建议选择 "Create a JavaScript project"(或 TypeScript,如果你熟悉它)。这个选项会为你创建一个结构清晰、包含示例合约和测试的完整项目。
项目结构一览
初始化完成后,你会看到类似以下的目录结构,这是理解 Hardhat 项目的基础:
XML
my-hardhat-project/
├── contracts/ # 存放你的 Solidity 智能合约源代码 (.sol 文件)
│ └── Lock.sol # Hardhat 生成的示例合约
├── scripts/ # 存放部署脚本或其他辅助脚本 (.js 文件)
│ └── deploy.js # 用于将合约部署到网络的脚本示例
├── test/ # 存放你的测试文件 (.js 文件)
│ └── Lock.js # 针对 Lock.sol 的测试示例
├── hardhat.config.js # Hardhat 的核心配置文件(网络、插件等均在此设置)
└── package.json # Node.js 项目标准文件,记录依赖和脚本
第二步:编写你的第一个智能合约
现在,我们来创建一个简单的合约。在 contracts/ 目录下新建一个文件 Greeter.sol:
javascript
// SPDX-License-Identifier: MIT
// 第一行指定源代码许可证,几乎所有开源项目都会包含
pragma solidity ^0.8.19; // 声明编译器版本
// 定义一个名为 Greeter 的合约
contract Greeter {
// 状态变量:将被永久存储在链上
string private greeting;
// 构造函数:仅在部署合约时执行一次
constructor(string memory _initialGreeting) {
greeting = _initialGreeting;
}
// 公共视图函数:读取状态变量,不消耗Gas
function greet() public view returns (string memory) {
return greeting;
}
// 公共函数:修改状态变量,需要消耗Gas并发送交易
function setGreeting(string memory _newGreeting) public {
greeting = _newGreeting;
}
}
这是一个经典入门合约,功能是存储和更新一条问候语。
第三步:编译与测试
1. 编译合约
在项目根目录运行以下命令。Hardhat 会自动读取 contracts/ 下的所有文件,并使用你在 hardhat.config.js 中指定的 Solidity 编译器版本进行编译。
bash
npx hardhat compile
编译成功后,会生成一个 artifacts/ 目录,里面包含合约的字节码(Bytecode) 和应用二进制接口(ABI),这是与合约交互的必要信息。
2. 运行测试
打开 test/ 目录下的 Lock.js 示例,看看测试是如何编写的。然后,我们为 Greeter 合约创建一个简单的测试。在 test/ 目录下新建 Greeter.js:
javascript
const { expect } = require("chai");
const { ethers } = require("hardhat");
describe("Greeter Contract", function () {
it("Should return the initial greeting", async function () {
// 1. 获取合约工厂(用于部署合约的抽象)
const Greeter = await ethers.getContractFactory("Greeter");
// 2. 部署合约,并传入构造函数的参数
const greeter = await Greeter.deploy("Hello, Hardhat!");
await greeter.deployed(); // 等待部署完成
// 3. 调用合约的 view/pure 函数进行断言
expect(await greeter.greet()).to.equal("Hello, Hardhat!");
});
it("Should change the greeting", async function () {
const Greeter = await ethers.getContractFactory("Greeter");
const greeter = await Greeter.deploy("Hello, Hardhat!");
await greeter.deployed();
// 4. 发送一个交易来改变状态(setGreeting)
const setTx = await greeter.setGreeting("Hola, Mundo!");
await setTx.wait(); // 等待交易上链
// 5. 验证状态是否被正确修改
expect(await greeter.greet()).to.equal("Hola, Mundo!");
});
});
运行测试:
bash
npx hardhat test
Hardhat 会自动启动其内置网络,运行测试,并给出清晰的结果反馈。通过测试是保证合约逻辑正确的关键步骤。
第四步:核心配置文件(hardhat.config.js)
这个文件是项目的控制中心。一个基本配置如下:
javascript
require("@nomicfoundation/hardhat-toolbox");
/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {
// 指定 Solidity 编译器版本
solidity: "0.8.19",
networks: {
// 内置的本地开发网络配置(默认已有,无需修改)
hardhat: {
chainId: 31337
},
// 你可以在这里添加其他网络,例如 Sepolia 测试网
sepolia: {
url: "YOUR_ALCHEMY_OR_INFURA_URL", // 节点提供商URL
accounts: [`0x${YOUR_PRIVATE_KEY}`] // 私钥数组(注意保密!)
}
},
// 路径配置(通常默认即可)
paths: {
sources: "./contracts",
tests: "./test",
cache: "./cache",
artifacts: "./artifacts"
}
};
下一步该做什么?
恭喜你完成了第一个 Hardhat 项目!为了真正掌握它,建议你按以下顺序深入:
-
深入学习 Solidity :理解更多语言特性,如映射、结构体、事件、错误处理以及最重要的安全模式(如重入攻击防范)。
-
探索脚本部署 :研究
scripts/deploy.js,学习如何将合约部署到真实的测试网(如 Sepolia)。 -
与前端集成 :学习如何使用 ethers.js 或 web3.js 库,在网页前端与已部署的合约进行交互。
-
使用验证插件 :使用
@nomicfoundation/hardhat-verify插件在 Etherscan 上验证你的合约源代码,这对建立用户信任至关重要。