如何从链接VRF V2获得10000个随机数



我想使用链接VRF V2生成10000个随机数,但一个请求中的最大NUM_WORDS是500,而且每次都失败我该怎么办?我的帐户有足够的链接,但我在下面所做的不起作用!

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol";
import "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol";
contract VRFCoordinatorTest is  VRFConsumerBaseV2 {
// Chainlink VRF Variables
address vrfCoordinatorV2 = 0x6168499c0cFfCaCD319c818142124B7A15E857ab;
uint64 subscriptionId = 14422;
bytes32 gasLane = 0xd89b2bf150e3b9e13446986e571fb9cab24b13cea0a43ea20a6049a85cc807cc;
uint32 public callbackGasLimit = 2500000; //already max gaslimit
//network coordinator
VRFCoordinatorV2Interface private immutable _vrfCoordinator;
// The default is 3, but you can set this higher.
uint16 public  REQUEST_CONFIRMATIONS = 10;
// retrieve NUM_WORDS random values in one request.
uint32 public NUM_WORDS = 500;
//keep the randomWords from fulfillRandomWords() function.
uint256[][] public _randomWords = new uint256[][](0);
//uint256[] public _randomWords;

event RequestedRandomWords(uint256 requestId ,address requester);
constructor() VRFConsumerBaseV2(vrfCoordinatorV2) {
_vrfCoordinator = VRFCoordinatorV2Interface(vrfCoordinatorV2);
}
function fulfillRandomWords(uint256, uint256[] memory randomWords) internal override{
_randomWords.push(randomWords);
// _randomWords = randomWords;
}
function requestRandomWords()public{
uint256 requestId = _vrfCoordinator.requestRandomWords(
gasLane,
subscriptionId,
REQUEST_CONFIRMATIONS,
callbackGasLimit,
NUM_WORDS
);
emit RequestedRandomWords(requestId, msg.sender);
}
function set_REQUEST_CONFIRMATIONS(uint16 comf)public{
REQUEST_CONFIRMATIONS = comf;
}
function set_NUM_WORDS(uint32 num)public{
NUM_WORDS = num;
}
function set_gasLimit(uint32 gasl) public{
callbackGasLimit = gasl;
}
function getMaxLengthAndNum()public view returns(uint256,uint256){
uint256 lth = _randomWords.length;
uint256[] memory tmpArray = _randomWords[lth-1];
uint256 lastNum = tmpArray[tmpArray.length-1];
//uint256 maxNum = _randomWords[_randomWords.length-1];
return (lth,lastNum);
}
}

我看到您正在Rinkeby上进行测试。我建议你在Goerli上测试一下。Rinkeby被标记为已弃用(参见。https://docs.chain.link/docs/vrf/v2/supported-networks/)。

我已经测试了你的合同,并指出fulfillRandomWords的汽油用完了。事实上,每个请求可以接收的随机单词的最大数量是500,回调函数支持的最大气体限制是2500000。因此,您必须确保回调函数不会耗尽气体(意思是:您的回调函数消耗的气体不能超过2500000(。在您的示例中,您试图存储500个随机单词。将一个值从非零设置为零需要大约20000气体(参见以太坊黄皮书附录H(。有了250万的汽油,你最多可以储存125个单词。这就是为什么所附的合同在NUM_WORDS=500(fulfillRandomWords用完汽油(时不起作用。如果您想存储10001个随机值,我建议您进行多次请求。例如:在requestRandomWords内部,您可以循环vrfCoordinator.requestRandomWords多次(例如:100次运行时NUM_WORDS=100,最后一次运行时为1(。回调函数将被调用多次(=requestId的数量(,因此请确保实现一个等待所有请求完成的逻辑(例如,您可以更新状态变量s_requestsFulfilled每次满足请求时(。

这里有一个你可以在Goerli上测试的例子,我修改了你的例子(重要备注:这是一个未经审计的代码,具有硬编码值。不要将其用作生产代码的参考。请根据你的需要进行测试/更改(

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.8;
import "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol";
import "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol";
contract VRFCoordinatorTest_2 is  VRFConsumerBaseV2 {
// Chainlink VRF Variables
address vrfCoordinatorV2 = 0x2Ca8E0C643bDe4C2E08ab1fA0da3401AdAD7734D;
uint64 subscriptionId = 443;
bytes32 gasLane = 0x79d3d8832d904592c0bf9818b621522c988bb8b0c05cdc3b15aea1b6e8db0c15;
uint32 public callbackGasLimit = 2500000; //already max gaslimit
uint256 public requestsFulfilled = 0; // count number of request fulfilled
//network coordinator
VRFCoordinatorV2Interface private immutable _vrfCoordinator;
// The default is 3, but you can set this higher.
uint16 public  REQUEST_CONFIRMATIONS = 3;
//keep the randomWords from fulfillRandomWords() function.
struct RequestStatus {
bool fulfilled; // whether the request has been successfully fulfilled
bool exists; // whether a requestId exists
uint256[] randomWords;
}
mapping(uint256 => RequestStatus) public s_requests;
uint256[] public requestIds;
//uint256[] public _randomWords;

event ReceivedRandomWords(uint256 requestId ,uint256[] randomWords);
event RequestedRandomWords(uint256 requestId ,address requester);
event AllRequestsFulfilled();
constructor() VRFConsumerBaseV2(vrfCoordinatorV2) {
_vrfCoordinator = VRFCoordinatorV2Interface(vrfCoordinatorV2);
}
function fulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords) internal override{
require(s_requests[_requestId].exists, 'request not found');
require(!s_requests[_requestId].fulfilled, 'request already fulfilled');
requestsFulfilled++;
s_requests[_requestId].fulfilled = true;
s_requests[_requestId].randomWords = _randomWords;
emit ReceivedRandomWords(_requestId,_randomWords);
if(requestsFulfilled==101){
emit AllRequestsFulfilled();
}
}
function requestRandomWords()public{
uint32 numWords = 100;
for(uint256 i=0;i<101;i++){
if(i==100){
numWords=1;
}
uint256 requestId = _vrfCoordinator.requestRandomWords(
gasLane,
subscriptionId,
REQUEST_CONFIRMATIONS,
callbackGasLimit,
numWords
);
s_requests[requestId]=RequestStatus({randomWords: new uint256[](0), exists: true, fulfilled: false});
requestIds.push(requestId);
emit RequestedRandomWords(requestId, msg.sender);

}

}
function getRequestStatus(uint256 requestId) external view returns (bool fulfilled, uint256[] memory randomWords) {
require(s_requests[requestId].exists, 'request not found');
RequestStatus memory request = s_requests[requestId];
return (request.fulfilled, request.randomWords);
}
function getRandomWordsAt(uint256 requestId,uint32 index) external view returns (uint256) {
require(s_requests[requestId].exists, 'request not found');
RequestStatus memory request = s_requests[requestId];
return  request.randomWords[index];
}
function getRequestIdsLength() external view returns (uint256){
return requestIds.length;
}
function getRandomWords(uint256 requestId) external view returns (uint256[] memory){
require(s_requests[requestId].exists, 'request not found');
return s_requests[requestId].randomWords;
}

}

相关内容

  • 没有找到相关文章

最新更新