Created
June 6, 2024 15:48
-
-
Save QingyangKong/52b0a096b47d4263651a70d510ab1057 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// SPDX-License-Identifier: MIT | |
// Compatible with OpenZeppelin Contracts ^5.0.0 | |
pragma solidity ^0.8.20; | |
import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; | |
import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; | |
import "@openzeppelin/contracts/access/Ownable.sol"; | |
import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol"; | |
import {VRFConsumerBaseV2Plus} from "@chainlink/contracts/src/v0.8/vrf/dev/VRFConsumerBaseV2Plus.sol"; | |
import {VRFV2PlusClient} from "@chainlink/contracts/src/v0.8/vrf/dev/libraries/VRFV2PlusClient.sol"; | |
contract MyToken is ERC721, ERC721URIStorage, VRFConsumerBaseV2Plus { | |
uint256 private _nextTokenId; | |
// metadata for NFT | |
string constant METADATA_SHIBAINU = "ipfs://QmXw7TEAJWKjKifvLE25Z9yjvowWk2NWY3WgnZPUto9XoA"; | |
string constant METADATA_HUSKY = "ipfs://QmTFXZBmmnSANGRGhRVoahTTVPJyGaWum8D3YicJQmG97m"; | |
string constant METADATA_BULLDOG = "ipfs://QmSM5h4WseQWATNhFWeCbqCTAGJCZc11Sa1P5gaXk38ybT"; | |
// minimum payment | |
uint256 constant MINIMUM_PAYMENT = 1 * 10 ** 18; // 1usd (wei) | |
// Data feed | |
AggregatorV3Interface dataFeed; | |
// vrf config | |
uint256 public s_subscriptionId; | |
bytes32 public keyHash =0x787d74caea10b2b357790d5b5247c2f63d1d91572a9846f780606e4d953677ae; | |
uint32 public callbackGasLimit = 500000; | |
uint16 public requestConfirmations = 3; | |
uint32 public numWords = 1; | |
//mapping for tokenId and reqId | |
mapping(uint256 => uint256) public reqIdToTokenId; | |
constructor(uint256 subId) | |
ERC721("MyToken", "MTK") | |
VRFConsumerBaseV2Plus(0x9DdfaCa8183c41ad55329BdeeD9F6A8d53168B1B) | |
{ | |
// this is hardcoded for Sepolia | |
dataFeed = AggregatorV3Interface(0x694AA1769357215DE4FAC081bf1f309aDC325306); | |
s_subscriptionId = subId; | |
} | |
// make sure the minter pay minimum eth to mint a nft | |
function safeMint() public payable { | |
require(convertEthToUsd(msg.value) > MINIMUM_PAYMENT, "Please send more ETH"); // msg.valeu amount of eth, MIMI value of usd | |
uint256 tokenId = _nextTokenId++; | |
_safeMint(msg.sender, tokenId); | |
// send a vrf request | |
uint256 requestId; | |
requestId = s_vrfCoordinator.requestRandomWords( | |
VRFV2PlusClient.RandomWordsRequest({ | |
keyHash: keyHash, | |
subId: s_subscriptionId, | |
requestConfirmations: requestConfirmations, | |
callbackGasLimit: callbackGasLimit, | |
numWords: numWords, | |
extraArgs: VRFV2PlusClient._argsToBytes( | |
VRFV2PlusClient.ExtraArgsV1({ | |
nativePayment: false | |
}) | |
) | |
}) | |
); | |
reqIdToTokenId[requestId] = tokenId; | |
} | |
function fulfillRandomWords( | |
uint256 _requestId, | |
uint256[] calldata _randomWords | |
) internal override { | |
uint256 tokenId = reqIdToTokenId[_requestId]; | |
uint256 randomNumber = _randomWords[0] % 3; | |
if(randomNumber == 0) { | |
//case 1 | |
_setTokenURI(tokenId, METADATA_SHIBAINU); | |
} else if(randomNumber == 1) { | |
// case 2 | |
_setTokenURI(tokenId, METADATA_HUSKY); | |
} else { | |
// case 3 | |
_setTokenURI(tokenId, METADATA_BULLDOG); | |
} | |
} | |
function convertEthToUsd(uint256 ethAmount) public view returns (uint256) { | |
// value of ethAmount | |
return ethAmount * uint256(getChainlinkDataFeedLatestAnswer()) / 10 ** 8; | |
} | |
function getChainlinkDataFeedLatestAnswer() public view returns (int) { | |
// prettier-ignore | |
( | |
/* uint80 roundID */, | |
int answer, | |
/*uint startedAt*/, | |
/*uint timeStamp*/, | |
/*uint80 answeredInRound*/ | |
) = dataFeed.latestRoundData(); | |
return answer; | |
} | |
// The following functions are overrides required by Solidity. | |
function tokenURI(uint256 tokenId) | |
public | |
view | |
override(ERC721, ERC721URIStorage) | |
returns (string memory) | |
{ | |
return super.tokenURI(tokenId); | |
} | |
function supportsInterface(bytes4 interfaceId) | |
public | |
view | |
override(ERC721, ERC721URIStorage) | |
returns (bool) | |
{ | |
return super.supportsInterface(interfaceId); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment