-
Notifications
You must be signed in to change notification settings - Fork 2.2k
Open
Labels
bugSomething isn't workingSomething isn't working
Description
// 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 迁移 官方文档
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working