使用测试驱动开发模式编写智能合约

hardhat简介

  • hardhat是一个以太坊智能合约开发框架,主要用于简化和加速以太坊区块链上的智能合约开、测试和部署,提供了许多工具帮助开发人员更轻松地构建和维护智能合约项目,以下是他的一些主要功能:
    • 智能合约开发:hardhat提供了强大的开发环境,支持solidity语言,允许开发人员轻松编写、调试和测试智能合约。
    • 智能合约测试:hardhat提供了一个集成的测试框架,使开发人员能编写和运行针对智能合约的自动化测试,这有助于确保合约在不同场景下的正确性和安全性。
    • 本地开发网络:hardhat支持在本地运行一个以太坊节点,以便在开发过程中快速测试和调试智能合约,使得开发人员无需连接到主网络,提高了开发效率。
    • 集成测试和部署:hardhat提供了工具和脚本,方便集成测试和部署智能合约到以太坊主网或测试网,有助于合约在真实环境中正常运行。
    • 脚本和任务:hardhat允许开发人员编写自定义脚本和任务,以执行特定的操作,例如部署合约、验证代码等,为自动化开发流程提供了更大的灵活性。
    • 插件系统:hardhat的插件系统使得开发人员能扩展框架的功能,以满足项目的特定需求,可以使用现有的插件,也可以编写自己的定制插件。
    • 与其它开发工具的集成: Hardhat 与其他常用的开发工具集成,例如 Truffle、ethers.js 等,为开发人员提供更多选择和灵活性。

安装hardhat

  • 前提是要安装好node.js。
  • 在项目目录里打开终端使用mkdir 文件名命令来创建一个新的文件夹
  • 然后使用cd 文件名命令转到该目录
  • 使用npm install --save-dev hardhat命令安装hardhat
  • 输入npx hardhat init命令进行初始化
  • 该某目录下就会多出这些文件

使用测试驱动开发模式编写智能合约

  • 基于该框架,使用vscode打开该文件夹,在test目录下新建test.js文件,在contracts目录下新建Mailbox.sol合约文件
  • 示例代码
    注意:要进入我们之前安装hardhat的根目录,否则他会显示错误信息Error HH1: You are not inside a Hardhat project.,表示你当前不在一个hardhat项目中,我这里创建的目录是my-new-project,因此要在该目录下创建文件以及运行
    js代码

const { expect } = require("chai");
const { ethers } = require("hardhat");describe("Mailbox", async () => {it("should get mailbox contract", async () => {const mailboxContract = await ethers.getContractFactory("Mailbox");});it("should get total letters in the box", async () => {const mailboxContract = await ethers.getContractFactory("Mailbox");const mailbox = await mailboxContract.deploy();expect(await mailbox.totalLetters()).to.equal(0);});it("should increase by one when got new letter", async () => {const mailboxContract = await ethers.getContractFactory("Mailbox");const mailbox = await mailboxContract.deploy();await mailbox.write("Hello");expect(await mailbox.totalLetters()).to.equal(1);})it("should get mail content", async () => {const mailboxContract = await ethers.getContractFactory("Mailbox");const mailbox = await mailboxContract.deploy();await mailbox.write("Hello");const letters = await mailbox.read();expect(letters[0].letter).to.equal("Hello");})it("should get mail sender", async () => {const mailboxContract = await ethers.getContractFactory("Mailbox");const mailbox = await mailboxContract.deploy();await mailbox.write("Hello");const letters = await mailbox.read();//这里记得测试后将0x替换成终端给出的地址expect(letters[0].sender).to.equal("0x");})
});

合约代码

pragma solidity 0.8.24;
contract Mailbox {
//这里没有赋初值的话,初始值为0uint public totalLetters;struct Letter {string letter;address sender;}Letter[] private letters;function write(string memory letter) public {totalLetters++;letters.push(Letter(letter, msg.sender));}function read() public view returns (Letter[] memory) {return letters;}
}

终端界面输入npx hardhat test命令,当显示全绿表示测试通过
在这里插入图片描述

学习笔记
  • const { expect } = require("chai");
    这行代码使用了JavaScript的解构赋值语法,表示声明了一个expect常量,并从chai这个模块中 找到名为expect的属性并赋值给该expect常量。
    如果不使用解构赋值就使用const expect = require("chai")命令,该命令导入了chai的整个模块,使用解构赋值语法的好处就是只导入模块中真正需要的部分,减少不必要的代码依赖。当模块中有多个导出时可以防止导入的变量名和其它变量名发生冲突。
    这里的require用于加载指定模块
  • describe("Mailbox", async () => {})
    该代码是使用一种测试框架编写的测试用例描述。这种测试框架用于编写和组织测试用例,确保代码的正确性和可靠性。
    describe函数接收两个参数,一个描述字符串,也就是我们这里的"Mailbox",一个回调函数,即async () => {}。该回调函数是一个 异步函数(使用 async 关键字标记)。
    在describe函数的回调函数中 ,你可以添加一个或多个测试用例。测试用例使用测试框架提供的其它函数(如it)编写的。
  • it("should get mail sender", async () => {})
    是一个测试用例,接收两个参数,一个字符串,一个异步函数
  • const mailboxContract = await ethers.getContractFactory("Mailbox");
    使用ethers.getContractFactory获取一个名为Mailbox的智能合约,并将其实例化为一个常量对象。
  • const mailbox = await mailboxContract.deploy();
    mailboxContract.deploy()是一个异步操作,它返回一个promise对象,该对象在解析时包含一个已部署的"Mailbox"智能合约实例,await关键字用于等待Promise对象的解析,在这里用英语等待智能合约的部署完成。最后,将解析后的已部署智能合约实例赋值给常量对象mailbox。这样,我们就可以使用mailbox来调用"Mailbox"智能合约的方法和属性。
  • await mailbox.write("Hello");
    调用合约的write函数向信箱写入一条消息“Hello”
  • const letters = await mailbox.read();
    调用合约的read函数读取信箱中的邮箱
  • expect(letters[0].sender).to.equal('0x');
    使用expect函数进行断言,letters[0].sender从先前测试中获取到信箱中第一封信件的发送者地址,在终端测试后会给出该地址,替换掉0x即可测试通过。to.equal是一个匹配器。

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

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

相关文章

MySQL 针对逗号拼接的数据字段转行思路

一、MySQL 针对逗号拼接的数据字段转行思路 在 MySQL 中我们有可能为了方便操作,有时会将一个字段存储多个信息,使用英文逗号隔开,当然这种情况属于对数据库的设计上有些欠妥。但如果遇到了这种情况又需要对数据进行统计的情况就有点棘手了&…

STM32CubeIDE基础学习-设置输出HEX和BIN文件的方法

STM32CubeIDE基础学习-设置输出HEX和BIN文件的方法 前言 当某些时候,需要把一个程序下载到单片机里面进行功能验证或者看结果时,可以用串口软件来烧录程序,而不用再打开程序工程在线烧录程序这么麻烦了,那么就需要该工程文件夹下…

电脑记事本怎么查看字数 记事本字数便捷查看方法

在数字化的时代,电脑记事本已成为我记录生活、工作的得力助手。相较于传统的纸质笔记本,它的便捷性不言而喻:随时随地,打开就能写,无需担心纸张用尽或笔墨不干的尴尬。但有一个问题一直困扰着我,那就是如何…

UI学习 一

教程:Accessibility – Material Design 3 需要科学上网,否则图片显示不出来。设计教程没有图片说明,不容易理解。 优化UI方向 清晰可见的元素足够的对比度和尺寸重要性的明确等级一眼就能辨别的关键信息 传达某一事物的相对重要性 将重…

(二十二)从零开始搭建k8s集群——高可用kubernates集群搭建上篇

前言 本节内容分为上、中、下三篇,上篇主要是关于搭建k8s的基础环境,包括服务器基本环境的配置(网络、端口、主机名、防火墙、交换分区、文件句柄数等)、docker环境部署安装配置、镜像源配置等。中篇会介绍k8s的核心组件安装、k8…

xss.pwnfunction.com靶机 Warmups

通关要求弹出警告框alert(1337) 没有用户交互 不能使用外链接 在chrome中测试 Ma Spaghet! 通过分析代码我们可以看到它直接用innerHTML将接收的内容赋值 但是我们不能使用<script>标签因为&#xff1a;HTML 5 中指定不执行由 innerHTML 插入的 <script> 标签。 所…

网络原理初识

一、IP地址 概念 IP 地址主要用于标识网络主机、其他网络设备&#xff08;如路由器&#xff09;的网络地址。简单说&#xff0c; IP 地址用于定位主机 的网络地址 。 就像我们发送快递一样&#xff0c;需要知道对方的收货地址&#xff0c;快递员才能将包裹送到目的地。 二、…

YOLOv8原创改进:原创自研head创新 | 空间上下文感知模块(SCAM)结合超轻量高效动态上采样DySample | 小目标涨点系列

💡💡💡本文独家改进:YOLOV8 head创新,1)一种超轻量高效动态上采样DySample, 具有更少的参数、FLOPs,效果秒杀CAFFE和YOLOv8网络中的nn.Upsample;2)加入空间上下文感知模块(SCAM)进一步提升检测精度; 改进结构图如下: 💡💡💡在多个数据集下验证能够涨点…

Java中SpringBoot四大核心组件是什么

一、Spring Boot Starter 1.1 Starter的应用示例 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId> </dependency> <dependency><groupId>org.mybatis.sprin…

Android屏幕共享-硬编码硬解码

Android屏幕共享-硬编码硬解码 说起Android之间的屏幕共享&#xff0c;第一次接触会比较陌生&#xff0c;不过大家多少有了解过ffmpeg&#xff0c;看上去是不是很熟悉&#xff1f;ffmpeg是一套处理音视频的开源程序&#xff0c;但对于C了解较少的同学&#xff0c;编译起来很复杂…

二维码门楼牌管理系统应用场景:社会服务与福利的智能化革新

文章目录 前言一、二维码门楼牌管理系统的基本功能二、在社会服务领域的应用三、在福利保障领域的应用四、结论 前言 在数字化浪潮的推动下&#xff0c;二维码门楼牌管理系统以其便捷、高效的特点&#xff0c;正逐渐渗透到社会服务和福利的各个领域。这一系统不仅为市民提供了…

Claude3 目前最强大模型

过内试用连接 ChatAI (whjin.cn)http://chatyy.whjin.cn/?userid51913030&typebaidu&keywordid0&bd_vid12153741466503666331 Claude 3: A new generation of AI The Claude 3 family of models represents the cutting edge of AI technology, offering unpara…

RN开发搬砖经验之-如何处理FlashList组件加载后调用scrollToIndex没有滚动指定位置

前言 如题&#xff0c;这里只能说是处理&#xff0c;起正向作用的临时方案&#xff0c;因为我也着实没搞懂这个BUG的具体原因&#xff0c;看github上有提相关的issuesFor long lists with different item types scrollToIndex does not work reliable&#xff0c;但看官方没有…

Extended Feature Pyramid Network for SmallObject Detection

摘要 各种尺度的特征耦合会削弱小对象的性能&#xff0c;本文中&#xff0c;我们提出了具有超高分辨率金字塔的扩展特征金字塔网络&#xff08;EFPN &#xff09;&#xff0c;专门用于小目标检测。具体来说&#xff0c;我们设计了一个新模块&#xff0c;称为特征纹理转移&#…

【MySQL 系列】MySQL 起步篇

MySQL 是一个开放源代码的、免费的关系型数据库管理系统。在 Web 开发领域&#xff0c;MySQL 是最流行、使用最广泛的关系数据库。MySql 分为社区版和商业版&#xff0c;社区版完全免费&#xff0c;并且几乎能满足全部的使用场景。由于 MySQL 是开源的&#xff0c;我们还可以根…

统信os平台普通用户无法调用clockdiff的问题解决方法

问题描述 部署OceanBase 时遇到clockdiff: socket: operation not permitted 问题&#xff0c;从官网了解到可以通过setcap cap_net_rawep "$(which clockdiff)"解决 在centos平台&#xff0c;这个可以解决问题&#xff0c;但是在统信os平台失败了。。 参考: Ocea…

怎么把一个视频分割成几个?技巧在这里

在视频编辑的过程中&#xff0c;有时我们需要将一个较长的视频细分成多个部分&#xff0c;以便更灵活地进行处理、调整或分享。这个过程可以帮助我们有效管理视频内容&#xff0c;提取关键片段&#xff0c;并且适应不同的发布需求。在本文中&#xff0c;我们将深入探讨怎么把一…

JavaScript改变this指向的三种方法

在JavaScript中&#xff0c;可以使用call()、apply()或bind()来改变函数的this指向。 1.call(): 通过调用函数并传入新的上下文对象作为参数&#xff0c;将函数内部的this关键字指向该对象。示例代码如下所示 function greet(name) {console.log("Hello " name); …

机器学习笔记 DeepFakes和换脸技术简述

一、简述 人脸检测一直是 2000 年代初的主要研究课题。差不多二十年后,这个问题基本上得到了解决,并且人脸检测在大多数编程语言中都可以作为库使用。甚至换脸技术也不是什么新鲜事,并且已经存在了好些年了。 早在2016年左右就有基于OpenCV进行面部交换的方式了,主要是基于…

第107讲:Mycat实践指南:取模分片下的水平分表详解

文章目录 1.使用取模分片水平分表2.水平分表取模分片案例2.1.准备测试的表结构2.2.配置Mycat实现范围分片的水平分表2.2.1.配置Schema配置文件2.2.2.配置Rule分片规则配置文件2.2.3.配置Server配置文件2.2.4.重启Mycat 2.3.写入数据观察水平分表效果 1.使用取模分片水平分表 平…