可以看到其实是一个很简单的逻辑,里面定义了 2 个变量,还有一个事件,以及一个调用方法,整个合约要实现的就是当事件满足一定条件的时候才可以从合约账号提现
下面,我们使用 hardhat 提供的命令对合约文件进行编译:
npx hardhat compile
hardhat 会帮我们编译 contracts 目录下面的所有合约文件
这时候我们可以看到在控制台已经输出了编译日志,如果编译不成功会提示相应的错误信息
在我们的项目目录里同时也会生成一些新的文件,如上图所示,其中 cache 目录为缓存文件,artifacts 目录下的 build-info 目录,存放的是构建项目的信息,contracts 下面存放的是编译的每个合约对应的 abi 接口信息
2、测试合约
通过上面的操作,我们已经成功的编译了合约文件,下面我们来对合约文件进行测试,一个好的测试流程可以避免我们的合约出现一些严重的 bug,特别是在区块链上,一旦合约部署上去就无法再次更新,所以我们在正式上线之前,必须将合约完全测试一遍
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 };
}
复制
这部分代码定义了一个合约部署方法,其中
第一个 owner 即为我们部署合约的账号,可以通过加入更多字段接受返回,获取其他的账号信息,如 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 });