Hardhat 环境搭建及教程示例
一.安装node.js
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash
nvm install 18
nvm use 18
nvm alias default 18
npm install npm --global # Upgrade npm to the latest version
二. 安装hardhat
2.1 创建hardhat安装目录
mkdir hardhat
cd hardhat
2.2 安装hardhat
npm install --save-dev hardhat
ls
# 安装后的目录
# node_modules package-lock.json package.json
2.3 在安装hardhat的目录下运行hardhat
npx hardhat
选择创建hardhat配置文件
2.4 hardhat架构
Hardhat是围绕**task(任务)和plugins(插件)**的概念设计的。 **Hardhat **的大部分功能来自插件,作为开发人员,你可以自由选择你要使用的插件。
2.5 Task(任务)
每次你从CLI运行Hardhat时,你都在运行任务。 例如 npx hardhat compile正在运行compile任务。 要查看项目中当前可用的任务,运行npx hardhat。 通过运行npx hardhat help [task],可以探索任何任务。
2.6 Plugins(插件)
Hardhat 不限制选择哪种工具,但是它确实内置了一些插件,所有这些也都可以覆盖。 大多数时候,使用给定工具的方法是将其集成到Hardhat中作为插件。
在本教程中,我们将使用hardhat-toolbox插件。 通过他们与以太坊进行交互并测试合约。 稍后将解释它们的用法。 要安装它们,请在项目目录中运行:
npm install --save-dev @nomicfoundation/hardhat-toolbox
在hardhar.config.js文件中添加下面的代码
require("@nomicfoundation/hardhat-toolbox");/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {solidity: "0.8.18",
};
三. 编写、编译、测试、调试智能合约
3.1 写一个简单的智能合约
在hardhat目录下创建一个新的目录
mkdir contracts
cd contracts
添加Token.sol智能合约
//SPDX-License-Identifier: UNLICENSED// Solidity files have to start with this pragma.
// It will be used by the Solidity compiler to validate its version.
pragma solidity ^0.8.9;// This is the main building block for smart contracts.
contract Token {// Some string type variables to identify the token.string public name = "My Hardhat Token";string public symbol = "MHT";// The fixed amount of tokens, stored in an unsigned integer type variable.uint256 public totalSupply = 1000000;// An address type variable is used to store ethereum accounts.address public owner;// A mapping is a key/value map. Here we store each account's balance.mapping(address => uint256) balances;// The Transfer event helps off-chain applications understand// what happens within your contract.event Transfer(address indexed _from, address indexed _to, uint256 _value);/*** Contract initialization.*/constructor() {// The totalSupply is assigned to the transaction sender, which is the// account that is deploying the contract.balances[msg.sender] = totalSupply;owner = msg.sender;}/*** A function to transfer tokens.** The `external` modifier makes a function *only* callable from *outside** the contract.*/function transfer(address to, uint256 amount) external {// Check if the transaction sender has enough tokens.// If `require`'s first argument evaluates to `false` then the// transaction will revert.require(balances[msg.sender] >= amount, "Not enough tokens");// Transfer the amount.balances[msg.sender] -= amount;balances[to] += amount;// Notify off-chain applications of the transfer.emit Transfer(msg.sender, to, amount);}/*** Read only function to retrieve the token balance of a given account.** The `view` modifier indicates that it doesn't modify the contract's* state, which allows us to call it without executing a transaction.*/function balanceOf(address account) external view returns (uint256) {return balances[account];}
}
3.2 编译
npx hardhat compile
3.3 测试
创建test文件夹,创建测试文件Token.js
mkdir test
cd test
const { expect } = require("chai");describe("Token contract", function () {it("Deployment should assign the total supply of tokens to the owner", async function () {const [owner] = await ethers.getSigners();const Token = await ethers.getContractFactory("Token");const hardhatToken = await Token.deploy();const ownerBalance = await hardhatToken.balanceOf(owner.address);expect(await hardhatToken.totalSupply()).to.equal(ownerBalance);});
});
运行test命令
npx hardhat test
3.4 调试智能合约
Hardhat内置了Hardhat Network ,这是一个专为开发而设计的以太坊网络。 它允许你部署合约,运行测试和调试代码。 这是Hardhat所连接的默认网络,因此你无需进行任何设置即可工作。 你只需运行测试就好。
Solidity 中使用 console.log
在Hardhat Network上运行合约和测试时,你可以在Solidity代码中调用console.log()打印日志信息和合约变量。 你必须先从合约代码中导入**Hardhat **的console.log再使用它。
修改只能合约
pragma solidity ^0.8.9;import "hardhat/console.sol";contract Token {//...
}
function transfer(address to, uint256 amount) external {require(balances[msg.sender] >= amount, "Not enough tokens");console.log("Transferring from %s to %s %s tokens",msg.sender,to,amount);balances[msg.sender] -= amount;balances[to] += amount;emit Transfer(msg.sender, to, amount);
}
修改测试文件
// This is an example test file. Hardhat will run every *.js file in `test/`,
// so feel free to add new ones.// Hardhat tests are normally written with Mocha and Chai.// We import Chai to use its asserting functions here.
const { expect } = require("chai");// We use `loadFixture` to share common setups (or fixtures) between tests.
// Using this simplifies your tests and makes them run faster, by taking
// advantage of Hardhat Network's snapshot functionality.
const { loadFixture } = require("@nomicfoundation/hardhat-network-helpers");// `describe` is a Mocha function that allows you to organize your tests.
// Having your tests organized makes debugging them easier. All Mocha
// functions are available in the global scope.
//
// `describe` receives the name of a section of your test suite, and a
// callback. The callback must define the tests of that section. This callback
// can't be an async function.
describe("Token contract", function () {// We define a fixture to reuse the same setup in every test. We use// loadFixture to run this setup once, snapshot that state, and reset Hardhat// Network to that snapshot in every test.async function deployTokenFixture() {// Get the ContractFactory and Signers here.const Token = await ethers.getContractFactory("Token");const [owner, addr1, addr2] = await ethers.getSigners();// To deploy our contract, we just have to call Token.deploy() and await// its deployed() method, which happens once its transaction has been// mined.const hardhatToken = await Token.deploy();await hardhatToken.deployed();// Fixtures can return anything you consider useful for your testsreturn { Token, hardhatToken, owner, addr1, addr2 };}// You can nest describe calls to create subsections.describe("Deployment", function () {// `it` is another Mocha function. This is the one you use to define each// of your tests. It receives the test name, and a callback function.//// If the callback function is async, Mocha will `await` it.it("Should set the right owner", async function () {// We use loadFixture to setup our environment, and then assert that// things went wellconst { hardhatToken, owner } = await loadFixture(deployTokenFixture);// `expect` receives a value and wraps it in an assertion object. These// objects have a lot of utility methods to assert values.// This test expects the owner variable stored in the contract to be// equal to our Signer's owner.expect(await hardhatToken.owner()).to.equal(owner.address);});it("Should assign the total supply of tokens to the owner", async function () {const { hardhatToken, owner } = await loadFixture(deployTokenFixture);const ownerBalance = await hardhatToken.balanceOf(owner.address);expect(await hardhatToken.totalSupply()).to.equal(ownerBalance);});});describe("Transactions", function () {it("Should transfer tokens between accounts", async function () {const { hardhatToken, owner, addr1, addr2 } = await loadFixture(deployTokenFixture);// Transfer 50 tokens from owner to addr1await expect(hardhatToken.transfer(addr1.address, 50)).to.changeTokenBalances(hardhatToken, [owner, addr1], [-50, 50]);// Transfer 50 tokens from addr1 to addr2// We use .connect(signer) to send a transaction from another accountawait expect(hardhatToken.connect(addr1).transfer(addr2.address, 50)).to.changeTokenBalances(hardhatToken, [addr1, addr2], [-50, 50]);});it("Should emit Transfer events", async function () {const { hardhatToken, owner, addr1, addr2 } = await loadFixture(deployTokenFixture);// Transfer 50 tokens from owner to addr1await expect(hardhatToken.transfer(addr1.address, 50)).to.emit(hardhatToken, "Transfer").withArgs(owner.address, addr1.address, 50);// Transfer 50 tokens from addr1 to addr2// We use .connect(signer) to send a transaction from another accountawait expect(hardhatToken.connect(addr1).transfer(addr2.address, 50)).to.emit(hardhatToken, "Transfer").withArgs(addr1.address, addr2.address, 50);});it("Should fail if sender doesn't have enough tokens", async function () {const { hardhatToken, owner, addr1 } = await loadFixture(deployTokenFixture);const initialOwnerBalance = await hardhatToken.balanceOf(owner.address);// Try to send 1 token from addr1 (0 tokens) to owner.// `require` will evaluate false and revert the transaction.await expect(hardhatToken.connect(addr1).transfer(owner.address, 1)).to.be.revertedWith("Not enough tokens");// Owner balance shouldn't have changed.expect(await hardhatToken.balanceOf(owner.address)).to.equal(initialOwnerBalance);});});
});
运行测试
npx hardhat test
看到输出了log
四. 部署合约到网络
4.1 创建scripts文件夹,添加deploy.js文件
async function main() {const [deployer] = await ethers.getSigners();console.log("Deploying contracts with the account:", deployer.address);console.log("Account balance:", (await deployer.getBalance()).toString());const Token = await ethers.getContractFactory("Token");const token = await Token.deploy();console.log("Token address:", token.address);
}main().then(() => process.exit(0)).catch((error) => {console.error(error);process.exit(1);});
4.2 发布到hardhat自己的网络实例
npx hardhat run scripts/deploy.js
Deploying contracts with the account: 0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266
Account balance: 10000000000000000000000
Token address: 0x5FbDB2315678afecb367f032d93F642f64180aa3
4.3 发布到Ganache网络
修改配置文件hardhat.config.js
require("@nomicfoundation/hardhat-toolbox");/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {solidity: "0.8.18",networks: {deployment: {url: `http://127.0.0.1:7545`,accounts: ["bc549ba74b85bf9cc89309fc094cd868ff39215570b64271e19be9c1977df279"]}}
};
npx hardhat run scripts/deploy.js --network deployment
Deploying contracts with the account: 0xEb110D13835ff1e9B65320682601634D041dD505
Account balance: 98996267410475486878
Token address: 0x3f4f9B074bfd9B0C4920FD28b374e2B8E7B618f4
看到Ganache已经有记录
4.4 发布到sepolia测试网
修改配置文件hardhat.config.js
require("@nomicfoundation/hardhat-toolbox");// Go to https://infura.io, sign up, create a new API key
// in its dashboard, and replace "KEY" with it
const INFURA_API_KEY = "KEY";// Replace this private key with your Sepolia account private key
// To export your private key from Metamask, open Metamask and
// go to Account Details > Export Private Key
// Beware: NEVER put real Ether into testing accounts
const SEPOLIA_PRIVATE_KEY = "YOUR SEPOLIA PRIVATE KEY";module.exports = {solidity: "0.8.9",networks: {sepolia: {url: `https://sepolia.infura.io/v3/${INFURA_API_KEY}`,accounts: [SEPOLIA_PRIVATE_KEY]}}
};
npx hardhat run scripts/deploy.js --network sepolia
这个我没有试,有兴趣的可以试一下
参考文档:
hardhat官网教程
[译] Hardhat 入门教程 | 登链社区 | 区块链技术社区
相关文章:

Hardhat 环境搭建及教程示例
一.安装node.js curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.1/install.sh | bash nvm install 18 nvm use 18 nvm alias default 18 npm install npm --global # Upgrade npm to the latest version 二. 安装hardhat 2.1 创建hardhat安装目录 mkdir hard…...

复杂链表的复制-剑指Offer35-java
一、题目描述 请实现 copyRandomList 函数,复制一个复杂链表。在复杂链表中,每个节点除了有一个 next 指针指向下一个节点,还有一个 random 指针指向链表中的任意节点或者 null。 示例 1: 输入:head [[7,null],[13,…...

【Linux】进程理解与学习Ⅰ-进程概念
环境:centos7.6,腾讯云服务器Linux文章都放在了专栏:【Linux】欢迎支持订阅🌹相关文章推荐:【Linux】冯.诺依曼体系结构与操作系统进程概念什么是进程?进程是什么?我们打开任务管理器可以看到有…...

WebKitX ActiveX 6.0 X86 Crack
WebKitX ActiveX将 Chromium Embedded Framework (CEF3) 包装到一个进程外的 ActiveX 组件中,以便与 OLE/COM 语言一起使用。Chromium Embedded Framework 封装了 WebKit Blink HTML5 Renderer 和 Google V8 JavaScript Engine。这是一个用于商业用途的生产级稳定组…...

开源项目:数据库表结构生成文档工具
目录 一、软件介绍 二、技术框架 三、功能介绍 四、代码展示 1、获取数据库信息部分代码 2、导出Html文档代码 五、运行效果 六、项目开源地址 一、软件介绍 今天给大家分享我自己编写的数据库表结构文档生成工具,方便大家在实际开发当中,可以很方便导出…...

spring的两种拦截器HandlerIntercepter和MethodIntercepter
介绍 Spring有两种拦截器提供给我们使用,一种是HandlerIntercepter,另一种是MethodIntercepter。这两种的来源不同,实现方式也不同,具体的下面来看一下。 HandlerIntercepter 来源 来源于spring-webmvc包 HandlerIntercepter拦…...

初级算法-字符串
主要记录算法和数据结构学习笔记,新的一年更上一层楼! 初级算法-字符串一、反转字符串二、反转字符串(二)三、替换空格四、翻转字符串里的单词五、左旋转字符串六、实现 strStr()七、重复的子字符串字符串中元素只能是字符String…...

华为OD机试题 - 寻找目标字符串(JavaScript)| 机考必刷
更多题库,搜索引擎搜 梦想橡皮擦华为OD 👑👑👑 更多华为OD题库,搜 梦想橡皮擦 华为OD 👑👑👑 更多华为机考题库,搜 梦想橡皮擦华为OD 👑👑👑 最近更新的博客 华为od 2023 | 什么是华为od,od 薪资待遇,od机试题清单华为OD机试真题大全,用 Python 解华为…...

删除Terminating状态的namespace:cattle-system
这里以cattle-system为例!执行删除命令后namespace(也是用其他k8s object)仍然存在,首先执行 kubectl edit namespace cattle-system 查看是否存在spec.finalizers: kubernetes,如: spec: finalizers:…...

MiniOB 并发B+树实现解析
MiniOB 是 OceanBase 联合华中科技大学推出的一款用于教学的小型数据库系统,希望能够帮助数据库爱好者系统性的学习数据库原理与实战。 B 树介绍 B 树是传统数据库中常见的索引数据结构,比如MySQL、PostgreSQL都实现了B树索引。B 树是一个平衡多叉树&am…...

SpringCloud负载均衡服务调用——Ribbon
Ribbon 本专栏学习内容来自尚硅谷周阳老师的视频 有兴趣的小伙伴可以点击视频地址观看 简介 Spring Cloud Ribbon是基于Netflix Ribbon实现的一套客户端负载均衡的工具。 简单的说,Ribbon是Netflix发布的开源项目,主要功能是提供客户端的软件负载均衡算…...

各种邮箱服务软件对比
1.宝塔邮局管理器 特点:简单易用,可视化操作,小白也能搞,还有备份功能,一般足够用了 缺点:稳定性真是差,隔三差五的不能收发.没有接口,不能任意修改邮箱密码,只能管理员修改 注意要点:一定要开启ssl,否则有些邮箱给你发邮件你收不到 建议:不要入坑.坏了之后没法修复,哭都没地方…...

相机单独标定的实现过程[autoware标定]、tmp文件的查看方式
安装了autoware1.13和calibration标定包,发现实现相机单独标定的过程较为坎坷,参考了一些博主的方法,发现下面的过程更加适合自己,做个笔记。 1安装标定箱(与calibration标定包的安装并不冲突) 标定工具箱…...

4.10.1、IP 多播技术的相关基本概念
多播(Multicast,也称为组播)是一种实现 “一对多” 通信的技术,与传统单播“一对一”通信相比,多播可以极大地节省网络资源。 在因特网上进行的多播,称为 IP 多播。 1、单播 & 多播 如下所示…...

PIGOSS BSM监控国产数据库Oscar
前言神通数据库(原OSCAR数据库)是天津神舟通用数据技术有限公司(简称“神舟通用公司”)拥有自主知识产权的企业级、大型通用关系型数据库管理系统。PIGOSS BSM作为网利友联科技完全自主研发的纯国产基础 IT 架构运行状态监测平台软件…...

Spring Boot中文件上传
Spring Boot中文件上传 前言 本篇主要参考Spring官方文档,整理了Spring Boot中文件上传如何实现,以及在代码中使用RestTemplate和HttpClient两种方式实现文件上传。 创建Spring Boot项目 首先创建一个Spring Boot Web项目,使用的Spring B…...

Github上传大文件(>25MB)教程
Github上传大文件(>25MB)教程Github上传大文件(>25MB)教程安装git安装Git Large File Storage实例踩坑点1:failed to push some refs to踩坑点2:main与master踩坑点3:Failed to connect t…...

面试官:mysql索引会缓存内存吗?
文章目录 InnoDB缓冲池如何设置方法一:使用 `innodb_buffer_pool_size` 变量方法二:修改my.ini配置文件InnoDB缓冲池 InnoDB存储引擎是基于磁盘存储表文件和索引的,并将数据按页的方式管理,由于访问磁盘的速度较慢,多次访问磁盘会造成数据库性能的下降,为此,InnoDB在内…...

bs4解析数据和csv文件
\b 检测所在的位置是否是单词边界(任何可以将不同的单词进行区分的符号:空白符号,标点符号,字符串开头,字符串结尾) ^ 检测是否是字符串开头 $ 检测是否是字符串结尾 csv保存数据 什么是csv文件 读操作…...

Linux中Buffer和Cache的区别
Linux中Buffer和Cache的区别 free命令中会有一项buff/cache, 通过man free可以看到这里的关于buff/cache的介绍 buff/cache包含两部分 buffers:内核缓存区用到的内存,对应/proc/meminfo中Buffers的值 cache:内核页缓存和Slab用到的内存,对应/proc/mem…...

Docker 镜像使用
目录 1、列出镜像列表 2、获取一个新的镜像 3、查找镜像 4、拖取镜像 5、删除镜像 6、创建镜像 a.更新镜像 b.构建镜像 设置镜像标签 当运行容器时,使用的镜像如果在本地中不存在,docker 就会自动从 docker 镜像仓库中下载,默认是从 …...

Java阶段一Day10
Java阶段一Day10 文章目录Java阶段一Day10抽象类和抽象方法接口案例小练习引用类型数组教师总结回顾:精华笔记:笔记:补充:抽象类和抽象方法 关键字:abstract 只有方法的定义,没有具体的实现(连…...

触摸屏与PLC之间如何快速实现无线PPI通信?
PPI协议是西门子为S7-200专门开发的通信协议,是不开放的协议,CPU自带的两个通信口(Port0,Port1)均支持该协议,S7-200的一些通信模块也支持PPI协议。编程软件Micro/WIN与CPU进行编程通信也使用PPI协议&#…...

【华为OD机试 2023最新 】 羊、狼、农夫过河(C++ 100%)
题目描述 羊、狼、农夫都在岸边,当羊的数量小于狼的数量时,狼会攻击羊,农夫则会损失羊。农夫有一艘容量固定的船,能够承载固定数量的动物。 要求求出不损失羊情况下将全部羊和狼运到对岸需要的最小次数。 只计算农夫去对岸的次数,回程时农夫不会运送羊和狼。 备注:农…...

Java中关于try、catch、finally中的细节分析
本文讲解的是关于Java中关于try、catch、finally中一些问题 下面看一个例子(例1),来讲解java里面中try、catch、finally的处理流程 public class TryCatchFinally {SuppressWarnings("finally")public static final String test(…...

Zookeeper原理
一、概念 Zookeeper是一个开源的、分布式的,为分布式应用提供协调服务的Apache项目。封装好复杂易出错的关键服务,将简单易用的接口和性能高效、功能稳定的系统提供给用户。 二、选举机制 首先是几个概念: myid:节点的唯一标识&…...

关于FPGA如何快速生成模块的例化模板(实用)
关于FPGA如何快速生成模块的例化模板(实用) 语言 :Verilg HDL 、VHDL EDA工具:ISE、Vivado、Quartus II 关于FPGA如何快速生成模块的例化模板(实用)一、引言二、快速生成例化模块的几种方法1. IP核的例化模…...

在 Python 中将字符串转换为集合
使用 set() 类将字符串转换为集合,例如 my_set set(my_str)。 set() 类将通过拆分其字符将字符串转换为集合。 my_str one# ✅ 通过拆分字符将字符串转换为集合 my_set set(my_str) print(my_set) # 👉️ {n, o, e}# -----------------------------…...

大数据Flink进阶(十三):Flink 任务提交模式
文章目录 Flink 任务提交模式 一、会话模式(Session Mode) 二、单作业模式(Per-Job Mode) 三、应用模式(Application Mode) Flink 任务提交模式 Flink分布式计算框架可以基于多种模式部署,…...

day11—编程题
文章目录1.第一题1.1题目1.2涉及的相关知识1.3思路1.4解题2.第二题2.1题目2.2思路2.3解题1.第一题 1.1题目 描述: 将一棵无穷大满二叉树的结点按根结点一层一层地从左往右编号,根结点编号为1。现给定a,b为两个结点。设计一个算法࿰…...