एनएफटी के लिए एक लोकप्रिय और व्यावहारिक उपयोग मामला लाइव इवेंट के लिए टिकट तैयार कर रहा है। एथेरियम जैसे ब्लॉकचेन एक डिजिटल आइटम के स्वामित्व, प्रवर्तक और प्रामाणिकता की गारंटी दे सकते हैं, नकली टिकटों की समस्या को प्रभावी ढंग से हल कर सकते हैं। जबकि टिकटमास्टर जैसे प्रमुख खिलाड़ी स्कैल्पर्स को कम करने के लिए संघर्ष करते हैं (यह नियंत्रित करने के लिए सख्त कोशिश कर रहे हैं कि कौन टिकटों को पुनर्विक्रय कर सकता है, कहां और कितने के लिए) और टिकट धोखाधड़ी- वेब 3 के पास पहले से ही एक समाधान है। टिकटिंग उद्योग व्यवधान के लिए परिपक्व है।
इस ट्यूटोरियल में, हम देखेंगे कि ConsenSys Truffle , Infura और Infura NFT API का उपयोग करके इस तरह का टिकटिंग समाधान कैसे बनाया जाए। हम एक स्मार्ट अनुबंध तैनात करेंगे जो टिकटिंग सेवा के रूप में कार्य करता है और ERC-20 अपूरणीय टोकन (NFTs) के रूप में टिकट बनाता है। हम संभावित फ़्रंटएंड के कुछ आर्किटेक्चर के माध्यम से भी चलेंगे जो अनुबंध के साथ इंटरफेस कर सकते हैं, और एक एकीकृत, पूर्ण-स्टैक, वेब3 टिकटिंग सिस्टम के रूप में कार्य कर सकते हैं।
चलो निर्माण करते हैं!
हमारे सिस्टम की बुनियादी वास्तुकला का उद्देश्य एक स्मार्ट अनुबंध बनाना है जो हमारे टिकटों को अपूरणीय टोकन (एनएफटी) के रूप में जारी करता है। एनएफटी हम जो बनाना चाहते हैं उसके लिए एकदम सही हैं। वे सिद्ध रूप से अद्वितीय डिजिटल टोकन हैं जो हमें यह सुनिश्चित करने की अनुमति देते हैं कि प्रत्येक टिकट अद्वितीय है और उसकी नकल या जाली नहीं की जा सकती है। यह न केवल कॉन्सर्ट जाने वालों के लिए एक सुरक्षित टिकटिंग अनुभव की गारंटी देता है, बल्कि टिकट वितरण, मूल्य निर्धारण और पुनर्विक्रय पर अधिक नियंत्रण के साथ कलाकारों (और इवेंट आयोजकों) को भी सशक्त बनाता है। स्मार्ट कॉन्ट्रैक्ट्स और एनएफटी का उपयोग करने से रॉयल्टी भुगतान और रेवेन्यू शेयरिंग जैसे नए रेवेन्यू स्ट्रीम की भी अनुमति मिलती है!
(यदि आपको इनमें से किसी भी शब्द, ब्लॉकचेन तकनीक, या सामान्य रूप से वेब3 पर पृष्ठभूमि की जानकारी चाहिए, तो इस लेख को वेब3 स्टैक एक्सप्लोर करके वेब3 डेवलपर बनने के बारे में जानें)।
पहला काम जो हम करने जा रहे हैं वह है एक मेटामास्क वॉलेट सेट करना और उसमें सेपोलिया परीक्षण नेटवर्क जोड़ना। मेटामास्क दुनिया का सबसे लोकप्रिय, सुरक्षित और इस्तेमाल में आसान सेल्फ-कस्टोडियल डिजिटल वॉलेट है।
सबसे पहले, मेटामास्क एक्सटेंशन डाउनलोड करें । आपके द्वारा एक्सटेंशन इंस्टॉल करने के बाद, मेटामास्क आपके लिए वॉलेट सेट करेगा। इस प्रक्रिया में, आपको एक गुप्त मुहावरा दिया जाएगा। इसे सुरक्षित रखें, और किसी भी परिस्थिति में आपको इसे सार्वजनिक नहीं करना चाहिए।
मेटामास्क सेट करने के बाद, ऊपर दाईं ओर स्थित नेटवर्क टैब पर क्लिक करें। आपको टेस्ट नेटवर्क दिखाने/छिपाने का विकल्प दिखाई देगा।
एक बार जब आप परीक्षण नेटवर्क चालू कर देते हैं, तो आपको ड्रॉप-डाउन मेनू में सेपोलिया परीक्षण नेटवर्क देखने में सक्षम होना चाहिए। हम सेपोलिया नेटवर्क का उपयोग करना चाहते हैं ताकि हम बिना कोई वास्तविक पैसा खर्च किए अपने सिस्टम को तैनात और परीक्षण कर सकें।
हमारे स्मार्ट अनुबंध को तैनात करने और इसके साथ बातचीत करने के लिए, हमें कुछ निःशुल्क परीक्षण ETH की आवश्यकता होगी। आप सेपोलिया नल से निःशुल्क सेपोलिया ईटीएच प्राप्त कर सकते हैं।
एक बार जब आप अपने बटुए को निधि देते हैं, तो आपको मेटामास्क पर सेपोलिया परीक्षण नेटवर्क पर स्विच करने पर एक गैर-शून्य शेष राशि दिखाई देनी चाहिए।
सभी एथेरियम डैप की तरह, हम नोड और एनपीएम का उपयोग करके अपनी परियोजना का निर्माण करेंगे। यदि आपके पास ये आपके स्थानीय मशीन पर स्थापित नहीं हैं, तो आप यहां ऐसा कर सकते हैं।
यह सुनिश्चित करने के लिए कि सब कुछ ठीक से काम कर रहा है, निम्नलिखित कमांड चलाएँ:
$ node -v
यदि सब कुछ ठीक रहा, तो आपको नोड के लिए संस्करण संख्या देखनी चाहिए।
हमारे अनुबंध को सेपोलिया नेटवर्क में परिनियोजित करने के लिए, हमें एक Infura खाते की आवश्यकता होगी। इन्फ्यूरा हमें आरपीसी एंडपॉइंट्स तक पहुंच प्रदान करता है जो हमारी पसंद के ब्लॉकचेन तक तेज, विश्वसनीय और आसान पहुंच की अनुमति देता है।
मुफ़्त खाते के लिए साइन अप करें । अपना खाता बना लेने के बाद, डैशबोर्ड पर नेविगेट करें और नई कुंजी बनाएं चुनें.
नेटवर्क के लिए, Web3 API चुनें और इसे टिकटिंग सिस्टम , या अपनी पसंद का कुछ नाम दें।
एक बार जब आप Create पर क्लिक करते हैं, तो Infura आपके लिए एक API कुंजी उत्पन्न करेगा और आपको Ethereum, Goerli, Sepolia, L2s, और गैर-EVM L1s (और उनके संबंधित टेस्टनेट) को स्वचालित रूप से RPC समापन बिंदु देगा।
इस ट्यूटोरियल के लिए, हम केवल सेपोलिया आरपीसी समापन बिंदु में रुचि रखते हैं। यह URL फॉर्म का है https://sepolia.infura.io/v3/←API KEY→
आइए निम्नलिखित कमांड चलाकर एक खाली प्रोजेक्ट रिपॉजिटरी सेट करें:
$ mkdir nft-ticketing && cd nft-ticketing $ npm init -y
हम अपने क्रिप्टोक्यूरेंसी स्मार्ट अनुबंध को बनाने और तैनात करने के लिए ईवीएम स्मार्ट अनुबंधों के लिए विश्व स्तरीय विकास पर्यावरण और परीक्षण ढांचे ट्रफल का उपयोग करेंगे। चलाकर ट्रफल स्थापित करें:
$ npm install —save truffle
अब हम निम्नलिखित कमांड चलाकर एक बेयरबोन ट्रफल प्रोजेक्ट बना सकते हैं:
$ npx truffle init
यह जांचने के लिए कि क्या सब कुछ ठीक से काम करता है, दौड़ें:
$ npx truffle test
अब हमारे पास ट्रफल सफलतापूर्वक कॉन्फ़िगर हो गया है। अब हम आगे OpenZeppelin संविदा पैकेज स्थापित करते हैं। यह पैकेज हमें ERC-721 आधार कार्यान्वयन (अपूरणीय टोकन के लिए मानक) के साथ-साथ कुछ सहायक अतिरिक्त कार्यात्मकताओं तक पहुंच प्रदान करेगा।
$ npm install @openzeppelin/contracts
Truffle को हमारे मेटामास्क वॉलेट का उपयोग करने, लेन-देन पर हस्ताक्षर करने और हमारी ओर से गैस का भुगतान करने की अनुमति देने के लिए, हमें hdwalletprovider
नामक एक अन्य पैकेज की आवश्यकता होगी। निम्न आदेश का उपयोग कर इसे स्थापित करें:
$ npm install @truffle/hdwallet-provider
अंत में, अपनी संवेदनशील वॉलेट जानकारी को सुरक्षित रखने के लिए, हम dotenv
पैकेज का उपयोग करेंगे।
$ npm install dotenv
एक कोड संपादक में प्रोजेक्ट रिपॉजिटरी खोलें (उदाहरण के लिए: वीएस कोड)। contracts
फ़ोल्डर में, NftTicketing.sol
नामक एक नई फ़ाइल बनाएँ।
हमारा टिकटिंग अनुबंध OpenZeppelin के ERC721Enumerable
कार्यान्वयन द्वारा प्रदान की जाने वाली सभी कार्यात्मकताओं को इनहेरिट करेगा। इसमें स्थानान्तरण, मेटाडेटा ट्रैकिंग, स्वामित्व डेटा आदि शामिल हैं।
हम निम्नलिखित सुविधाओं को बिल्कुल शुरू से लागू करेंगे:
निम्नलिखित कोड को NftTicketing.sol
में जोड़ें।
//SPDX-License-Identifier: MIT pragma solidity ^0.8.19; import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; import "@openzeppelin/contracts/utils/Base64.sol"; import "@openzeppelin/contracts/utils/Strings.sol"; contract NftTicketing is ERC721, ERC721Enumerable, ERC721URIStorage, Ownable { using Counters for Counters.Counter; Counters.Counter private _tokenIds; // Total number of tickets available for the event uint public constant MAX_SUPPLY = 10000; // Number of tickets you can book at a time; prevents spamming uint public constant MAX_PER_MINT = 5; string public baseTokenURI; // Price of a single ticket uint public price = 0.05 ether; // Flag to turn sales on and off bool public saleIsActive = false; // Give collection a name and a ticker constructor() ERC721("My NFT Tickets", "MNT") {} // Generate NFT metadata function generateMetadata(uint tokenId) public pure returns (string memory) { string memory svg = string(abi.encodePacked( "<svg xmlns='http://www.w3.org/2000/svg' preserveAspectRatio='xMinyMin meet' viewBox='0 0 350 350'>", "<style>.base { fill: white; font-family: serif; font-size: 25px; }</style>", "<rect width='100%' height='100%' fill='red' />", "<text x='50%' y='40%' class='base' dominant-baseline='middle' text-anchor='middle'>", "<tspan y='50%' x='50%'>NFT Ticket #", Strings.toString(tokenId), "</tspan></text></svg>" )); string memory json = Base64.encode( bytes( string( abi.encodePacked( '{"name": "NFT Ticket #', Strings.toString(tokenId), '", "description": "A ticket that gives you access to a cool event!", "image": "data:image/svg+xml;base64,', Base64.encode(bytes(svg)), '", "attributes": [{"trait_type": "Type", "value": "Base Ticket"}]}' ) ) ) ); string memory metadata = string( abi.encodePacked("data:application/json;base64,", json) ); return metadata; } // Reserve tickets to creator wallet function reserveNfts(uint _count) public onlyOwner { uint nextId = _tokenIds.current(); require(nextId + _count < MAX_SUPPLY, "Not enough NFTs left to reserve"); for (uint i = 0; i < _count; i++) { string memory metadata = generateMetadata(nextId + i); _mintSingleNft(msg.sender, metadata); } } // Airdrop NFTs function airDropNfts(address[] calldata _wAddresses) public onlyOwner { uint nextId = _tokenIds.current(); uint count = _wAddresses.length; require(nextId + count < MAX_SUPPLY, "Not enough NFTs left to reserve"); for (uint i = 0; i < count; i++) { string memory metadata = generateMetadata(nextId + i); _mintSingleNft(_wAddresses[i], metadata); } } // Set Sale state function setSaleState(bool _activeState) public onlyOwner { saleIsActive = _activeState; } // Allow public to mint NFTs function mintNfts(uint _count) public payable { uint nextId = _tokenIds.current(); require(nextId + _count < MAX_SUPPLY, "Not enough NFT tickets left!"); require(_count > 0 && _count <= MAX_PER_MINT, "Cannot mint specified number of NFT tickets."); require(saleIsActive, "Sale is not currently active!"); require(msg.value >= price * _count, "Not enough ether to purchase NFTs."); for (uint i = 0; i < _count; i++) { string memory metadata = generateMetadata(nextId + i); _mintSingleNft(msg.sender, metadata); } } // Mint a single NFT ticket function _mintSingleNft(address _wAddress, string memory _tokenURI) private { // Sanity check for absolute worst case scenario require(totalSupply() == _tokenIds.current(), "Indexing has broken down!"); uint newTokenID = _tokenIds.current(); _safeMint(_wAddress, newTokenID); _setTokenURI(newTokenID, _tokenURI); _tokenIds.increment(); } // Update price function updatePrice(uint _newPrice) public onlyOwner { price = _newPrice; } // Withdraw ether function withdraw() public payable onlyOwner { uint balance = address(this).balance; require(balance > 0, "No ether left to withdraw"); (bool success, ) = (msg.sender).call{value: balance}(""); require(success, "Transfer failed."); } // Get tokens of an owner function tokensOfOwner(address _owner) external view returns (uint[] memory) { uint tokenCount = balanceOf(_owner); uint[] memory tokensId = new uint256[](tokenCount); for (uint i = 0; i < tokenCount; i++) { tokensId[i] = tokenOfOwnerByIndex(_owner, i); } return tokensId; } // The following functions are overrides required by Solidity. function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) internal override(ERC721, ERC721Enumerable) { super._beforeTokenTransfer(from, to, tokenId, batchSize); } function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) { super._burn(tokenId); } function tokenURI(uint256 tokenId) public view override(ERC721, ERC721URIStorage) returns (string memory) { return super.tokenURI(tokenId); } function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC721Enumerable) returns (bool) { return super.supportsInterface(interfaceId); } }
सुनिश्चित करें कि अनुबंध चलाकर सही ढंग से संकलन कर रहा है:
npx truffle compile
हमारा अनुबंध पहले से ही काफी जटिल है, लेकिन जैसा कि आप फिट देखते हैं, कुछ अतिरिक्त सुविधाओं को जोड़ना संभव है।
उदाहरण के लिए, आप अपने अनुबंध के भीतर एक एंटी-स्केलिंग तंत्र लागू कर सकते हैं। ऐसा करने के चरण इस प्रकार होंगे:
अनुबंध के निर्माता के नीचे निम्नलिखित स्निपेट जोड़ें:
mapping(address => bool) canMintMultiple; // Function that allowlists addresses to hold multiple NFTs. function addToAllowlist(address[] calldata _wAddresses) public onlyOwner { for (uint i = 0; i < _wAddresses.length; i++) { canMintMultiple[_wAddresses[i]] = true; } }
अंत में, निम्नलिखित के लिए _ beforeTokenTranfer फ़ंक्शन को संशोधित करें:
// The following functions are overrides required by Solidity. function _beforeTokenTransfer(address from, address to, uint256 tokenId, uint256 batchSize) internal override(ERC721, ERC721Enumerable) { if (balanceOf(to) > 0) { require(to == owner() || canMintMultiple[to], "Not authorized to hold more than one ticket"); } super._beforeTokenTransfer(from, to, tokenId, batchSize); }
उपरोक्त ट्रफल कमांड का उपयोग करके एक बार फिर से अनुबंध को संकलित करें।
प्रोजेक्ट की रूट डायरेक्टरी में .env
नामक एक नई फ़ाइल बनाएँ और निम्नलिखित सामग्री जोड़ें:
INFURA_API_KEY = "https://sepolia.infura.io/v3/<Your-API-Key>" MNEMONIC = "<Your-MetaMask-Secret-Recovery-Phrase>"
इसके बाद, आइए अपने ट्रफल कॉन्फ़िगरेशन फ़ाइल में अपने वॉलेट, इन्फ्यूरा आरपीसी एंडपॉइंट और सेपोलिया नेटवर्क के बारे में जानकारी जोड़ें। निम्नलिखित के साथ truffle.config.js
की सामग्री को बदलें:
require('dotenv').config(); const HDWalletProvider = require('@truffle/hdwallet-provider'); const { INFURA_API_KEY, MNEMONIC } = process.env; module.exports = { networks: { development: { host: "127.0.0.1", port: 8545, network_id: "*" }, sepolia: { provider: () => new HDWalletProvider(MNEMONIC, INFURA_API_KEY), network_id: '5', } } };
आइए अब हम अपने अनुबंध को सेपोलिया ब्लॉकचेन में तैनात करने के लिए एक स्क्रिप्ट लिखते हैं।
migrations
फ़ोल्डर में, 1_deploy_contract.js
नामक एक नई फ़ाइल बनाएँ और निम्न कोड जोड़ें:
// Get instance of the NFT contract const nftContract = artifacts.require("NftTicketing"); module.exports = async function (deployer) { // Deploy the contract await deployer.deploy(nftContract); const contract = await nftContract.deployed(); // Mint 5 tickets await contract.reserveNfts(5); console.log("5 NFT Tickets have been minted!") };
हम पूरी तरह तैयार हैं! निम्न आदेश चलाकर अनुबंध परिनियोजित करें:
truffle migrate --network sepolia
यदि सब ठीक हो जाता है, तो आपको आउटपुट (अनुबंध पता युक्त) देखना चाहिए जो कुछ इस तरह दिखता है:
Starting migrations... ====================== > Network name: 'sepolia' > Network id: 5 > Block gas limit: 30000000 (0x1c9c380) 1_deploy_contract.js ==================== Deploying 'NftTicketing' ----------------------- > transaction hash: … > Blocks: 2 Seconds: 23 … > Saving artifacts ------------------------------------- > Total cost: 0.1201 ETH Summary ======= > Total deployments: 1 > Final cost: 0.1201 ETH
आप सेपोलिया इथरस्कैन पर अपना अनुबंध पता खोज सकते हैं और इसे लाइव देख सकते हैं।
बधाई हो! आपने सेपोलिया में अनुबंध को सफलतापूर्वक लागू कर दिया है।
चरण 9: स्मार्ट अनुबंध के साथ इंटरफेस
हमारे पास हमारा स्मार्ट अनुबंध है! अगला कदम उस इंटरफ़ेस को अनुबंध के साथ तैनात करना है और किसी को भी दान करने के लिए मिंट फ़ंक्शन को कॉल करने और अपने लिए टिकट बनाने की अनुमति देना है।
पूरी तरह कार्यात्मक टिकटिंग सेवा के लिए, आपको आमतौर पर निम्नलिखित फ़्रंटएंड की आवश्यकता होगी:
इन प्रणालियों को खरोंच से बनाना इस ट्यूटोरियल के दायरे से बाहर है, लेकिन हम आपको कुछ संसाधनों और युक्तियों के साथ छोड़ देंगे।
फ्रंटएंड मिंटिंग वेबसाइट के लिए, शुरुआती बिंदु के रूप में थैंक यू एनएफटी ट्यूटोरियल में बनाए गए फ्रंटएंड को देखें।
यदि आप इथरस्कैन पर अपना अनुबंध सत्यापित करते हैं, तो यह स्वचालित रूप से आपको एक व्यवस्थापक पोर्टल देगा जहां आप अपने अनुबंध पर किसी भी फ़ंक्शन को कॉल कर सकते हैं। कस्टम समाधान बनाने का निर्णय लेने से पहले यह एक अच्छा पहला कदम है।
यह सत्यापित करना कि आपके संग्रह से एक वॉलेट का टिकट है, balanceOf
फ़ंक्शन का उपयोग करके बेहद सरल है। अगर कोई यह साबित कर सकता है कि उनके पास हमारे टिकटों में से एक वाला बटुआ है, तो यह मूल रूप से सबूत है कि उनके पास टिकट है। इसे डिजिटल सिग्नेचर के जरिए हासिल किया जा सकता है।
एक और संकेत: एक बार जब आपके पास आपका स्मार्ट कॉन्ट्रैक्ट और फ्रंटएंड (या इससे पहले कि आपका फ्रंटएंड पूरा हो जाए और आप यह साबित करना चाहते हैं कि सब कुछ काम करता है), तो आप यह सत्यापित करने के लिए इंफुरा एनएफटी एपीआई का उपयोग कर सकते हैं कि आपका नया एनएफटी मौजूद है। Infura NFT API बहुत सारे NFT- संबंधित कोड को एक ही API कॉल से बदलने का एक त्वरित तरीका है।
उदाहरण के लिए, हमें अपने एनएफटी का स्वामित्व दिखाने के लिए आवश्यक जानकारी एपीआई के माध्यम से हमारे लिए आसानी से उपलब्ध है। हमें केवल बटुए का पता देने की जरूरत है। कोड कुछ इस तरह दिखेगा:
const walletAddress = <your wallet address> const chainId = "1" const baseUrl = "https://nft.api.infura.io" const url = `${baseUrl}/networks/${chainId}/accounts/${walletAddress}/assets/nfts` // API request const config = { method: 'get', url: url, auth: { username: '<-- INFURA_API_KEY –>', password: '<-- INFURA_API_SECRET –>', } }; // API Request axios(config) .then(response => { console.log(response['data']) }) .catch(error => console.log('error', error));
इसे चलाने के लिए …
$ node <filename>.js
और आपको ऐसा कुछ देखना चाहिए:
{ total: 1, pageNumber: 1, pageSize: 100, network: 'ETHEREUM', account: <account address>, cursor: null, assets: [ { contract: <NFT contract address>, tokenId: '0', supply: '1', type: 'ERC20', metadata: [Object] }, … ] }
इस ट्यूटोरियल में, हमने Truffle , Infura और Infura NFT API का उपयोग करके पूरी तरह कार्यात्मक NFT टिकटिंग सेवा तैनात की।
यह स्पष्ट रूप से टिकटमास्टर को बाधित करने के लिए आवश्यक सब कुछ नहीं है - लेकिन यह एक ठोस शुरुआत है और अवधारणा का एक बड़ा प्रमाण है! यहां तक कि अगर आप इस कोड को नहीं लेते हैं और अपना खुद का एनएफटी टिकटिंग प्लेटफॉर्म शुरू करते हैं, तो उम्मीद है कि आपने इस प्रक्रिया में वेब3 के बारे में कुछ सीखा है।
इस लेख की मुख्य छवि हैकरनून केएआई इमेज जेनरेटर द्वारा "एक बड़े स्टेडियम में एक रॉक कॉन्सर्ट" के माध्यम से तैयार की गई थी।