स्मार्ट अनुबंधों की संरचना
पेज का अंतिम अपडेट: 23 फ़रवरी 2026
एक स्मार्ट अनुबंध एक प्रोग्राम है जो एथेरियम पर एक पते पर चलता है। वे डेटा और फंक्शंस से बने होते हैं जो लेनदेन प्राप्त करने पर निष्पादित हो सकते हैं। स्मार्ट अनुबंध क्या होता है, इसका अवलोकन यहां दिया गया है।
पूर्वापेक्षाएं
पहले सुनिश्चित करें कि आपने स्मार्ट अनुबंधों के बारे में पढ़ा है। यह दस्तावेज़ मानता है कि आप जावास्क्रिप्ट या पायथन जैसी प्रोग्रामिंग भाषाओं से पहले से ही परिचित हैं।
डेटा
किसी भी अनुबंध डेटा को एक स्थान पर निर्दिष्ट किया जाना चाहिए: या तो storage या memory पर। स्मार्ट अनुबंध में भंडारण को संशोधित करना महंगा है, इसलिए आपको यह विचार करने की आवश्यकता है कि आपका डेटा कहां रहना चाहिए।
भंडारण
लगातार डेटा को भंडारण के रूप में संदर्भित किया जाता है और इसे स्टेट वेरिएबल्स द्वारा दर्शाया जाता है। ये मान ब्लॉकचेन पर स्थायी रूप से संग्रहित हो जाते हैं। आपको प्रकार घोषित करने की आवश्यकता है ताकि अनुबंध इस बात पर नज़र रख सके कि संकलित होने पर ब्लॉकचेन पर उसे कितने भंडारण की आवश्यकता है।
1// Solidity उदाहरण2contract SimpleStorage {3 uint storedData; // स्टेट वैरिएबल4 // ...5}1# Vyper उदाहरण2storedData: int128यदि आपने पहले से ही ऑब्जेक्ट-ओरिएंटेड भाषाओं को प्रोग्राम किया है, तो आप संभवतः अधिकांश प्रकारों से परिचित होंगे। हालांकि, यदि आप एथेरियम विकास में नए हैं तो address आपके लिए नया होना चाहिए।
एक address प्रकार एक एथेरियम पता रख सकता है जो 20 बाइट्स या 160 बिट्स के बराबर होता है। यह हेक्साडेसिमल नोटेशन में अग्रणी 0x के साथ लौटता है।
अन्य प्रकारों में शामिल हैं:
- बूलियन
- पूर्णांक
- निश्चित बिंदु संख्याएँ
- निश्चित आकार की बाइट सरणियाँ
- गतिशील आकार की बाइट सरणियाँ
- परिमेय और पूर्णांक लिटरल
- स्ट्रिंग लिटरल
- हेक्साडेसिमल लिटरल
- एनम्स
अधिक स्पष्टीकरण के लिए, दस्तावेज़ों पर एक नज़र डालें:
मेमोरी
मान जो केवल अनुबंध फंक्शन के निष्पादन के जीवनकाल के लिए संग्रहित होते हैं, उन्हें मेमोरी वेरिएबल्स कहा जाता है। चूंकि ये ब्लॉकचेन पर स्थायी रूप से संग्रहित नहीं होते हैं, इसलिए इनका उपयोग करना बहुत सस्ता होता है।
सॉलिडिटी डॉक्स (opens in a new tab) में EVM डेटा (स्टोरेज, मेमोरी और स्टैक) कैसे संग्रहीत करता है, इसके बारे में अधिक जानें।
पर्यावरण वैरिएबल
आपके अनुबंध पर आपके द्वारा परिभाषित वेरिएबल्स के अलावा, कुछ विशेष वैश्विक वेरिएबल्स हैं। वे मुख्य रूप से ब्लॉकचेन या वर्तमान लेनदेन के बारे में जानकारी प्रदान करने के लिए उपयोग किए जाते हैं।
उदाहरण
| प्रॉप | स्टेट वेरिएबल | विवरण |
|---|---|---|
block.timestamp | uint256 | वर्तमान ब्लॉक युग टाइमस्टैम्प |
msg.sender | पता | संदेश का प्रेषक (वर्तमान कॉल) |
फ़ंक्शन
सबसे सरल शब्दों में, फंक्शंस आने वाले लेनदेन के जवाब में जानकारी प्राप्त कर सकते हैं या जानकारी सेट कर सकते हैं।
फंक्शन कॉल दो प्रकार के होते हैं:
internal– ये EVM कॉल नहीं बनाते हैं- आंतरिक फ़ंक्शन और स्टेट वैरिएबल को केवल आंतरिक रूप से एक्सेस किया जा सकता है (यानी, वर्तमान अनुबंध या इससे प्राप्त होने वाले अनुबंधों के भीतर से)
external– ये EVM कॉल बनाते हैं- बाहरी फंक्शंस अनुबंध इंटरफ़ेस का हिस्सा हैं, जिसका अर्थ है कि उन्हें अन्य अनुबंधों से और लेनदेन के माध्यम से कॉल किया जा सकता है। एक बाहरी फ़ंक्शन
fको आंतरिक रूप से कॉल नहीं किया जा सकता है (यानी,f()काम नहीं करता है, लेकिनthis.f()काम करता है)।
- बाहरी फंक्शंस अनुबंध इंटरफ़ेस का हिस्सा हैं, जिसका अर्थ है कि उन्हें अन्य अनुबंधों से और लेनदेन के माध्यम से कॉल किया जा सकता है। एक बाहरी फ़ंक्शन
वे public या private भी हो सकते हैं
publicफ़ंक्शन को अनुबंध के भीतर से आंतरिक रूप से या संदेशों के माध्यम से बाहरी रूप से कॉल किया जा सकता हैprivateफ़ंक्शन केवल उस अनुबंध के लिए दिखाई देते हैं जिसमें उन्हें परिभाषित किया गया है और व्युत्पन्न अनुबंधों में नहीं
दोनों फंक्शंस और स्टेट वेरिएबल्स को सार्वजनिक या निजी बनाया जा सकता है
अनुबंध पर एक स्टेट वेरिएबल्स को अपडेट करने के लिए एक फंक्शन यहां है:
1// Solidity उदाहरण2function update_name(string value) public {3 dapp_name = value;4}- प्रकार
stringका पैरामीटरvalueफ़ंक्शन:update_nameमें पास किया जाता है - इसे
publicघोषित किया गया है, जिसका अर्थ है कि कोई भी इसे एक्सेस कर सकता है - इसे
viewघोषित नहीं किया गया है, इसलिए यह अनुबंध की स्थिति को संशोधित कर सकता है
व्यू फ़ंक्शन
ये फंक्शंस अनुबंध के डेटा की स्थिति को संशोधित नहीं करने का वादा करते हैं। सामान्य उदाहरण "गेटर" फंक्शंस हैं – उदाहरण के लिए आप इसका उपयोग यूज़र की शेष राशि प्राप्त करने के लिए कर सकते हैं।
1// Solidity उदाहरण2function balanceOf(address _owner) public view returns (uint256 _balance) {3 return ownerPizzaCount[_owner];4}1dappName: public(string)23@view4@public5def readName() -> string:6 return dappNameसंशोधित स्थिति क्या मानी जाती है:
- स्टेट वेरिएबल्स के लिए लेखन।
- इवेंट्स उत्सर्जित करना (opens in a new tab)।
- अन्य अनुबंध बनाना (opens in a new tab)।
selfdestructका उपयोग करना।- कॉल के माध्यम से ईथर भेजना।
- किसी भी ऐसे फ़ंक्शन को कॉल करना जो
viewयाpureके रूप में चिह्नित नहीं है। - निम्न-स्तरीय कॉल का उपयोग करना।
- इनलाइन असेंबली का उपयोग करना जिसमें कुछ ऑप्कोड होते हैं।
कंस्ट्रक्टर फ़ंक्शन
constructor फ़ंक्शन केवल एक बार निष्पादित होते हैं जब अनुबंध पहली बार परिनियोजित होता है। कई वर्ग-आधारित प्रोग्रामिंग भाषाओं में constructor की तरह, ये फ़ंक्शन अक्सर स्टेट वैरिएबल को उनके निर्दिष्ट मानों पर प्रारंभ करते हैं।
1// Solidity उदाहरण2// अनुबंध के डेटा को प्रारंभ करता है, `owner` को3// अनुबंध निर्माता के पते पर सेट करता है।4constructor() public {5 // सभी स्मार्ट अनुबंध अपने कार्यों को ट्रिगर करने के लिए बाहरी लेनदेन पर निर्भर करते हैं।6 // `msg` एक वैश्विक वैरिएबल है जिसमें दिए गए लेनदेन पर प्रासंगिक डेटा शामिल है,7 // जैसे प्रेषक का पता और लेनदेन में शामिल ETH मान।8 // और जानें: https://solidity.readthedocs.io/en/v0.5.10/units-and-global-variables.html#block-and-transaction-properties9 owner = msg.sender;10}सभी दिखाएँ1# Vyper उदाहरण23@external4def __init__(_beneficiary: address, _bidding_time: uint256):5 self.beneficiary = _beneficiary6 self.auctionStart = block.timestamp7 self.auctionEnd = self.auctionStart + _bidding_timeबिल्ट-इन फ़ंक्शन
आपके अनुबंध पर आपके द्वारा परिभाषित वेरिएबल्स और फंक्शंस के अलावा, कुछ विशेष बिल्ट-इन फंक्शंस हैं। सबसे स्पष्ट उदाहरण है:
address.send()– सॉलिडिटीsend(address)– वाइपर
ये अनुबंधों को ETH को अन्य खातों में भेजने की अनुमति देते हैं।
फ़ंक्शन लिखना
आपका फंक्शन निम्न आवश्यक करता है:
- पैरामीटर वेरिएबल और प्रकार (यदि यह पैरामीटर स्वीकार करता है)
- internal/external की घोषणा
- pure/view/payable की घोषणा
- रिटर्न प्रकार (यदि यह मान लौटाता है)
1pragma solidity >=0.4.0 <=0.6.0;23contract ExampleDapp {4 string dapp_name; // state variable56 // जब अनुबंध परिनियोजित होता है और मान को प्रारंभ करता है तब कॉल किया जाता है7 constructor() public {8 dapp_name = "My Example dapp";9 }1011 // फ़ंक्शन प्राप्त करें12 function read_name() public view returns(string) {13 return dapp_name;14 }1516 // फ़ंक्शन सेट करें17 function update_name(string value) public {18 dapp_name = value;19 }20}सभी दिखाएँएक पूर्ण अनुबंध कुछ इस तरह दिख सकता है। यहाँ constructor फ़ंक्शन dapp_name वैरिएबल के लिए एक प्रारंभिक मान प्रदान करता है।
इवेंट्स और लॉग
इवेंट्स आपके स्मार्ट अनुबंध को आपके फ़्रंटएंड या अन्य सदस्यता लेने वाले एप्लिकेशन के साथ संवाद करने में सक्षम बनाते हैं। एक बार लेनदेन मान्य हो जाने और एक ब्लॉक में जोड़े जाने के बाद, स्मार्ट अनुबंध इवेंट्स का उत्सर्जन कर सकते हैं और जानकारी लॉग कर सकते हैं, जिसे फ्रंटएंड तब संसाधित और उपयोग कर सकता है।
एनोटेट किए गए उदाहरण
ये सॉलिडिटी में लिखे गए कुछ उदाहरण हैं। यदि आप कोड के साथ खेलना चाहते हैं, तो आप रीमिक्स (opens in a new tab) में उनके साथ इंटरैक्ट कर सकते हैं।
हैलो वर्ल्ड
1// सिमेंटिक वर्जनिंग का उपयोग करते हुए, Solidity का संस्करण निर्दिष्ट करता है।2// और जानें: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#pragma3pragma solidity ^0.5.10;45// `HelloWorld` नामक एक अनुबंध को परिभाषित करता है।6// एक अनुबंध फ़ंक्शन और डेटा (इसकी स्थिति) का एक संग्रह है।7// एक बार परिनियोजित होने के बाद, एक अनुबंध Ethereum ब्लॉकचेन पर एक विशिष्ट पते पर रहता है।8// और जानें: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html9contract HelloWorld {1011 // `string` प्रकार के एक स्टेट वैरिएबल `message` की घोषणा करता है।12 // स्टेट वैरिएबल ऐसे वैरिएबल होते हैं जिनके मान अनुबंध भंडारण में स्थायी रूप से संग्रहीत होते हैं।13 // कीवर्ड `public` वैरिएबल को एक अनुबंध के बाहर से सुलभ बनाता है14 // और एक फ़ंक्शन बनाता है जिसे अन्य अनुबंध या क्लाइंट मान तक पहुंचने के लिए कॉल कर सकते हैं।15 string public message;1617 // कई वर्ग-आधारित ऑब्जेक्ट-ओरिएंटेड भाषाओं के समान, एक कंस्ट्रक्टर18 // एक विशेष फ़ंक्शन है जो केवल अनुबंध निर्माण पर निष्पादित होता है।19 // कंस्ट्रक्टर का उपयोग अनुबंध के डेटा को प्रारंभ करने के लिए किया जाता है।20 // और जानें: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constructors21 constructor(string memory initMessage) public {22 // एक स्ट्रिंग तर्क `initMessage` स्वीकार करता है और मान सेट करता है23 // अनुबंध के `message` भंडारण वैरिएबल में)।24 message = initMessage;25 }2627 // एक सार्वजनिक फ़ंक्शन जो एक स्ट्रिंग तर्क स्वीकार करता है28 // और `message` भंडारण वैरिएबल को अपडेट करता है।29 function update(string memory newMessage) public {30 message = newMessage;31 }32}सभी दिखाएँटोकन
1pragma solidity ^0.5.10;23contract Token {4 // एक `address` एक ईमेल पते के बराबर है - इसका उपयोग Ethereum पर एक खाते की पहचान करने के लिए किया जाता है।5 // पते एक स्मार्ट अनुबंध या बाहरी (उपयोगकर्ता) खातों का प्रतिनिधित्व कर सकते हैं।6 // और जानें: https://solidity.readthedocs.io/en/v0.5.10/types.html#address7 address public owner;89 // एक `mapping` अनिवार्य रूप से एक हैश टेबल डेटा संरचना है।10 // यह `mapping` एक अहस्ताक्षरित पूर्णांक (टोकन शेष) को एक पते (टोकन धारक) को निर्दिष्ट करता है।11 // और जानें: https://solidity.readthedocs.io/en/v0.5.10/types.html#mapping-types12 mapping (address => uint) public balances;1314 // इवेंट्स ब्लॉकचेन पर गतिविधि की लॉगिंग की अनुमति देते हैं।15 // अनुबंध की स्थिति में परिवर्तन पर प्रतिक्रिया करने के लिए Ethereum क्लाइंट इवेंट्स सुन सकते हैं।16 // और जानें: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#events17 event Transfer(address from, address to, uint amount);1819 // अनुबंध के डेटा को प्रारंभ करता है, `owner` को20 // अनुबंध निर्माता के पते पर सेट करता है।21 constructor() public {22 // सभी स्मार्ट अनुबंध अपने कार्यों को ट्रिगर करने के लिए बाहरी लेनदेन पर निर्भर करते हैं।23 // `msg` एक वैश्विक वैरिएबल है जिसमें दिए गए लेनदेन पर प्रासंगिक डेटा शामिल है,24 // जैसे प्रेषक का पता और लेनदेन में शामिल ETH मान।25 // और जानें: https://solidity.readthedocs.io/en/v0.5.10/units-and-global-variables.html#block-and-transaction-properties26 owner = msg.sender;27 }2829 // नए टोकन की एक राशि बनाता है और उन्हें एक पते पर भेजता है।30 function mint(address receiver, uint amount) public {31 // `require` एक नियंत्रण संरचना है जिसका उपयोग कुछ शर्तों को लागू करने के लिए किया जाता है।32 // यदि कोई `require` कथन `false` का मूल्यांकन करता है, तो एक अपवाद चालू हो जाता है,33 // जो वर्तमान कॉल के दौरान स्थिति में किए गए सभी परिवर्तनों को वापस कर देता है।34 // और जानें: https://solidity.readthedocs.io/en/v0.5.10/control-structures.html#error-handling-assert-require-revert-and-exceptions3536 // केवल अनुबंध का मालिक ही इस फ़ंक्शन को कॉल कर सकता है37 require(msg.sender == owner, "You are not the owner.");3839 // टोकन की अधिकतम राशि लागू करता है40 require(amount < 1e60, "Maximum issuance exceeded");4142 // `receiver` की शेष राशि को `amount` से बढ़ाता है43 balances[receiver] += amount;44 }4546 // किसी भी कॉलर से मौजूदा टोकन की एक राशि एक पते पर भेजता है।47 function transfer(address receiver, uint amount) public {48 // प्रेषक के पास भेजने के लिए पर्याप्त टोकन होने चाहिए49 require(amount <= balances[msg.sender], "Insufficient balance.");5051 // दो पतों के टोकन शेष को समायोजित करता है52 balances[msg.sender] -= amount;53 balances[receiver] += amount;5455 // पहले परिभाषित इवेंट का उत्सर्जन करता है56 emit Transfer(msg.sender, receiver, amount);57 }58}सभी दिखाएँअद्वितीय डिजिटल संपत्ति
1pragma solidity ^0.5.10;23// अन्य फ़ाइलों से प्रतीकों को वर्तमान अनुबंध में आयात करता है।4// इस मामले में, OpenZeppelin से सहायक अनुबंधों की एक श्रृंखला।5// और जानें: https://solidity.readthedocs.io/en/v0.5.10/layout-of-source-files.html#importing-other-source-files67import "../node_modules/@openzeppelin/contracts/token/ERC721/IERC721.sol";8import "../node_modules/@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";9import "../node_modules/@openzeppelin/contracts/introspection/ERC165.sol";10import "../node_modules/@openzeppelin/contracts/math/SafeMath.sol";1112// `is` कीवर्ड का उपयोग बाहरी अनुबंधों से कार्यों और कीवर्ड को विरासत में लेने के लिए किया जाता है।13// इस मामले में, `CryptoPizza` `IERC721` और `ERC165` अनुबंधों से विरासत में मिला है।14// और जानें: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#inheritance15contract CryptoPizza is IERC721, ERC165 {16 // अंकगणितीय संचालन को सुरक्षित रूप से करने के लिए OpenZeppelin की SafeMath लाइब्रेरी का उपयोग करता है।17 // और जानें: https://docs.openzeppelin.com/contracts/2.x/api/math#SafeMath18 using SafeMath for uint256;1920 // Solidity में लगातार स्टेट वैरिएबल अन्य भाषाओं के समान हैं21 // लेकिन आपको एक ऐसे एक्सप्रेशन से असाइन करना होगा जो कंपाइल समय पर स्थिर हो।22 // और जानें: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#constant-state-variables23 uint256 constant dnaDigits = 10;24 uint256 constant dnaModulus = 10 ** dnaDigits;25 bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;2627 // स्ट्रक्ट प्रकार आपको अपना स्वयं का प्रकार परिभाषित करने देते हैं28 // और जानें: https://solidity.readthedocs.io/en/v0.5.10/types.html#structs29 struct Pizza {30 string name;31 uint256 dna;32 }3334 // पिज्जा स्ट्रक्ट्स की एक खाली सरणी बनाता है35 Pizza[] public pizzas;3637 // पिज्जा आईडी से उसके मालिक के पते तक मैपिंग38 mapping(uint256 => address) public pizzaToOwner;3940 // मालिक के पते से स्वामित्व वाले टोकन की संख्या तक मैपिंग41 mapping(address => uint256) public ownerPizzaCount;4243 // टोकन आईडी से स्वीकृत पते पर मैपिंग44 mapping(uint256 => address) pizzaApprovals;4546 // आप मैपिंग को नेस्ट कर सकते हैं, यह उदाहरण ऑपरेटर अनुमोदन के लिए मालिक को मैप करता है47 mapping(address => mapping(address => bool)) private operatorApprovals;4849 // स्ट्रिंग (नाम) और डीएनए से एक यादृच्छिक पिज्जा बनाने के लिए आंतरिक फ़ंक्शन50 function _createPizza(string memory _name, uint256 _dna)51 // `internal` कीवर्ड का मतलब है कि यह फ़ंक्शन केवल52 // इस अनुबंध और इस अनुबंध को प्राप्त करने वाले अनुबंधों के भीतर दिखाई देता है53 // और जानें: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#visibility-and-getters54 internal55 // `isUnique` एक फ़ंक्शन संशोधक है जो जांचता है कि पिज्जा पहले से मौजूद है या नहीं56 // और जानें: https://solidity.readthedocs.io/en/v0.5.10/structure-of-a-contract.html#function-modifiers57 isUnique(_name, _dna)58 {59 // पिज्जा की सरणी में पिज्जा जोड़ता है और आईडी प्राप्त करता है60 uint256 id = SafeMath.sub(pizzas.push(Pizza(_name, _dna)), 1);6162 // जांचता है कि पिज्जा का मालिक वर्तमान उपयोगकर्ता के समान है63 // और जानें: https://solidity.readthedocs.io/en/v0.5.10/control-structures.html#error-handling-assert-require-revert-and-exceptions6465 // ध्यान दें कि address(0) शून्य पता है,66 // यह दर्शाता है कि pizza[id] अभी तक किसी विशेष उपयोगकर्ता को आवंटित नहीं किया गया है।6768 assert(pizzaToOwner[id] == address(0));6970 // पिज्जा को मालिक से मैप करता है71 pizzaToOwner[id] = msg.sender;72 ownerPizzaCount[msg.sender] = SafeMath.add(73 ownerPizzaCount[msg.sender],74 175 );76 }7778 // स्ट्रिंग (नाम) से एक यादृच्छिक पिज्जा बनाता है79 function createRandomPizza(string memory _name) public {80 uint256 randDna = generateRandomDna(_name, msg.sender);81 _createPizza(_name, randDna);82 }8384 // स्ट्रिंग (नाम) और मालिक (निर्माता) के पते से यादृच्छिक डीएनए उत्पन्न करता है85 function generateRandomDna(string memory _str, address _owner)86 public87 // `pure` के रूप में चिह्नित फ़ंक्शन स्थिति से पढ़ने या संशोधित न करने का वादा करते हैं88 // और जानें: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#pure-functions89 pure90 returns (uint256)91 {92 // स्ट्रिंग (नाम) + पता (मालिक) से यादृच्छिक uint उत्पन्न करता है93 uint256 rand = uint256(keccak256(abi.encodePacked(_str))) +94 uint256(_owner);95 rand = rand % dnaModulus;96 return rand;97 }9899 // मालिक द्वारा पाए गए पिज्जा की सरणी लौटाता है100 function getPizzasByOwner(address _owner)101 public102 // `view` के रूप में चिह्नित फ़ंक्शन स्थिति को संशोधित न करने का वादा करते हैं103 // और जानें: https://solidity.readthedocs.io/en/v0.5.10/contracts.html#view-functions104 view105 returns (uint256[] memory)106 {107 // केवल इस फ़ंक्शन कॉल के जीवनचक्र के लिए मानों को संग्रहीत करने के लिए `memory` भंडारण स्थान का उपयोग करता है।108 // और जानें: https://solidity.readthedocs.io/en/v0.5.10/introduction-to-smart-contracts.html#storage-memory-and-the-stack109 uint256[] memory result = new uint256[](ownerPizzaCount[_owner]);110 uint256 counter = 0;111 for (uint256 i = 0; i < pizzas.length; i++) {112 if (pizzaToOwner[i] == _owner) {113 result[counter] = i;114 counter++;115 }116 }117 return result;118 }119120 // पिज्जा और स्वामित्व को दूसरे पते पर स्थानांतरित करता है121 function transferFrom(address _from, address _to, uint256 _pizzaId) public {122 require(_from != address(0) && _to != address(0), "Invalid address.");123 require(_exists(_pizzaId), "Pizza does not exist.");124 require(_from != _to, "Cannot transfer to the same address.");125 require(_isApprovedOrOwner(msg.sender, _pizzaId), "Address is not approved.");126127 ownerPizzaCount[_to] = SafeMath.add(ownerPizzaCount[_to], 1);128 ownerPizzaCount[_from] = SafeMath.sub(ownerPizzaCount[_from], 1);129 pizzaToOwner[_pizzaId] = _to;130131 // आयातित IERC721 अनुबंध में परिभाषित इवेंट का उत्सर्जन करता है132 emit Transfer(_from, _to, _pizzaId);133 _clearApproval(_to, _pizzaId);134 }135136 /**137 * किसी दिए गए टोकन आईडी के स्वामित्व को सुरक्षित रूप से दूसरे पते पर स्थानांतरित करता है138 * यदि लक्ष्य पता एक अनुबंध है, तो इसे `onERC721Received` लागू करना होगा,139 * जिसे एक सुरक्षित हस्तांतरण पर कहा जाता है, और जादू मान140 * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` लौटाता है;141 * अन्यथा, हस्तांतरण वापस कर दिया जाता है।142 */143 function safeTransferFrom(address from, address to, uint256 pizzaId)144 public145 {146 // solium-disable-next-line arg-overflow147 this.safeTransferFrom(from, to, pizzaId, "");148 }149150 /**151 * किसी दिए गए टोकन आईडी के स्वामित्व को सुरक्षित रूप से दूसरे पते पर स्थानांतरित करता है152 * यदि लक्ष्य पता एक अनुबंध है, तो इसे `onERC721Received` लागू करना होगा,153 * जिसे एक सुरक्षित हस्तांतरण पर कहा जाता है, और जादू मान154 * `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))` लौटाता है;155 * अन्यथा, हस्तांतरण वापस कर दिया जाता है।156 */157 function safeTransferFrom(158 address from,159 address to,160 uint256 pizzaId,161 bytes memory _data162 ) public {163 this.transferFrom(from, to, pizzaId);164 require(_checkOnERC721Received(from, to, pizzaId, _data), "Must implement onERC721Received.");165 }166167 /**168 * किसी लक्ष्य पते पर `onERC721Received` को लागू करने के लिए आंतरिक फ़ंक्शन169 * यदि लक्ष्य पता एक अनुबंध नहीं है तो कॉल निष्पादित नहीं किया जाता है170 */171 function _checkOnERC721Received(172 address from,173 address to,174 uint256 pizzaId,175 bytes memory _data176 ) internal returns (bool) {177 if (!isContract(to)) {178 return true;179 }180181 bytes4 retval = IERC721Receiver(to).onERC721Received(182 msg.sender,183 from,184 pizzaId,185 _data186 );187 return (retval == _ERC721_RECEIVED);188 }189190 // एक पिज्जा को जलाता है - टोकन को पूरी तरह से नष्ट कर देता है191 // `external` फ़ंक्शन संशोधक का मतलब है कि यह फ़ंक्शन192 // अनुबंध इंटरफ़ेस का हिस्सा है और अन्य अनुबंध इसे कॉल कर सकते हैं193 function burn(uint256 _pizzaId) external {194 require(msg.sender != address(0), "Invalid address.");195 require(_exists(_pizzaId), "Pizza does not exist.");196 require(_isApprovedOrOwner(msg.sender, _pizzaId), "Address is not approved.");197198 ownerPizzaCount[msg.sender] = SafeMath.sub(199 ownerPizzaCount[msg.sender],200 1201 );202 pizzaToOwner[_pizzaId] = address(0);203 }204205 // पते द्वारा पिज्जा की गिनती लौटाता है206 function balanceOf(address _owner) public view returns (uint256 _balance) {207 return ownerPizzaCount[_owner];208 }209210 // आईडी द्वारा पाए गए पिज्जा के मालिक को लौटाता है211 function ownerOf(uint256 _pizzaId) public view returns (address _owner) {212 address owner = pizzaToOwner[_pizzaId];213 require(owner != address(0), "Invalid Pizza ID.");214 return owner;215 }216217 // पिज्जा के स्वामित्व को स्थानांतरित करने के लिए दूसरे पते को मंजूरी देता है218 function approve(address _to, uint256 _pizzaId) public {219 require(msg.sender == pizzaToOwner[_pizzaId], "Must be the Pizza owner.");220 pizzaApprovals[_pizzaId] = _to;221 emit Approval(msg.sender, _to, _pizzaId);222 }223224 // विशिष्ट पिज्जा के लिए स्वीकृत पता लौटाता है225 function getApproved(uint256 _pizzaId)226 public227 view228 returns (address operator)229 {230 require(_exists(_pizzaId), "Pizza does not exist.");231 return pizzaApprovals[_pizzaId];232 }233234 /**235 * किसी दिए गए टोकन आईडी की वर्तमान स्वीकृति को साफ़ करने के लिए निजी फ़ंक्शन236 * यदि दिया गया पता वास्तव में टोकन का स्वामी नहीं है तो रिवर्ट करता है237 */238 function _clearApproval(address owner, uint256 _pizzaId) private {239 require(pizzaToOwner[_pizzaId] == owner, "Must be pizza owner.");240 require(_exists(_pizzaId), "Pizza does not exist.");241 if (pizzaApprovals[_pizzaId] != address(0)) {242 pizzaApprovals[_pizzaId] = address(0);243 }244 }245246 /*247 * किसी दिए गए ऑपरेटर की स्वीकृति को सेट या अनसेट करता है248 * एक ऑपरेटर को उनकी ओर से प्रेषक के सभी टोकन स्थानांतरित करने की अनुमति है249 */250 function setApprovalForAll(address to, bool approved) public {251 require(to != msg.sender, "Cannot approve own address");252 operatorApprovals[msg.sender][to] = approved;253 emit ApprovalForAll(msg.sender, to, approved);254 }255256 // बताता है कि क्या कोई ऑपरेटर किसी दिए गए मालिक द्वारा अनुमोदित है257 function isApprovedForAll(address owner, address operator)258 public259 view260 returns (bool)261 {262 return operatorApprovals[owner][operator];263 }264265 // पिज्जा का स्वामित्व लेता है - केवल स्वीकृत उपयोगकर्ताओं के लिए266 function takeOwnership(uint256 _pizzaId) public {267 require(_isApprovedOrOwner(msg.sender, _pizzaId), "Address is not approved.");268 address owner = this.ownerOf(_pizzaId);269 this.transferFrom(owner, msg.sender, _pizzaId);270 }271272 // जांचता है कि पिज्जा मौजूद है या नहीं273 function _exists(uint256 pizzaId) internal view returns (bool) {274 address owner = pizzaToOwner[pizzaId];275 return owner != address(0);276 }277278 // जांचता है कि पता मालिक है या पिज्जा स्थानांतरित करने के लिए अनुमोदित है279 function _isApprovedOrOwner(address spender, uint256 pizzaId)280 internal281 view282 returns (bool)283 {284 address owner = pizzaToOwner[pizzaId];285 // Solium जांच अक्षम करें क्योंकि286 // https://github.com/duaraghav8/Solium/issues/175287 // solium-disable-next-line operator-whitespace288 return (spender == owner ||289 this.getApproved(pizzaId) == spender ||290 this.isApprovedForAll(owner, spender));291 }292293 // जांचें कि पिज्जा अद्वितीय है और अभी तक मौजूद नहीं है294 modifier isUnique(string memory _name, uint256 _dna) {295 bool result = true;296 for (uint256 i = 0; i < pizzas.length; i++) {297 if (298 keccak256(abi.encodePacked(pizzas[i].name)) ==299 keccak256(abi.encodePacked(_name)) &&300 pizzas[i].dna == _dna301 ) {302 result = false;303 }304 }305 require(result, "Pizza with such name already exists.");306 _;307 }308309 // लौटाता है कि लक्ष्य पता एक अनुबंध है या नहीं310 function isContract(address account) internal view returns (bool) {311 uint256 size;312 // वर्तमान में यह जांचने का कोई बेहतर तरीका नहीं है कि किसी पते में कोई अनुबंध है या नहीं313 // उस पते पर कोड के आकार की जांच करने से।314 // यह कैसे काम करता है, इसके बारे में अधिक जानकारी के लिए https://ethereum.stackexchange.com/a/14016/36603315 // देखें।316 // TODO Serenity रिलीज से पहले इसे फिर से जांचें, क्योंकि तब सभी पते317 // अनुबंध होंगे।318 // solium-disable-next-line security/no-inline-assembly319 assembly {320 size := extcodesize(account)321 }322 return size > 0;323 }324}सभी दिखाएँआगे की रीडिंग
स्मार्ट अनुबंधों के अधिक संपूर्ण अवलोकन के लिए सॉलिडिटी और वाइपर के प्रलेखन देखें:
संबंधित विषय
संबंधित ट्यूटोरियल
- अनुबंध आकार सीमा से लड़ने के लिए अनुबंधों का आकार छोटा करना - आपके स्मार्ट अनुबंध के आकार को कम करने के लिए कुछ व्यावहारिक सुझाव।
- इवेंट्स के साथ स्मार्ट अनुबंधों से डेटा लॉगिंग – स्मार्ट अनुबंध इवेंट्स का परिचय और आप डेटा लॉग करने के लिए उनका उपयोग कैसे कर सकते हैं।
- सॉलिडिटी से अन्य अनुबंधों के साथ इंटरैक्ट करें – मौजूदा अनुबंध से स्मार्ट अनुबंध कैसे परिनियोजित करें और इसके साथ इंटरैक्ट करें।