在requestRandomWords()之后未调用Chainlink VRFV2 fulfillRandomWords



嗨,我想使用ChainlinkVRFConsumerBaseV2获得一个随机数,但在调用VRFCoordinatorV2Interface.requestRandomWords()后没有调用fulfillRandomWords()。我可以确认;实现";正在控制台上记录。

Imp:我正在安全帽上测试合同(包括Chainlink合同(本地。我添加了一个文件test/VRFCoordinatorV2Mock.sol,它只是导入VRFV2模拟合同:

import "@chainlink/contracts/src/v0.8/mocks/VRFCoordinatorV2Mock.sol";

以下是我的NFT.sol文件:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.9;
import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/utils/math/SafeMath.sol";
import '@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol';
import '@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol';
import "hardhat/console.sol";
contract NFT is ERC721, Ownable, VRFConsumerBaseV2 {
using SafeMath for uint256;
event RequestSent(uint256 requestId, uint32 numWords);
event RequestFulfilled(uint256 requestId, uint256[] randomWords);
struct NFTData {
uint256 mintedOn;
uint256 initialPower;
}
struct NFTInfo {
uint256 cardId;
address userAddress;
uint256 initialPower;
}
VRFCoordinatorV2Interface public coordinator;
uint64 private _subscriptionId;
bytes32 public keyHash;
uint32 public callbackGasLimit = 100000;
uint16 requestConfirmations = 3;
uint32 numWords = 1;
mapping(uint256 => NFTInfo) private _requestIdToNFTInfo;
mapping(uint256 => NFTData) private _nfts;
constructor(string memory _name, string memory _symbol, address _coordinator, uint64 subscriptionId, bytes32 _keyHash)
ERC721(_name, _symbol)
VRFConsumerBaseV2(_coordinator)
{
coordinator = VRFCoordinatorV2Interface(_coordinator);
_subscriptionId = subscriptionId;
keyHash = _keyHash;
}
function mintNFT(uint256 cardId, address userAddress, uint256 _initialPower) external onlyOwner returns(uint256) {
console.log("requestRandom: ");
uint256 requestId = coordinator.requestRandomWords(
keyHash,
_subscriptionId,
requestConfirmations,
callbackGasLimit,
numWords
);
_requestIdToNFTInfo[requestId] = NFTInfo(cardId, userAddress, _initialPower);
emit RequestSent(requestId, numWords);
console.log("Emit");
return requestId;
}
function fulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords) internal override {
console.log("fulfill");
NFTInfo memory requestNFTInfo = _requestIdToNFTInfo[_requestId];
require(requestNFTInfo.userAddress != address(0), "Request not found");
_safeMint(requestNFTInfo.userAddress, requestNFTInfo.cardId);
console.log("_safeMint");
_nfts[requestNFTInfo.cardId] = NFTData(block.timestamp, requestNFTInfo.initialPower);
emit RequestFulfilled(_requestId, _randomWords);
}
}

以下是我的nft.test.js文件:

const { expect } = require("chai");
describe("Contract deployment", () => {
let nft, vrfCoordinatorV2Mock, hardhatVrfCoordinatorV2Mock, owner;
before(async () => {
nftFactory = await ethers.getContractFactory("NFT");
vrfCoordinatorV2Mock = await ethers.getContractFactory("VRFCoordinatorV2Mock");
});
beforeEach(async () => {
[owner] = await ethers.getSigners();
hardhatVrfCoordinatorV2Mock = await vrfCoordinatorV2Mock.deploy(0, 0);
await hardhatVrfCoordinatorV2Mock.deployed();
await hardhatVrfCoordinatorV2Mock.createSubscription();
await hardhatVrfCoordinatorV2Mock.fundSubscription(1, 100000);
nft = await nftFactory.deploy("NFT", "NFT", hardhatVrfCoordinatorV2Mock.address, 1, "0x79d3d8832d904592c0bf9818b621522c988bb8b0c05cdc3b15aea1b6e8db0c15");
await nft.deployed();
});

describe("NFT", () => {
it("Mint NFT", async () => {
await hardhatVrfCoordinatorV2Mock.addConsumer(1, nft.address);
await nft.mintNFT(1, owner.address, 100);
// here "fulfill" isn't being logged
});
});
});

是否有可能在安全帽上本地测试VRF,或者我遗漏了什么?非常感谢您的帮助。此外,我们也欢迎任何关于在当地与VRF正确测试我的NFT合同的建议。

除非创建Oracle应用程序,否则无法在本地进行测试。

VFR的工作方式是向VFR合同请求随机性。Chainlink有一个单独的服务运行在某个地方(不在区块链上(,它监控请求的随机性请求。Chainlink然后向区块链提交一笔交易,区块链会调用您的fulfillRandomWords函数。

相关内容

  • 没有找到相关文章

最新更新