Open REBOA opened 1 month ago
// SPDX-License-Identifier: MIT pragma solidity ^0.8.21; import "https://github.com/AmazingAng/WTFSolidity/blob/main/34_ERC721/ERC721.sol"; import "https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2Plus.sol"; import "https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/vrf/dev/libraries/VRFV2PlusClient.sol"; contract Random is ERC721, VRFConsumerBaseV2Plus { // NFT related variables uint256 public totalSupply = 100; // Total supply uint256[100] public ids; // Array for available token IDs uint256 public mintCount; // Number of minted tokens // Chainlink VRF parameters address vrfCoordinator = 0x9DdfaCa8183c41ad55329BdeeD9F6A8d53168B1B; bytes32 keyHash = 0x787d74caea10b2b357790d5b5247c2f63d1d91572a9846f780606e4d953677ae; uint16 requestConfirmations = 3; uint32 callbackGasLimit = 1_000_000; uint32 numWords = 1; uint256 public requestId; uint256 public subId; // Mapping to keep track of request IDs and mint addresses mapping(uint256 => address) public requestToSender; constructor(uint256 _subId) VRFConsumerBaseV2Plus(vrfCoordinator) ERC721("WTF Random", "WTF") { subId = _subId; } function pickRandomUniqueId(uint256 random) private returns (uint256 tokenId) { uint256 len = totalSupply - mintCount++; require(len > 0, "All tokens have been minted"); uint256 randomIndex = random % len; tokenId = ids[randomIndex] != 0 ? ids[randomIndex] : randomIndex; ids[randomIndex] = ids[len - 1] == 0 ? len - 1 : ids[len - 1]; ids[len - 1] = 0; } function getRandomOnchain() public view returns (uint256) { bytes32 randomBytes = keccak256(abi.encodePacked(blockhash(block.number - 1), msg.sender, block.timestamp)); return uint256(randomBytes); } function mintRandomOnchain() public { uint256 tokenId = pickRandomUniqueId(getRandomOnchain()); _mint(msg.sender, tokenId); } function mintRandomVRF() public { requestId = s_vrfCoordinator.requestRandomWords( VRFV2PlusClient.RandomWordsRequest({ keyHash: keyHash, subId: subId, requestConfirmations: requestConfirmations, callbackGasLimit: callbackGasLimit, numWords: numWords, extraArgs: VRFV2PlusClient._argsToBytes(VRFV2PlusClient.ExtraArgsV1({nativePayment: false}) ) }) ); requestToSender[requestId] = msg.sender; } function fulfillRandomWords(uint256 requestId, uint256[] calldata randomWords) internal override { address sender = requestToSender[requestId]; uint256 tokenId = pickRandomUniqueId(randomWords[0]); _mint(sender, tokenId); } }
subId 由 uint64 更改为 uint256
新合约继承 VRFConsumerBaseV2Plus,s_vrfCoordinator 在 VRFConsumerBaseV2Plus.sol 初始化为 IVRFCoordinatorV2Plus 类型的实例
s_vrfCoordinator.requestRandomWords 调用了接口 IVRFCoordinatorV2Plus.sol 的 requestRandomWords 来获取 requestId,其具体实现在合约 VRFCoordinatorV2_5.sol 中
Chainlink 从 VRF v2 迁移 官方文档
下周我有空去看一下
subId 由 uint64 更改为 uint256
新合约继承 VRFConsumerBaseV2Plus,s_vrfCoordinator 在 VRFConsumerBaseV2Plus.sol 初始化为 IVRFCoordinatorV2Plus 类型的实例
s_vrfCoordinator.requestRandomWords 调用了接口 IVRFCoordinatorV2Plus.sol 的 requestRandomWords 来获取 requestId,其具体实现在合约 VRFCoordinatorV2_5.sol 中
Chainlink 从 VRF v2 迁移 官方文档