主页 > imtoken钱包下载安卓 > 使用hardhat开发以太坊智能合约——测试合约
使用hardhat开发以太坊智能合约——测试合约
本系列课程: 第1节:使用hardhat开发以太坊智能合约-搭建环境[2] 第2节:使用hardhat开发以太坊智能合约-测试合约[3] 第3节:使用hardhat开发以太坊智能合约-发布contract [4] 第四节:使用安全帽开发以太坊智能合约——验证合约 [5]
在上一章中,我们讲解了如何搭建一个基本的安全帽开发环境。 在本章中,我们将讨论如何测试和部署合约
特别提醒:本系列教程默认你已经掌握了solidity的开发技巧。 如果你还没有完全理解solidity,请先移步到solidity的相关教程。
1.编译合约
我们用vscode打开工程,在左侧菜单,打开contracts目录,可以发现里面已经有一个Lock.sol文件,这是hardhat为我们准备的测试合约文件
打开 Lock.sol 文件
可以看出其实是一个很简单的逻辑,定义了2个变量,一个事件,一个调用方法。 整个合约需要实现的是,当事件满足一定条件时,合约账户是可以提现的。
接下来,我们使用hardhat提供的命令编译合约文件:
npx hardhat compile
复制
hardhat会帮我们编译contracts目录下的所有合约文件
这时我们可以看到控制台已经输出了编译日志。 如果编译不成功,会提示相应的错误信息。
同时,我们的项目目录下会生成一些新的文件,如上图,其中cache目录为缓存文件,artifacts目录下的build-info目录存放了构建项目的信息,以及contracts下的是compilation的每个合约对应的abi接口信息
2.测试合约
通过以上操作以太坊智能合约实验,我们就成功编译了合约文件。 接下来,我们将测试合约文件。 一个好的测试过程可以避免我们的合约出现一些严重的错误,尤其是在区块链上。 合约一旦部署一旦上传,就无法再次更新,所以我们必须在合约正式上线前对合约进行全面测试
2.1 测试脚本介绍
我们回到vscode,打开项目目录test,里面已经有一个名为Lock.js的脚本文件
让我们打开它看看它的主要组件
代码的前6行定义了几个常用的测试辅助对象,其中loadFixture允许我们在测试中使用相同的配置。 最常用的就是我们在测试类中定义一个部署合约的方法,然后在需要的时候使用合约对象所在的地方,通过loadFixture(function)获取部署合约的快照对象
在hardhat中,我们使用chaijs chaijs官网[6]进行断言测试,感兴趣的朋友,可以浏览chai官网了解更多信息,使用expect方法进行断言测试
describe("Lock", function () {})
复制
这段代码是识别测试的开始。 第一个参数是测试标题,可以随便定义。 第二个参数是要执行的函数体。 我们把具体的测试逻辑写在函数体中
describe可以嵌套
所以我们通常在describe中先定义一个合约部署方法,然后在describe中嵌套describe,通过loadFixture(function)得到相同的合约部署快照
2.2 合约部署方式
回到刚才的测试文件,我们继续看代码
async function deployOneYearLockFixture() {
const ONE_YEAR_IN_SECS = 365 * 24 * 60 * 60;
const ONE_GWEI = 1_000_000_000;
const lockedAmount = ONE_GWEI;
const unlockTime = (await time.latest()) + ONE_YEAR_IN_SECS;
// Contracts are deployed using the first signer/account by default
const [owner, otherAccount] = await ethers.getSigners();
const Lock = await ethers.getContractFactory("Lock");
const lock = await Lock.deploy(unlockTime, { value: lockedAmount });
return { lock, unlockTime, lockedAmount, owner, otherAccount };
}
复制
这部分代码定义了一个合约部署方法,其中
第一个所有者是我们部署合约的帐户。 我们可以通过增加更多的字段来接受返回获取其他账户信息,比如otherAccount的定义
const [owner, otherAccount] = await ethers.getSigners();
const Lock = await ethers.getContractFactory("Lock");
复制
此代码创建一个合约对象 Lock。 注意括号中的Lock对应的是合约文件中定义的名称,即
contract Lock {}
复制
请不要将合约文件名误认为是该参数,否则会报错
const lock = await Lock.deploy(unlockTime, { value: lockedAmount });
复制
通过 deploy 方法部署合约。 括号内为合约部署所需的初始化值。 如果合同不需要,可以留空
2.3 测试方法
describe("Deployment", function () {
it("Should set the right unlockTime", async function () {
const { lock, unlockTime } = await loadFixture(deployOneYearLockFixture);
expect(await lock.unlockTime()).to.equal(unlockTime);
});
});
复制
describe中,用它来测试,第一个参数是测试描述以太坊智能合约实验,第二个参数是具体的方法实现
const { lock, unlockTime } = await loadFixture(deployOneYearLockFixture);
复制
获取合约创建快照对象,从对象中获取合约对象和合约部署方法中定义的解锁时间
expect(await lock.unlockTime()).to.equal(unlockTime);
复制
使用expect进行断言判断合约对象中存储的解锁时间是否等于合约部署方法中定义的解锁时间
2.4 测试演示
接下来我们运行一下测试,看看测试结果
使用以下命令测试合约:
npx hardhat test
复制
从图中打印的信息中,我们可以清楚的看到测试结果。 值得注意的是,打印也是有层次的。 这是因为我们使用 describe in loop 嵌套来产生效果。 通过嵌套,我们可以改变测试结果。 比较清晰,推荐大家使用
通过本章的学习,我们了解了合约是如何测试的,以及测试中的一些注意事项。 接下来,我们将解释如何部署合约和网络的选择。 朋友们,下节课见。
参考
[1]
整干攻城尸:
[2]
使用hardhat开发以太坊智能合约——搭建环境:
[3]
使用hardhat开发以太坊智能合约-测试合约:
[4]
使用hardhat开发以太坊智能合约——发布合约:
[5]
使用hardhat开发以太坊智能合约——验证合约:
[6]
Chaijs官网: