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

chainlink VRF中文教程(含mock),解决error: Arithmetic Underflow in createSubscription

我使用的版本:chainlink-brownie-contracts version:1.3.0

1. Import 相关包
,,,
import {VRFConsumerBaseV2Plus} from "@chainlink/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2PLUS.sol";
import {VRFV2PlusClient} from "@chainlink/contracts/src/v0.8/vrf/dev/libraries/VRFV2PlusClient.sol";
,,,

2. 要使用的VRF功能的 contract 继承 VRFConsumerBaseV2Plus
,,,
contract EnterDungeon is VRFConsumerBaseV2Plus{}
,,,

3. 在contract中 声明下列VRF状态变量
,,,
// Chainlink VRF Variables
uint256 private immutable i_subscriptionId;
bytes32 private immutable i_gasLane; // keyHash
uint32 private immutable i_callbackGasLimit;
uint16 private constant REQUEST_CONFIRMATIONS = 3;
uint32 private constant NUM_WORDS = 1;
bool private s_enableNativePayment; // true:ETH, false:LINK
,,,

4. 重构你的 contract 的 constructor
,,,
constructor(address _vrfCoordinator, uint256 _subscriptionId, bytes32 _gasLane, uint32 _callbackGasLimit) VRFConsumerBaseV2Plus(_vrfCoordinator) {
i_subscriptionId = _subscriptionId;
i_gasLane = _gasLane;
i_callbackGasLimit = _callbackGasLimit;
}
,,,

5. 实现 requestRandomNumber(),用来封装随机数请求的逻辑
,,,
/**
* @notice requestRandomNumber
* @dev 自己定义的一个函数,可以叫做任何名字,只是单独封装了VRF请求随机数的逻辑
* @return requestId
*/
function requestRandomNumber() public returns (uint256 requestId) {
requestId = s_vrfCoordinator.requestRandomWords(
VRFV2PlusClient.RandomWordsRequest({
keyHash: i_gasLane,
subId: i_subscriptionId,
requestConfirmations: REQUEST_CONFIRMATIONS,
callbackGasLimit: i_callbackGasLimit,
numWords: NUM_WORDS,
extraArgs: VRFV2PlusClient._argsToBytes(VRFV2PlusClient.ExtraArgsV1({nativePayment: s_enableNativePayment}))
})
);
}
,,,

6. 重写 fulfillRandomWords() 里面写你具体的业务逻辑
,,,
/**
* @notice fulfillRandomWords
* @dev 当VRF请求随机数成功后,会调用这个函数,里面是拿到随机数后的具体处理逻辑
*      调用者是 VRF Coordinator,要使用requestId映射playerAddress
* @param  requestId 请求ID
* @param randomWords 随机数
*/
function fulfillRandomWords(uint256 requestId, uint256[] calldata randomWords) internal override {
// TODO:
}
,,,

7. 本地 Mock 测试

7.1 导入 Mock 合约
,,,
import {VRFCoordinatorV2_5Mock} from "@chainlink/contracts/src/v0.8/vrf/mocks/VRFCoordinatorV2_5Mock.sol";
,,,

7.2 部署 Mock 合约
,,,
// 1. deploy vrfCoordinatorV2_5Mock
vrfCoordinatorV2_5Mock = new VRFCoordinatorV2_5Mock(
MOCK_BASE_FEE,
MOCK_GAS_PRICE_LINK,
MOCK_WEI_PER_UINT_LINK
);

        // 2. create subscription
uint256 subscriptionId = vrfCoordinatorV2_5Mock.createSubscription();

        // 3. fund subscription
vrfCoordinatorV2_5Mock.fundSubscription(subscriptionId, FUND_LINK_AMOUNT); 
// FUND_LINK_AMOUNT = 100000000000000000000 = 100 LINK

        // 4. add consumer
vrfCoordinatorV2_5Mock.addConsumer(chainConfig.subscriptionId, address(consumer_addr));
,,,


7.3 常见报错 & 解决

报错信息    原因    解决办法
Arithmetic underflow in createSubscription()    mock 里用 blockhash(block.number - 1),而本地链把前一区块 hash 置 0    把内部实现改成 blockhash(block.number)(已在下方补丁)

错误信息:

VRFCoordinatorV2_5Mock::createSubscription()
│ └─ ← [Revert] panic: arithmetic underflow or overflow (0x11)
└─ ← [Revert] panic: arithmetic underflow or overflow (0x11)

补丁示例:

// SubscriptionApi.sol 片段
subId = uint256(
keccak256(
abi.encodePacked(
msg.sender,
blockhash(block.number), // ← 修改
address(this),
s_currentSubNonce
)
)
);


🔗 线上部署别忘记

在 [Chainlink-VRF-UI](https://vrf.chain.link/) 手动 Add Consumer,否则主网请求将被拒绝。

http://www.dtcms.com/a/286934.html

相关文章:

  • bmp图像操作:bmp图像保存及raw与bmp转换
  • 二分答案之第 K 小/大
  • CMake指令:常见内置命令行工具( CMake -E )
  • 乙烯丙烯酸酯橡胶市场报告:性能优势、行业现状与发展前景​
  • selenium后续!!
  • 【数据集】1970-2023年全球温室气体排放 GHG 数据集 EDGAR
  • 语音直播和视频直播的测试要点
  • 【ROS1】06-ROS通信机制——话题通信
  • OOA、OOD 与 OOP:面向对象范式的核心支柱详解
  • 接口测试的原则、用例与流程详解
  • ModelSim 配合 Makefile 搭建 Verilog 仿真工程
  • Docker-下载和安装
  • ADVB协议内容分析
  • LeetCode Hot100【6. Z 字形变换】
  • GI6E 加密GRID電碼通信SHELLCODE載入
  • CCF编程能力等级认证GESP—C++3级—20250628
  • 操作系统-处理机调度和死锁进程同步
  • 基于Qwen2.5-3B-Instruct的LoRA微调与推理实战指南
  • 多线程-3-线程同步
  • HTTPie: 开发者友好的http客户端工具
  • 数据排序
  • 特种作业操作证(制冷空调)的考试科目有哪些?
  • Xilinx Zynq:一款适用于软件定义无线电的现代片上系统
  • 使用 C# 实现移动加权平均(Weighted Moving Average)算法
  • java基础-5 : 面向对象
  • python网络爬虫(第三章/共三章:驱动浏览器窗口界面,网页元素定位,模拟用户交互(输入操作、点击操作、文件上传),浏览器窗口切换,循环爬取存储)
  • RPG60.生成可拾取物品
  • 拓扑排序/
  • 安卓Android项目 报错:系统找不到指定文件
  • Python编程:从入门到实践