如何对Chainlink可验证随机函数(VRF)进行本地单元测试
自托管Chainlink VRF单元测试与CI流程配置方案
目录结构
project-root ├── contracts │ ├── YourVRFConsumer.sol # 自研VRF消费合约 │ └── mocks │ ├── MockVRFCoordinatorV2.sol # Chainlink官方Mock VRF协调器(可直接从@chainlink/contracts包导入) │ └── MockLINK.sol # 官方Mock LINK代币合约 ├── test │ └── VRFTest.spec.ts # Waffle测试用例 ├── hardhat.config.ts # Hardhat配置(集成Waffle) ├── .github/workflows/test.yml / .gitlab-ci.yml # CI配置文件 ├── package.json └── .env # 无需配置公网RPC相关变量
核心配置文件
hardhat.config.ts
不需要配置Kovan、主网等公网网络,默认使用本地Hardhat网络,配置示例:
import { HardhatUserConfig } from "hardhat/config"; import "@nomiclabs/hardhat-waffle"; import "@nomiclabs/hardhat-ethers"; const config: HardhatUserConfig = { solidity: "0.8.17", // 匹配你的合约solidity版本 networks: { hardhat: { gas: 12000000, // 本地网络默认gas上限调足 } } }; export default config;
测试用例前置配置
在测试用例的before钩子中完成本地模拟环境初始化,解决gas估算失败问题:
- 部署MockLINK、MockVRFCoordinatorV2合约
- 在VRF协调器中创建订阅并充值足够额度的Mock LINK
- 部署自研VRF消费合约,传入协调器地址、LINK地址、keyHash、订阅ID等参数
- 将消费合约地址加入VRF协调器订阅的消费者白名单
测试逻辑编写
gas充足场景测试
调用getRandomNumber()时指定足够的gasLimit,随后调用MockVRFCoordinator的fulfillRandomWords方法模拟Chainlink节点回调,断言返回的随机数为正整数。示例代码:
it("should return integer when gas is sufficient", async () => { const tx = await consumerContract.getRandomNumber({ gasLimit: 500000 }); const txReceipt = await tx.wait(); const requestId = txReceipt.events[0].args.requestId; // 模拟回调填充随机数 await vrfCoordinator.fulfillRandomWords(requestId, consumerContract.address); const randomNumber = await consumerContract.getLatestRandomNumber(); expect(randomNumber).to.gt(0); });
gas不足场景测试
调用getRandomNumber()时手动设置低于实际消耗的gasLimit,断言交易抛出revert错误。示例代码:
it("should revert when gas is insufficient", async () => { await expect( consumerContract.getRandomNumber({ gasLimit: 10000 }) // 故意设置过低的gas limit ).to.be.reverted; });
运行命令
- 编译合约:
npx hardhat compile - 本地单元测试:
npx hardhat test,全程运行在本地Hardhat网络,无需公网RPC依赖 - CI执行命令和本地完全一致,CI环境只需安装Node.js依赖后直接执行测试命令即可
内容的提问来源于stack exchange,提问作者a.t.
相关产品推荐
相关产品推荐

