web3实战工程 - hardhat框架

news/2025/9/28 12:57:48/文章来源:https://www.cnblogs.com/lxjshuju/p/19116450

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、目标?
    • 步骤总览
    • 环境准备(本地)
    • 初始化项目 & 依赖
  • 二、编写智能合约
  • 测试你的合约
    • Solidity 测试
    • TypeScript 测试
  • 编写脚本与网络交互
  • 部署合约
  • 总结


在这里插入图片描述

前言

我把 从零到可运行的 ERC-721 收藏品 + 简单固定价市场(marketplace) 的完整「一步一步」实操指南(含可复制的命令与示例代码)。适合初学者用 Hardhat + OpenZeppelin + ethers.js 在 Sepolia 测试网 上练手(因为 Goerli 已逐步退役,建议用 Sepolia)。


提示:以下是本篇文章正文内容,下面案例可供参考

一、目标?

用 OpenZeppelin 实现一个简单的 ERC-721 收藏品合约(可 mint 带 metadata 的 NFT),再做一个简单的固定价 marketplace 合约(list / buy / cancel / withdraw),并演示如何在 Sepolia 上部署和用前端或脚本交互。

步骤总览

  1. 环境准备(Node、Hardhat、MetaMask、RPC),node建议最新版本22的版本
  2. 新建 Hardhat 项目并安装依赖
  3. 写 ERC-721 合约(MyCollectible)
  4. 写简单 Marketplace 合约(NftMarketplace,使用 pull payments &
    ReentrancyGuard)
  5. 编写部署脚本并在本地 / Sepolia 部署
  6. 测试:mint → approve → list → buy → withdraw(示例脚本 + 前端调用)
  7. 注意事项(metadata 存储、审计、生产上要改的点)

环境准备(本地)

初始化项目 & 依赖

执行如下命令

mkdir nft-marketplace
cd nft-marketplace
npm init -y
npm install --save-dev hardhat
npx hardhat --init

出现如下界面说明安装成功
在这里插入图片描述
我们在选择的时候会遇到一个选项

? What type of project would you like to initialize?
❯ A TypeScript Hardhat project using Node Test Runner and Viem
A TypeScript Hardhat project using Mocha and Ethers.js
  1. Node Test Runner + Viem
    ·· Node.js 新的测试运行器(而不是 Mocha)。
    ··交互库是 Viem(替代 Ethers.js,API 不同,学习成本更高)。
  2. Mocha + Ethers.js
    ··使用经典的 Mocha 测试框架。
    –使用 Ethers.js,几乎所有教程(包括我给你写的脚本)都是基于 Ethers.js。
    建议选择:Node Test Runner + Viem
    生成完成后可以看到
contracts/
scripts/
test/
hardhat.config.ts

在这里插入图片描述

二、编写智能合约

使用 Hardhat 编写智能合约非常简单,只需在contracts目录中编写一个 Solidity 文件即可。例如,您的contracts/Counter.sol代码如下所示:

pragma solidity ^0.8.28;
contract Counter {
uint public x;
event Increment(uint by);
function inc() public {
x++;
emit Increment(1);
}
function incBy(uint by) public {
require(by > 0, "incBy: increment should be positive");
x += by;
emit Increment(by);
}
}

Hardhat 会自动检测它,并根据其pragma声明和你的 Hardhat 配置,使用正确版本的 Solidity 进行编译。你只需运行以下命令:

npx hardhat build

在这里插入图片描述

测试你的合约

测试是任何以太坊项目的关键部分。Hardhat 允许您使用Solidity和TypeScript编写测试,让您可以灵活地根据具体情况选择合适的工具。

安全帽测试针对本地内存区块链运行,这比使用真实网络快得多,并且不需要您花费 ETH 或获取测试网络代币。

Solidity 测试

Hardhat 3 完全支持编写 Solidity 测试。示例项目包含一个 Solidity 测试文件,位于contracts/Counter.t.sol:

import { Counter } from "./Counter.sol";
import { Test } from "forge-std/Test.sol";
contract CounterTest is Test {
Counter counter;
function setUp() public {
counter = new Counter();
}
function test_InitialValue() public view {
require(counter.x() == 0, "Initial value should be 0");
}
function testFuzz_Inc(uint8 x) public {
for (uint8 i = 0; i < x; i++) {
counter.inc();
}
require(counter.x() == x, "Value after calling inc x times should be x");
}
function test_IncByZero() public {
vm.expectRevert();
counter.incBy(0);
}
}

执行下面的命令可以测试所有的合约

npx hardhat test

如果您只想运行 Solidity 测试,则可以使用以下命令:

npx hardhat test solidity

当您运行此命令时,Hardhat 将:

  1. 编译您的合同和测试。
  2. 收集所有测试文件。包括目录.t.sol中的所有文件contracts/以及目录.sol中的所有文件test/。
  3. 部署这些文件中定义的每个测试合同。
  4. 调用每个以 开头的函数test。如果任何调用被撤销,则相应的测试将被标记为失败。

在上面的例子中:

  • test_InitialValue是单元测试:它们不带参数,并且每次测试执行时运行一次test_IncByZero。
  • testFuzz_Inc是一个模糊测试:由于它接受一个参数,Hardhat
    会使用随机输入多次运行它。如果任何一次运行失败,则模糊测试失败,并打印失败的输入。
  • 如果您的任何测试失败,Hardhat 将提供详细的Solidity
    堆栈跟踪,以帮助您了解原因。要查看它们的实际效果,请首先注释掉vm.expectRevert();以下行test_IncByZero:
function test_IncByZero() public {
// vm.expectRevert();
counter.incBy(0);
}
Failure (1): test_IncByZero()
Reason: revert: incBy: increment should be positive
at Counter.incBy (contracts/Counter.sol:15)
at CounterTest.test_IncByZero (contracts/Counter.t.sol:30)

TypeScript 测试

Solidity 测试非常适合快速、集中的单元测试,但在某些情况下却存在不足:

  • 复杂的测试逻辑,其中像 TypeScript 这样的通用语言比 Solidity 更具表现力和人体工程学。
  • 需要真实区块链行为的测试,例如区块推进或 Gas
    成本计算。虽然作弊码可以在一定程度上模拟这些行为,但过度模拟难以维护,并且可能导致不准确的假设。
  • 端到端场景,您希望测试您的合同在生产中的行为,涉及多个交易、客户端和用户交互。

为了支持这些用例,Hardhat 允许您使用 TypeScript(或 JavaScript)编写测试,使用
Node.js 测试运行器
或其他框架,例如
摩卡
这些测试在真实的 Node.js 环境中运行,并通过 JSON-RPC 与您的合约进行交互,使其更能代表实际使用情况。
示例项目附带一个 TypeScript 测试文件,位于test/Counter.ts,其中包含以下测试:

it("The sum of the Increment events should match the current value", async function () {
const counter = await viem.deployContract("Counter");
// run a series of increments
for (let i = 1n; i <= 10n; i++) {
await counter.write.incBy([i]);
}
const events = await publicClient.getContractEvents({
address: counter.address,
abi: counter.abi,
eventName: "Increment",
fromBlock: 0n,
strict: true,
});
// check that the aggregated events match the current value
let total = 0n;
for (const event of events) {
total += event.args.by;
}
assert.equal(total, await counter.read.x());
});

该测试部署Counter合约,incBy多次调用(每次在单独的交易中),收集所有发出的Increment事件,并验证它们的总和是否与合约的最终价值相匹配。

用 Solidity 编写同样的测试也是可行的,但不太方便,而且测试会在不同的上下文中执行——更接近于单个交易多次调用合约,而不是不同用户随时间推移与其交互。这使得 TypeScript 更适合那些依赖于实际交易流程或区块链行为的场景。

要运行 TypeScript 测试,请使用以下test nodejs任务:

npx hardhat test nodejs

编写脚本与网络交互

Hardhat 中的脚本只是一个 TypeScript 或 JavaScript 文件,可以访问您的合约、配置以及 Hardhat 提供的任何其他功能。您可以使用它们来运行自定义逻辑或自动化工作流程。

按照惯例,脚本位于scripts/目录中。您可以随意命名它们,并使用.ts或.js扩展名。

示例项目包含两个脚本。其中一个脚本scripts/send-op-tx.ts展示了如何模拟本地类似 Optimism 的网络并在其上发送交易。

要运行脚本,您可以使用以下run任务:

npx hardhat run scripts/send-op-tx.ts

部署合约

示例项目附带我们的官方部署解决方案:Hardhat Ignition,一个用于部署智能合约的声明式系统。

使用 Hardhat Ignition,您可以定义要部署的智能合约实例以及要对其执行的任何操作。这些定义被分组到 Ignition 模块中,然后以最高效的方式进行分析和执行。这包括并行发送独立交易、从错误中恢复以及恢复中断的部署。

Ignition 模块位于ignition/modules/目录中。这是示例模块ignition/modules/Counter.ts:

import { buildModule } from "@nomicfoundation/hardhat-ignition/modules";
export default buildModule("CounterModule", (m) => {
const counter = m.contract("Counter");
m.call(counter, "incBy", [5n]);
return { counter };
});
npx hardhat ignition deploy ignition/modules/Counter.ts

总结

本文介绍了如何从零开始开发一个ERC-721 NFT收藏品合约和简单的固定价市场(marketplace),并部署到Sepolia测试网。主要内容包括:环境准备(Node.js、Hardhat、MetaMask)、项目初始化、编写ERC-721合约和Marketplace合约、部署流程、测试方法(Solidity和TypeScript测试)以及交互演示。文章提供了详细的步骤指南和代码示例,适合初学者学习使用Hardhat、OpenZeppelin和ethers.js进行区块链开发。特别强调了测试的重要性,并比较了Solidity测试和TypeScript测试的不同适用场景。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/920664.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

重组蛋白表达中包涵体的形成与优化策略

重组蛋白表达中包涵体的形成与优化策略 重组蛋白广泛应用于基础研究、生物制药和工业酶制剂等领域。大肠杆菌(Escherichia coli)因生长快、操作简便、成本低、表达量高,长期作为主要的重组蛋白宿主。然而高水平表达…

【MySQL】性能优化与核心机制深度解析 - 详解

【MySQL】性能优化与核心机制深度解析 - 详解pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", &qu…

程序员究竟要不要写文章

写在前面 时光飞逝,一晃已经从业七年有余,若从接触编程的时间算起,恐怕还要再加个四五年,可以堂而皇之地自称为拥有十多年的编程经验了,哈哈。 一路上,经常会有人问我,我们为什么要写文章甚至博客,有什么意义吗…

B4375 [蓝桥杯青少年组省赛 2025] 庆典队列B4376 [蓝桥杯青少年组省赛 2025] 茶具套装B4377 [蓝桥杯青少年组省赛 2025] 平衡奇偶位置的字符交换

好久不见,最近参加了蓝桥的省赛,虽然只是省二,但是还是要总结一下 今儿个三合一,前三道 1.B4375 [蓝桥杯青少年组省赛 2025] 庆典队列 题目描述 有 \(n\) 名志愿者参加了一场庆典活动,我们希望将这些人排成一个矩…

2025 年纽扣电池厂家:力源电池以 TWS 适配技术与定制服务,打造多场景电源解决方案

在 5G 技术全面普及与智能穿戴设备市场爆发的双重驱动下,纽扣电池市场需求持续攀升,2024 年全球市场规模已达 49.58 亿美元,预计 2025 年将保持 6.3% 的复合增长率。其中 TWS 耳机作为核心应用场景占比达 18%,对电…

web3hardhat 框架实战-ERC20 - 指南

web3hardhat 框架实战-ERC20 - 指南2025-09-28 12:46 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !imp…

网站开发人员定罪案例汽车网站建设公司哪家好

如果网站跑在了LAMP环境中&#xff0c;就无法使用php-fpm的slow log了&#xff0c;那如何分析瓶颈点&#xff1f;没关系你还可以使用这个XdebugWebgrind&#xff0c;其中Xdebug是一个开放源代码的PHP程序调试器(即一个Debug工具)&#xff0c;可以用来跟踪&#xff0c;调试和分析…

网站建设与管理报告市场运营和市场营销的区别

声明:该专栏涉及的所有案例均为学习使用,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关!如有侵权,请私信联系本人删帖! 文章目录 一、前言二、网站分析1.X-S-HEADER参数2.请求参数data3.响应机密值data一、前言 网址: aHR0cHM6Ly93d3cubGFnb3UuY29t…

网站访问工具wordpress文章模块化插件

在网络通信中&#xff0c;密钥的安全分发和公钥的有效认证是确保系统安全的关键。本文将为基础小白介绍密钥分发与公钥认证的基本概念和实际应用&#xff0c;帮助大家更好地理解这些技术如何保障我们的网络通信安全。 1. 密钥分发与公钥认证的背景 由于密码算法是公开的&…

wordpress中怎么排序上饶网站优化

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

crewCTF 2025 -- WASM Vault

从 js 中看出,先把输入的 flag 存到 wasm 的内存为 0 的位置,然后调用 vault.wasm 导出的 unlock() 函数判断 这里用开源项目 wabt 把 wasm 转成 c 文件,再用 gcc 编译成二进制文件,这样就可以拖到 ida 里分析了 w…

东莞做网站的模块网站怎么做

1 非静态代码块非静态代码块特点①可以为实例变量(非静态的属性)初始化②每次创建对象的时候&#xff0c;都会执行一次&#xff0c;且先于构造器执行③若有多个非静态的代码块&#xff0c;那么按照定义的顺序从上到下依次执行④代码块中既可以调用非静态的变量和方法&#xff0…

神经网络常见的40多种激活函数(应用场景+数学公式+代码实现+函数图象)

长文预警:经典的、大模型用的、探索研究的,这里都有什么是激活函数 激活函数,属于神经网络中的概念。 激活函数,就像神经元的开关,决定了输入信号能否被传递,以及以什么形式传递。 为应对不同的场景,激活函数不…

oppo-r9m线刷刷机教程

前言全局说明oppo-r9m线刷刷机教程一、说明 1.1 环境: Windows 7 旗舰版二、刷机首次刷机,电脑需要安装驱动2.1 打开刷机工具 找到”刷机工具.exe”双击打开如下图 (如果工具打不开以管理员身份运行打开。)2.2 手机…

【DateTime】日期时间:时间处理的基础

【DateTime】日期时间:时间处理的基础教学说明:本篇因 DateTime 数据类型需要,将提前使用 Get-Date 函数。该函数会在后续 “初级篇” 中详细讲解,此处仅用于演示 DateTime 类型的基本操作。 在编程中,日期时间(…

网站建设行业新闻南宁网站建设推广服务

(2011-10-08 17:08:43) 转载▼标签&#xff1a; 杂谈 分类&#xff1a; Javatry{//代码区}catch(Exception e){//异常处理}代码区如果有错误&#xff0c;就会返回所写异常的处理。 首先要清楚&#xff0c;如果没有try的话&#xff0c;出现异常会导致程序崩溃。而try则可以保证…

地图制作网站小程序定制开发和模板有什么区别

大家好&#xff0c;我是写代码的篮球。计算机专业的小伙伴&#xff0c;在学校期间一定学过 C 语言。它是众多高级语言的鼻祖&#xff0c;深入学习这门语言会对计算机原理、操作系统、内存管理等等底层相关的知识会有更深入的了解&#xff0c;所以我在直播的时候&#xff0c;多次…

完整教程:蒸汽机革命后工业生产方式的变革与AI智能名片S2B2C商城小程序的影响

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

2025 PHP7/8 实战入门:15 天精通现代 Web 制作——第 15 课:项目实战与部署

2025 PHP7/8 实战入门:15 天精通现代 Web 制作——第 15 课:项目实战与部署pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-fam…

做网站怎么投放广告企业网站加快企业信息化建设

xcopy XCOPY是COPY的扩展&#xff0c;可以把指定的目录连文件和目录结构一并拷贝&#xff0c;但不能拷贝系统文件&#xff1b;使用时源盘符、源目标路径名、源文件名至少指定一个&#xff1b;选用/S时对源目录下及其子目录下的所有文件进行COPY。除非指定/E参数&#xff0c;否则…