当前位置: 首页 > news >正文

hardhat部署智能合约

Hardhat安装

安装node

可以使用 nvm 安装node

GitHub - nvm-sh/nvm: Node Version Manager - POSIX-compliant bash script to manage multiple active node.js versions

安装Hardhat

打开命令行工具,输入:

mkdir hardhat-demo
cd hardhat-demo
npm init -y
npm install --save-dev hardhat

创建Hardhat项目

打开命令行工具,输入:

cd hardhat-demo
npx hardhat

选择第三项:创建空白项目配置 Create an empty hardhat.config.js

Welcome to Hardhat v2.22.2? What do you want to do? ...
> Create a JavaScript projectCreate a TypeScript projectCreate a TypeScript project (with Viem)Create an empty hardhat.config.jsQuit

安装插件

npm install --save-dev @nomicfoundation/hardhat-toolbox

将插件添加到你的hardhat配置文件中 hardhat.config.js

require("@nomicfoundation/hardhat-toolbox");/** @type import('hardhat/config').HardhatUserConfig */
module.exports = {solidity: "0.8.21",
};

编写并编译合约

如果你用过remix,那么你直接在remix上点击保存的时候,会自动帮你编译的。但是在本地的hardhat开发环境中,你需要手动编译合约。

新建合约目录

新建contracts合约目录,并添加第31章节的ERC20合约。

编写合约

这里的合约直接使用[WTF Solidity第31讲](https://github.com/AmazingAng/WTF-Solidity/blob/main/31_ERC20/readme.md]的ERC20合约

// SPDX-License-Identifier: MIT
// WTF Solidity by 0xAApragma solidity ^0.8.21;import "./IERC20.sol";contract ERC20 is IERC20 {mapping(address => uint256) public override balanceOf;mapping(address => mapping(address => uint256)) public override allowance;uint256 public override totalSupply;   // 代币总供给string public name;   // 名称string public symbol;  // 符号uint8 public decimals = 18; // 小数位数// @dev 在合约部署的时候实现合约名称和符号constructor(string memory name_, string memory symbol_){name = name_;symbol = symbol_;}// @dev 实现`transfer`函数,代币转账逻辑function transfer(address recipient, uint amount) external override returns (bool) {balanceOf[msg.sender] -= amount;balanceOf[recipient] += amount;emit Transfer(msg.sender, recipient, amount);return true;}// @dev 实现 `approve` 函数, 代币授权逻辑function approve(address spender, uint amount) external override returns (bool) {allowance[msg.sender][spender] = amount;emit Approval(msg.sender, spender, amount);return true;}// @dev 实现`transferFrom`函数,代币授权转账逻辑function transferFrom(address sender,address recipient,uint amount) external override returns (bool) {allowance[sender][msg.sender] -= amount;balanceOf[sender] -= amount;balanceOf[recipient] += amount;emit Transfer(sender, recipient, amount);return true;}// @dev 铸造代币,从 `0` 地址转账给 调用者地址function mint(uint amount) external {balanceOf[msg.sender] += amount;totalSupply += amount;emit Transfer(address(0), msg.sender, amount);}// @dev 销毁代币,从 调用者地址 转账给  `0` 地址function burn(uint amount) external {balanceOf[msg.sender] -= amount;totalSupply -= amount;emit Transfer(msg.sender, address(0), amount);}}

编译合约

npx hardhat compile

看到如下输出,说明合约编译成功:

Compiling 2 Solidity files successfully

成功后,你会在文件夹下看到artifacts目录,里面的json文件就是编译结果。

编写单元测试

这里的单元测试非常简单,仅包含部署合约并测试合约地址是否合法(是否部署成功)。

新建测试文件夹test,在其中新建test.js。单元测试中,我们会用到chaiethers.js两个库,分别用于测试和链上交互。对ethers.js不了解的开发者,可以看下WTF Ethers极简教程的前6讲。我们之后的教程会更详细的介绍chaimocha

const { expect } = require('chai');
const { ethers } = require('hardhat');describe("ERC20 合约测试", ()=>{it("合约部署", async () => {// ethers.getSigners,代表eth账号  ethers 是一个全局函数,可以直接调用const [owner, addr1, addr2] = await ethers.getSigners();// ethers.js 中的 ContractFactory 是用于部署新智能合约的抽象,因此这里的 ERC20 是我们代币合约实例的工厂。ERC20代表contracts 文件夹中的 ERC20.sol 文件const Token = await ethers.getContractFactory("ERC20");// 部署合约, 传入参数 ERC20.sol 中的构造函数参数分别是 name, symbol 这里我们都叫做WTFconst hardhatToken = await Token.deploy("WTF", "WTF"); await hardhatToken.waitForDeployment();// 获取合约地址const ContractAddress = await hardhatToken.target;expect(ContractAddress).to.properAddress;});
})

运行测试

在命令行输入以下内容运行测试:

npx hardhat test
# 如果有多个文件想跑指定文件可以使用
npx mocha test/test.js

看到如下输出,说明测试成功。

  ERC20 合约测试✔ 合约部署 (1648ms)1 passing (2s)

部署合约

在remix中,我们只需要点击一下deploy就可以部署合约了,但是在本地hardhat中,我们需要编写一个部署脚本。

新建一个scripts文件夹,我们来编写部署合约脚本。并在该目录下新建一个deploy.js

输入以下代码

// 我们可以通过 npx hardhat run <script> 来运行想要的脚本
// 这里你可以使用 npx hardhat run deploy.js 来运行
const hre = require("hardhat");async function main() {const Contract = await hre.ethers.getContractFactory("ERC20");const token = await Contract.deploy("WTF","WTF");await token.waitForDeployment();console.log("成功部署合约:", token.target);
}// 运行脚本
main().catch((error) => {console.error(error);process.exitCode = 1;
});

运行以下代码部署合约到本地测试网络

hardhat会提供一个默认的网络,参考:hardhat默认网络

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

看到如下输出,说明合约部署成功:

(node:45779) ExperimentalWarning: stream/web is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
成功部署合约: 0x5FbDB2315678afecb367f032d93F642f64180aa3

部署合约到Goerli测试网络 | 网络配置

前期准备

  1. 申请alchemy的api key 参考【第4讲:Alchemy, 区块链API和节点基础设施】
  2. 申请Goerli测试代币 点击申请 登录alchemy账号每天可以领取0.2个代币
  3. 导出私钥 因为需要把合约部署到Goerli测试网络,所以该测试账号中留有一定的测试代币。导出已有测试代币的账户的私钥,用于部署合约
  4. 申请 etherscan 的 api key,用于验证合约 点击申请

配置网络

hardhat.config.js中,我们可以配置多个网络,这里我们配置Goerli测试网络。

编辑 hardhat.config.js

require("@nomicfoundation/hardhat-toolbox");// 申请alchemy的api key
const ALCHEMY_API_KEY = "KEY";//将此私钥替换为测试账号私钥
//从Metamask导出您的私钥,打开Metamask和进入“帐户详细信息”>导出私钥
//注意:永远不要把真正的以太放入测试帐户
const GOERLI_PRIVATE_KEY = "YOUR GOERLI PRIVATE KEY";// 申请etherscan的api key
const ETHERSCAN_API_KEY = "YOUR_ETHERSCAN_API_KEY";module.exports = {solidity: "0.8.21", // solidity的编译版本networks: {goerli: {url: `https://eth-goerli.alchemyapi.io/v2/${ALCHEMY_API_KEY}`,accounts: [GOERLI_PRIVATE_KEY]}},etherscan: {apiKey: ETHERSCAN_API_KEY,},
};

配置完成运行

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

你就可以把你的合约部署到Goerli测试网络了。

看到如下信息,你就成功部署到Goerli测试网络了。

(node:46996) ExperimentalWarning: stream/web is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
(node:46999) ExperimentalWarning: stream/web is an experimental feature. This feature could change at any time
(Use `node --trace-warnings ...` to show where the warning was created)
成功部署合约: 0xeEAcef71084Dd1Ae542***9D8F64E3c68e15****

可以通过etherscan查看合约部署情况

同理你也可以配置多个网络,比如mainnetrinkeby等。

最后验证你的合约:

npx hardhat verify --network goerli DEPLOYED_CONTRACT_ADDRESS "Constructor argument 1"

总结

这一讲,我们介绍了Hardhat基础用法。通过Hardhat我们能够工程化solidity的项目,并提供了很多有用的脚手架。在后续的文章中,我们会介绍更多的Hardhat的高级用法,例如使用Hardhat的插件、测试框架等等。

相关文章:

hardhat部署智能合约

Hardhat安装 安装node 可以使用 nvm 安装node GitHub - nvm-sh/nvm: Node Version Manager - POSIX-compliant bash script to manage multiple active node.js versions 安装Hardhat 打开命令行工具&#xff0c;输入&#xff1a; mkdir hardhat-demo cd hardhat-demo npm i…...

界面控件DevExtreme中文教程 - 如何与Amazon S3和Azure Blob存储集成?

DevExtreme拥有高性能的HTML5 / JavaScript小部件集合&#xff0c;使您可以利用现代Web开发堆栈&#xff08;包括React&#xff0c;Angular&#xff0c;ASP.NET Core&#xff0c;jQuery&#xff0c;Knockout等&#xff09;构建交互式的Web应用程序。从Angular和Reac&#xff0c…...

【ERROR】ubuntu source: not found

Ubuntu 24.04.1 LTS系统设置环境变量&#xff0c;执行 source ~/.bashrc出现错误&#xff1a; source command not found 解决方案&#xff1a;不需要处理( echo 以下你的环境变量&#xff0c;发现是生效的)&#xff0c;ubantu系统 中 /bin/sh 通常链接到 dash&#xff0c;这…...

聚焦IOC容器刷新环节postProcessBeanFactory(BeanFactory后置处理)专项

目录 一、IOC容器的刷新环节快速回顾 二、postProcessBeanFactory源码展示分析 &#xff08;一&#xff09;模版方法postProcessBeanFactory &#xff08;二&#xff09;AnnotationConfigServletWebServerApplicationContext 调用父类的 postProcessBeanFactory 包扫描 …...

配置nginx服务通过ip访问多网站

过程概要 1.前提配置 关防火墙 关selinux 2.安装web服务程序nginx 3.查看nginx是否开启 4.为当前主机添加多地址&#xff08;ip a&#xff09; 5.自定义nginx配置文件通过多地址区分多网站 /etc/nginx/conf.d/test_ip.conf server { #标记为一个虚拟主机 } 6.根据配置…...

银河麒麟V10设置QT开发程序开机自启动

1、切换root用户: su root 2、进入/etc/xdg/autostart目录&#xff1a; cd /etc/xdg/autostart 3、创建一个test.desktop文件&#xff0c;文件名不一定命名为test&#xff0c;可以自己随意命名&#xff1a; touch test.desktop 4、完善test.desktop文件内容&#xff1a; …...

RabbitMQ高级特性详解

前言 RabbitMQ是一款广泛使用的开源消息队列软件&#xff0c;它基于AMQP&#xff08;Advanced Message Queuing Protocol&#xff09;标准实现。本文将带你深入了解RabbitMQ的一些高级特性&#xff0c;包括消息确认、死信队列、延迟队列、事务处理以及消息分发策略等&#xff…...

提升泛化能力的前沿方法:多任务学习在机器学习中的应用与实践

提升泛化能力的前沿方法&#xff1a;多任务学习在机器学习中的应用与实践 &#x1f4cb; 目录 &#x1f9e9; 多任务学习的概念与动机&#x1f310; 多任务学习在自然语言处理中的应用案例&#x1f5bc;️ 多任务学习在计算机视觉中的应用案例⚙️ 项目实践&#xff1a;实现多…...

【小白学机器学习16】 概率论的世界观2

目录 一 从正态分布说起 1.1 正态分布是自然分布&#xff0c;是客观 1.2 万物不齐 1.3 中庸 1.4 动态平衡 正态分布&#xff0c;概率论都是一种世界观 一 从正态分布说起 1.1 正态分布是自然分布&#xff0c;是客观 世界是客观的&#xff0c;是不以人们的意志想法为转…...

洛谷 P9868 [NOIP2023] 词典

好久不写博客了&#xff0c;今天来水一篇 原题链接 初看此题在洛谷上的定位是黄题&#xff0c;实际上也并不是很简单。 其实主要就用到了贪心的思想&#xff0c;先说一下我在做题的时候是怎么想的吧。 先看了部分分&#xff0c;10分是很好拿的&#xff0c;再就分析题意&…...

跨浏览器免费书签管理系统

随着互联网信息的爆炸式增长&#xff0c;如何有效管理我们日常浏览中发现的重要网页&#xff0c;成为了每个重度互联网用户的需求。一个跨平台的书签管理网站能够帮助用户在不同设备之间无缝同步和管理书签。本文将分享如何使用 Python 和 SQLite 构建一个简单、易于维护的跨平…...

导出Excel的常用方法:从前端到后端的全面指南

导出Excel的常用方法&#xff1a;从前端到后端的全面指南 在现代Web应用中&#xff0c;导出数据为Excel文件是一个常见需求。无论是为了数据分析、记录保存还是简单的数据共享&#xff0c;Excel文件都因其广泛的兼容性和易用性而成为首选格式之一。本文将介绍几种常用的Excel导…...

uni-app中添加自定义相机(微信小程序+app)

一、微信小程序中 微信小程序中可以直接使用camera标签&#xff0c;这个标签不兼容app&#xff0c;官方文档 <cameradevice-position"back"flash"off":style"{ height: lheight px, width: lwidth px }"class"w-full"></c…...

Android中的SSL/TLS加密及其作用

Android中的SSL/TLS加密及其作用 SSL/TLS&#xff08;Secure Sockets Layer/Transport Layer Security&#xff09;加密技术是保护网络通信安全的关键技术之一&#xff0c;广泛应用于各种网络通信场景&#xff0c;包括Android应用开发。在Android中&#xff0c;SSL/TLS加密技术…...

东芝TLP176AM光耦合器:提升设计性能的关键元件

在当今快速发展的电子领域&#xff0c;精确性、可靠性和效率比以往任何时候都更加重要。作为工程师&#xff0c;我们不断寻找不仅能满足严格技术要求&#xff0c;还能提升整体设计性能的元件。其中&#xff0c;东芝的TLP176AM光耦合器正因其卓越的性能在业界备受关注。 什么是…...

MySQL数据库:基础介绍下载与安装

数据库基础知识先谈发音MySQL如何发音&#xff1f;在国内MySQL发音有很多种&#xff0c;Oracle官方文档说他们念作My sequal[si:kwəl]。 数据库基本概念 1。数据数据&#xff08;Data&#xff09;是指对客观事物进行描述并可以鉴别的符号&#xff0c;这些符号是可识别的、抽…...

原理代码解读:基于DiT结构视频生成模型的ControlNet

Diffusion Models视频生成-博客汇总 前言:相比于基于UNet结构的视频生成模型,DiT结构的模型最大的劣势在于生态不够完善,配套的ControlNet、IP-Adapter等开源权重不多,导致难以落地。最近DiT-based 5B的ControlNet开源了,相比于传统的ControlNet有不少改进点,这篇博客将从…...

【Pip】初识 Pip:Python 包管理的基本命令详解

目录 引言1. 什么是 pip&#xff1f;1.1 pip 的安装 2. pip 的基本命令2.1 pip install2.2 pip uninstall2.3 pip list2.4 pip show2.5 pip freeze2.6 pip search2.7 pip install -U2.8 pip install -r2.9 pip check2.10 pip cache 3. 使用示例3.1 安装多个包3.2 创建虚拟环境3…...

JMeter 中两大高级线程组的区别与应用

一、JMeter 中的高级线程组概述 最近群里的测试小伙伴在问在 JMeter 中&#xff0c;“jpgc - Ultimate Thread Group”和“jpgc - Stepping Thread Group 阶梯加压”有哪些区别和实际应用场景有哪些&#xff1f;所以这里也跟大家分享一下 JMeter 作为一款强大的性能测试工具&a…...

深入理解伪元素与伪类元素

在“探秘盒子浮动&#xff0c;破解高度塌陷与文字环绕难题&#xff0c;清除浮动成关键&#xff01;”中&#xff0c;我们讲到如果父盒由于各种原因未设置高度&#xff0c; 子盒的浮动会导致父盒的高度塌陷。为了解决高度塌陷的问题&#xff0c;我们可以添加伪元素。 一、伪元素…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

学校招生小程序源码介绍

基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码&#xff0c;专为学校招生场景量身打造&#xff0c;功能实用且操作便捷。 从技术架构来看&#xff0c;ThinkPHP提供稳定可靠的后台服务&#xff0c;FastAdmin加速开发流程&#xff0c;UniApp则保障小程序在多端有良好的兼…...

【项目实战】通过多模态+LangGraph实现PPT生成助手

PPT自动生成系统 基于LangGraph的PPT自动生成系统&#xff0c;可以将Markdown文档自动转换为PPT演示文稿。 功能特点 Markdown解析&#xff1a;自动解析Markdown文档结构PPT模板分析&#xff1a;分析PPT模板的布局和风格智能布局决策&#xff1a;匹配内容与合适的PPT布局自动…...

【AI学习】三、AI算法中的向量

在人工智能&#xff08;AI&#xff09;算法中&#xff0c;向量&#xff08;Vector&#xff09;是一种将现实世界中的数据&#xff08;如图像、文本、音频等&#xff09;转化为计算机可处理的数值型特征表示的工具。它是连接人类认知&#xff08;如语义、视觉特征&#xff09;与…...

QT: `long long` 类型转换为 `QString` 2025.6.5

在 Qt 中&#xff0c;将 long long 类型转换为 QString 可以通过以下两种常用方法实现&#xff1a; 方法 1&#xff1a;使用 QString::number() 直接调用 QString 的静态方法 number()&#xff0c;将数值转换为字符串&#xff1a; long long value 1234567890123456789LL; …...

什么是Ansible Jinja2

理解 Ansible Jinja2 模板 Ansible 是一款功能强大的开源自动化工具&#xff0c;可让您无缝地管理和配置系统。Ansible 的一大亮点是它使用 Jinja2 模板&#xff0c;允许您根据变量数据动态生成文件、配置设置和脚本。本文将向您介绍 Ansible 中的 Jinja2 模板&#xff0c;并通…...

OPENCV形态学基础之二腐蚀

一.腐蚀的原理 (图1) 数学表达式&#xff1a;dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一&#xff0c;腐蚀跟膨胀属于反向操作&#xff0c;膨胀是把图像图像变大&#xff0c;而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

Android第十三次面试总结(四大 组件基础)

Activity生命周期和四大启动模式详解 一、Activity 生命周期 Activity 的生命周期由一系列回调方法组成&#xff0c;用于管理其创建、可见性、焦点和销毁过程。以下是核心方法及其调用时机&#xff1a; ​onCreate()​​ ​调用时机​&#xff1a;Activity 首次创建时调用。​…...

tomcat入门

1 tomcat 是什么 apache开发的web服务器可以为java web程序提供运行环境tomcat是一款高效&#xff0c;稳定&#xff0c;易于使用的web服务器tomcathttp服务器Servlet服务器 2 tomcat 目录介绍 -bin #存放tomcat的脚本 -conf #存放tomcat的配置文件 ---catalina.policy #to…...

提升移动端网页调试效率:WebDebugX 与常见工具组合实践

在日常移动端开发中&#xff0c;网页调试始终是一个高频但又极具挑战的环节。尤其在面对 iOS 与 Android 的混合技术栈、各种设备差异化行为时&#xff0c;开发者迫切需要一套高效、可靠且跨平台的调试方案。过去&#xff0c;我们或多或少使用过 Chrome DevTools、Remote Debug…...