1 random solidity smartcontracts chainlink
我想使用 chainlink VRF V2 生成 10000 个随机数,但一次请求的最大 NUM_WORDS 为 500,每次都失败\xef\xbc\x81\n我该怎么办?\n我的帐户有足够的 LINK,但我怎么办?做了下面的不起作用!
\n// SPDX-License-Identifier: MIT\npragma solidity ^0.8.8;\n\nimport "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol";\nimport "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol";\n\ncontract VRFCoordinatorTest is VRFConsumerBaseV2 {\n // Chainlink VRF Variables\n\n address vrfCoordinatorV2 = 0x6168499c0cFfCaCD319c818142124B7A15E857ab;\n uint64 subscriptionId = 14422;\n bytes32 gasLane = 0xd89b2bf150e3b9e13446986e571fb9cab24b13cea0a43ea20a6049a85cc807cc;\n uint32 public callbackGasLimit = 2500000; //already max gaslimit\n\n //network coordinator\n VRFCoordinatorV2Interface private immutable _vrfCoordinator;\n\n // The default is 3, but you can set this higher.\n uint16 public REQUEST_CONFIRMATIONS = 10;\n\n // retrieve NUM_WORDS random values in one request.\n uint32 public NUM_WORDS = 500;\n\n //keep the randomWords from fulfillRandomWords() function.\n uint256[][] public _randomWords = new uint256[][](0);\n //uint256[] public _randomWords;\n\n\n event RequestedRandomWords(uint256 requestId ,address requester);\n\n constructor() VRFConsumerBaseV2(vrfCoordinatorV2) {\n _vrfCoordinator = VRFCoordinatorV2Interface(vrfCoordinatorV2);\n }\n\n function fulfillRandomWords(uint256, uint256[] memory randomWords) internal override{\n _randomWords.push(randomWords);\n // _randomWords = randomWords;\n }\n\n function requestRandomWords()public{\n uint256 requestId = _vrfCoordinator.requestRandomWords(\n gasLane,\n subscriptionId,\n REQUEST_CONFIRMATIONS,\n callbackGasLimit,\n NUM_WORDS\n );\n emit RequestedRandomWords(requestId, msg.sender);\n }\n\n function set_REQUEST_CONFIRMATIONS(uint16 comf)public{\n REQUEST_CONFIRMATIONS = comf;\n }\n function set_NUM_WORDS(uint32 num)public{\n NUM_WORDS = num;\n }\n function set_gasLimit(uint32 gasl) public{\n callbackGasLimit = gasl;\n }\n\n function getMaxLengthAndNum()public view returns(uint256,uint256){\n uint256 lth = _randomWords.length;\n uint256[] memory tmpArray = _randomWords[lth-1];\n uint256 lastNum = tmpArray[tmpArray.length-1];\n //uint256 maxNum = _randomWords[_randomWords.length-1];\n\n return (lth,lastNum);\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n
我看到你正在 Rinkeby 上进行测试。我建议你在Goerli上测试一下。Rinkeby 被标记为已弃用(参见https://docs.chain.link/docs/vrf/v2/supported-networks/)。
\n我测试了你的合约并指出它fulfillRandomWords耗尽了汽油。事实上,每个请求可以接收的最大随机字数是 500,回调函数支持的最大 Gas 限制是 2,500,000。因此,您必须确保回调函数不会耗尽 Gas(这意味着:您的回调函数消耗的 Gas 不能超过 2,500,000)。\n在您的示例中,您尝试存储 500 个随机单词。将一个值从非零设置到零大约需要 20,000 个 Gas(参见以太坊黄皮书附录 H)。使用 2,500,000 Gas,最多可以存储 125 个单词。这就是为什么附加合约无法在 NUM_WORDS=500 的情况下工作(fulfillRandomWords 耗尽燃料)。\n如果您想存储 10001 个随机值,我建议发出多个请求。例如:requestRandomWords您可以在内部多次循环vrfCoordinator.requestRandomWords(例如:NUM_WORDS = 100 表示 100 次运行。1 表示最后一次运行)。\n您的回调函数将被调用多次(= requestId 的数量),因此请确保实现一个等待所有请求得到满足的逻辑(例如,您可以s_requestsFulfilled在每次满足请求时更新状态变量)。
这是一个您可以在 Goerli 上测试的示例,我修改了您的示例(重要提示:这是带有硬编码值的未经审核的代码。请勿将其用作生产代码的参考。请根据您的测试/更改它需要)
\n// SPDX-License-Identifier: MIT\npragma solidity ^0.8.8;\n\nimport "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol";\nimport "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol";\n\ncontract VRFCoordinatorTest_2 is VRFConsumerBaseV2 {\n // Chainlink VRF Variables\n\n address vrfCoordinatorV2 = 0x2Ca8E0C643bDe4C2E08ab1fA0da3401AdAD7734D;\n uint64 subscriptionId = 443;\n bytes32 gasLane = 0x79d3d8832d904592c0bf9818b621522c988bb8b0c05cdc3b15aea1b6e8db0c15;\n uint32 public callbackGasLimit = 2500000; //already max gaslimit\n\n uint256 public requestsFulfilled = 0; // count number of request fulfilled\n\n //network coordinator\n VRFCoordinatorV2Interface private immutable _vrfCoordinator;\n\n // The default is 3, but you can set this higher.\n uint16 public REQUEST_CONFIRMATIONS = 3;\n\n //keep the randomWords from fulfillRandomWords() function.\n struct RequestStatus {\n bool fulfilled; // whether the request has been successfully fulfilled\n bool exists; // whether a requestId exists\n uint256[] randomWords;\n }\n mapping(uint256 => RequestStatus) public s_requests;\n uint256[] public requestIds;\n //uint256[] public _randomWords;\n\n\n event ReceivedRandomWords(uint256 requestId ,uint256[] randomWords);\n event RequestedRandomWords(uint256 requestId ,address requester);\n event AllRequestsFulfilled();\n\n constructor() VRFConsumerBaseV2(vrfCoordinatorV2) {\n _vrfCoordinator = VRFCoordinatorV2Interface(vrfCoordinatorV2);\n }\n\n function fulfillRandomWords(uint256 _requestId, uint256[] memory _randomWords) internal override{\n require(s_requests[_requestId].exists, \'request not found\');\n require(!s_requests[_requestId].fulfilled, \'request already fulfilled\');\n requestsFulfilled++;\n s_requests[_requestId].fulfilled = true;\n s_requests[_requestId].randomWords = _randomWords;\n emit ReceivedRandomWords(_requestId,_randomWords);\n if(requestsFulfilled==101){\n emit AllRequestsFulfilled();\n }\n }\n\n function requestRandomWords()public{\n uint32 numWords = 100;\n for(uint256 i=0;i<101;i++){\n if(i==100){\n numWords=1;\n }\n uint256 requestId = _vrfCoordinator.requestRandomWords(\n gasLane,\n subscriptionId,\n REQUEST_CONFIRMATIONS,\n callbackGasLimit,\n numWords\n );\n s_requests[requestId]=RequestStatus({randomWords: new uint256[](0), exists: true, fulfilled: false});\n requestIds.push(requestId);\n emit RequestedRandomWords(requestId, msg.sender);\n \n }\n \n }\n\n function getRequestStatus(uint256 requestId) external view returns (bool fulfilled, uint256[] memory randomWords) {\n require(s_requests[requestId].exists, \'request not found\');\n RequestStatus memory request = s_requests[requestId];\n return (request.fulfilled, request.randomWords);\n }\n\n function getRandomWordsAt(uint256 requestId,uint32 index) external view returns (uint256) {\n require(s_requests[requestId].exists, \'request not found\');\n RequestStatus memory request = s_requests[requestId];\n return request.randomWords[index];\n }\n\n function getRequestIdsLength() external view returns (uint256){\n return requestIds.length;\n }\n\n function getRandomWords(uint256 requestId) external view returns (uint256[] memory){\n require(s_requests[requestId].exists, \'request not found\');\n return s_requests[requestId].randomWords;\n }\n \n}\n\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
842 次 |
| 最近记录: |