मुख्य सामग्री पर जाएँ
Change page

स्मार्ट कॉंट्रैक्ट की सुरक्षा

स्मार्ट अनुबंध बेहद लचीले होते हैं, और बड़ी मात्रा में मूल्य और डेटा को नियंत्रित करने में सक्षम होते हैं, जबकि ब्लॉकचेन पर परिनियोजित किए गए कोड के आधार पर अपरिवर्तनीय तर्क चलाते हैं। इसने विश्वासरहित और विकेंद्रीकृत अनुप्रयोग का एक जीवंत पारिस्थितिकी तंत्र बनाया है जो पुरानी प्रणालियों की तुलना में कई लाभ प्रदान करता है। वे उन हमलावरों के लिए भी अवसर प्रस्तुत करते हैं जो स्मार्ट कॉन्ट्रैक्ट्स में कमजोरियों का फायदा उठाकर लाभ कमाना चाहते हैं।

एथेरियम जैसे सार्वजनिक ब्लॉकचेन, स्मार्ट अनुबंध को सुरक्षित करने के मुद्दे को और जटिल बनाते हैं। परिनियोजित किया गया अनुबंध कोड आमतौर पर सुरक्षा खामियों को ठीक करने के लिए नहीं बदला जा सकता, जबकि स्मार्ट अनुबंधों से चुराई गई संपत्तियों को ट्रैक करना बेहद मुश्किल होता है और अपरिवर्तनीयता के कारण ज्यादातर वापस नहीं मिल पाती हैं।

हालांकि आंकड़े अलग-अलग हैं, यह अनुमान लगाया जाता है कि स्मार्ट अनुबंधों में सुरक्षा दोषों के कारण चोरी या खोए गए कुल मूल्य की राशि आसानी से 1 अरब डॉलर से अधिक है। इसमें उच्च-प्रोफाइल घटनाएं शामिल हैं, जैसे डीएओ हैक(opens in a new tab) (3.6M ETH चोरी, आज की कीमतों में $1B से अधिक मूल्य), पैरिटी मल्टी-सिग वॉलेट हैक(opens in a new tab) (हैकर्स के कारण $30M का नुकसान), और पैरिटी फ्रोजन वॉलेट समस्या(opens in a new tab) ($300M से अधिक ETH हमेशा के लिए लॉक हो गए)।

उपरोक्त समस्याएं डेवलपर्स के लिए सुरक्षित, मजबूत और लचीले स्मार्ट अनुबंध बनाने में प्रयास करना अनिवार्य बनाती हैं। स्मार्ट अनुबंध सुरक्षा एक गंभीर व्यवसाय है, और ऐसा जिसे हर डेवलपर को सीखना चाहिए। यह गाइड एथेरियम डेवलपर्स के लिए सुरक्षा संबंधी विचारों को कवर करेगी और स्मार्ट अनुबंध सुरक्षा में सुधार के लिए संसाधनों की खोज करेगी।

आवश्यक शर्तें

सुरक्षा को संभालने से पहले स्मार्ट अनुबंध विकास के मूल सिद्धांतों से परिचित होना सुनिश्चित करें।

सुरक्षित एथेरियम स्मार्ट अनुबंध बनाने के लिए दिशानिर्देश

1. उचित एक्सेस कंट्रोल डिज़ाइन करें

स्मार्ट अनुबंधों में, public या external के रूप में चिह्नित फंक्शंस को किसी भी बाहरी स्वामित्व वाले खातों (EOAs) या अनुबंध खातों द्वारा कॉल किया जा सकता है। यदि आप चाहते हैं कि दूसरे आपके अनुबंध के साथ इंटरैक्ट करें तो फंक्शंस के लिए सार्वजनिक दृश्यता निर्दिष्ट करना आवश्यक है। हालांकि private के रूप में चिह्नित फंक्शंस को केवल स्मार्ट अनुबंध के भीतर फंक्शंस द्वारा कॉल किया जा सकता है और बाहरी खातों द्वारा कॉल नहीं किया जा सकता है। हर नेटवर्क प्रतिभागी को अनुबंध फंक्शंस की एक्सेस देने से समस्याएं पैदा हो सकती हैं, खासकर अगर इसका मतलब है कि कोई भी संवेदनशील कार्य कर सकता है (जैसे, नए टोकन बनाना)।

स्मार्ट अनुबंध फंक्शंस के अनधिकृत उपयोग को रोकने के लिए, सुरक्षित एक्सेस कंट्रोल लागू करना आवश्यक है। एक्सेस कंट्रोल मैकेनिज्म स्मार्ट अनुबंध में कुछ फंक्शंस का उपयोग करने की क्षमता को स्वीकृत संस्थाओं तक सीमित करता है, जैसे कि अनुबंध प्रबंधन के लिए जिम्मेदार खाते। स्वामित्व योग्य पैटर्न और भूमिका-आधारित कंट्रोल दो ऐसे पैटर्न हैं जो स्मार्ट अनुबंधों में एक्सेस कंट्रोल लागू करने के लिए उपयोगी हैं:

स्वामित्व योग्स पैटर्न

स्वामित्व योग्य पैटर्न में, अनुबंध-निर्माण की प्रक्रिया के दौरान एक पता अनुबंध के “स्वामी” के रूप में सेट किया जाता है। संरक्षित फंक्शंस को एक OnlyOwner मॉडिफायर असाइन किया जाता है, जो यह सुनिश्चित करता है कि अनुबंध फंक्शन को निष्पादित करने से पहले कॉलिंग पते की पहचान को प्रमाणित करता है। अनुबंध स्वामी के अलावा अन्य पतों से संरक्षित फंक्शंस के लिए कॉल हमेशा वापस लौट जाते हैं, जिससे अवांछित एक्सेस रोकी जाती है।

भूमिका-आधारित एक्सेस कंट्रोल

किसी स्मार्ट अनुबंध में एकल पते को Owner के रूप में पंजीकृत करने से केंद्रीकरण का जोखिम पैदा होता है और यह एकल विफलता बिंदु का प्रतिनिधित्व करता है। यदि स्वामी के खाते की कुंजियां से छेड़छाड़ की जाती है, तो हमलावर स्वामित्व वाले अनुबंध पर हमला कर सकते हैं। इसलिए कई प्रशासनिक खातों के साथ भूमिका-आधारित एक्सेस कंट्रोल पैटर्न का उपयोग करना एक बेहतर विकल्प हो सकता है।

भूमिका-आधारित एक्सेस कंट्रोल में, संवेदनशील फंक्शंस की एक्सेस विश्वसनीय प्रतिभागियों के एक समूह के बीच वितरित की जाती है। उदाहरण के लिए, एक खाता टोकन बनाने के लिए जिम्मेदार हो सकता है, जबकि दूसरा खाता अपग्रेड करता है या अनुबंध को रोकता है। इस तरह से एक्सेस कंट्रोल को विकेंद्रीकृत करने से एकल विफलता बिंदु समाप्त हो जाते हैं और यूज़र के लिए विश्वास धारणाओं को कम किया जाता है।

मल्टी-सिग्नेचर वॉलेट का उपयोग करना

सुरक्षित एक्सेस कंट्रोल लागू करने का एक अन्य दृष्टिकोण एक अनुबंध को प्रबंधित करने के लिए मल्टी-सिग्नेचर खाते का उपयोग करना है। एक नियमित EOA के विपरीत, मल्टी-सिग्नेचर खाते कई संस्थाओं के स्वामित्व में होते हैं और लेनदेन को निष्पादित करने के लिए न्यूनतम संख्या में खातों—मान लीजिए 5 में से 3—से हस्ताक्षर की आवश्यकता होती है।

एक्सेस कंट्रोल के लिए मल्टीसिग का उपयोग करने से सुरक्षा की एक अतिरिक्त परत जुड़ जाती है क्योंकि लक्षित अनुबंध पर कार्रवाई के लिए कई पक्षों की सहमति की आवश्यकता होती है। यह विशेष रूप से उपयोगी है यदि स्वामित्व पैटर्न का उपयोग करना आवश्यक है, क्योंकि यह एक हमलावर या ठग इनसाइडर के लिए दुर्भावनापूर्ण उद्देश्यों के लिए संवेदनशील अनुबंध फंक्शंस में हेरफेर करना अधिक कठिन बना देता है।

2. अनुबंध संचालन की रक्षा के लिए require(), assert(), और revert() स्टेटमेंट्स का उपयोग करें

जैसा कि उल्लेख किया गया है, एक बार जब आपका स्मार्ट अनुबंध ब्लॉकचेन पर परिनियोजित हो जाता है, तो कोई भी आपके स्मार्ट अनुबंध में सार्वजनिक फंक्शंस को कॉल कर सकता है। चूंकि आप पहले से यह नहीं जान सकते कि बाहरी खाते अनुबंध के साथ कैसे इंटरैक्ट करेंगे, इसलिए परिनियोजित करने से पहले समस्याग्रस्त संचालन के खिलाफ आंतरिक सुरक्षा उपाय लागू करना आदर्श है। आप require(), assert(), और revert() स्टेटमेंट्स का उपयोग करके स्मार्ट अनुबंधों में सही व्यवहार लागू कर सकते हैं ताकि अपवाद ट्रिगर हो सकें और स्टेट परिवर्तन वापस हो सकें यदि निष्पादन कुछ आवश्यकताओं को पूरा करने में विफल रहता है।

require(): require फंक्शंस की शुरुआत में परिभाषित किए जाते हैं और सुनिश्चित करते हैं कि कॉल किए गए फंक्शन के निष्पादित होने से पहले पूर्व-निर्धारित शर्तें पूरी हो जाएं। एक require स्टेटमेंट का उपयोग यूज़र इनपुट को मान्य करने, स्टेट वेरिएबल्स की जांच करने, या फंक्शन के साथ आगे बढ़ने से पहले कॉलिंग खाते की पहचान को प्रमाणित करने के लिए किया जा सकता है।

assert(): assert() का उपयोग आंतरिक त्रुटियों का पता लगाने और आपके कोड में “अपरिवर्तनीयों" के उल्लंघन की जांच करने के लिए किया जाता है। एक अपरिवर्तनीय आपके अनुबंध की स्थिति के बारे में एक तार्किक कथन है जो सभी फंक्शन निष्पादन के लिए सत्य होना चाहिए। एक अपरिवर्तनीय का उदाहरण किसी टोकन अनुबंध की अधिकतम कुल आपूर्ति या शेष राशि है। assert() का उपयोग सुनिश्चित करता है कि आपका अनुबंध कभी भी कमजोर स्थिति में नहीं पहुंचता है और यदि ऐसा होता है, तो स्टेट वेरिएबल्स में सभी परिवर्तन वापस लौटा दिए जाते हैं।

revert(): यदि आवश्यक शर्त पूरी नहीं होती है तो revert() का उपयोग एक if-else स्टेटमेंट में किया जा सकता है जो एक अपवाद ट्रिगर करता है। नीचे दिया गया नमूना अनुबंध फंक्शंस के निष्पादन की रक्षा के लिए revert() का उपयोग करता है:

1pragma solidity ^0.8.4;
2
3contract VendingMachine {
4 address owner;
5 error Unauthorized();
6 function buy(uint amount) public payable {
7 if (amount > msg.value / 2 ether)
8 revert("Not enough Ether provided.");
9 // Perform the purchase.
10 }
11 function withdraw() public {
12 if (msg.sender != owner)
13 revert Unauthorized();
14
15 payable(msg.sender).transfer(address(this).balance);
16 }
17}
सभी दिखाएँ

3. स्मार्ट अनुबंधों का परीक्षण करें और कोड की सटीकता सत्यापित करें

एथेरियम वर्चुअल मशीन में चलने वाले कोड की अपरिवर्तनीयता का अर्थ है कि स्मार्ट अनुबंध विकास चरण के दौरान उच्च स्तर के गुणवत्ता मूल्यांकन की मांग करते हैं। अपने अनुबंध का व्यापक परीक्षण करना और किसी भी अप्रत्याशित परिणाम के लिए इसका अवलोकन करना सुरक्षा में काफी सुधार करेगा और लंबे समय में आपके उपयोगकर्ताओं की रक्षा करेगा।

सामान्य तरीका छोटे इकाई परीक्षण लिखना है जो उस मॉक डेटा का उपयोग करते हैं जिसे अनुबंध को उपयोगकर्ताओं से प्राप्त करने की उम्मीद है। इकाई परीक्षण कुछ फंक्शंस की कार्यक्षमता का परीक्षण करने और यह सुनिश्चित करने के लिए अच्छा है कि स्मार्ट अनुबंध अपेक्षा के अनुसार काम करता है।

दुर्भाग्य से, आइसोलेशन में उपयोग किए जाने पर इकाई परीक्षण स्मार्ट अनुबंध सुरक्षा में सुधार के लिए न्यूनतम रूप से प्रभावी है। एक इकाई परीक्षण यह साबित कर सकता है कि एक फंक्शन मॉक डेटा के लिए ठीक से निष्पादित होता है, लेकिन इकाई परीक्षण केवल उतने ही प्रभावी होते हैं जितने कि लिखे गए परीक्षण। इससे छूटे हुए किनारे के मामलों और कमजोरियों का पता लगाना मुश्किल हो जाता है जो आपके स्मार्ट अनुबंध की सुरक्षा को तोड़ सकते हैं।

एक बेहतर दृष्टिकोण स्थिर और गतिशील विश्लेषण का उपयोग करके किए गए गुण-आधारित परीक्षण के साथ इकाई परीक्षण को जोड़ना है। स्थिर विश्लेषण पहुंच योग्य प्रोग्राम स्थितियों और निष्पादन पथों का विश्लेषण करने के लिए कंट्रोल प्रवाह ग्राफ(opens in a new tab) और एब्स्ट्रेक्ट सिंटेक्स ट्री(opens in a new tab) जैसे निम्न-स्तरीय प्रतिनिधित्वों पर निर्भर करता है। इस बीच, स्मार्ट अनुबंध फज़िंग(opens in a new tab) जैसी गतिशील विश्लेषण तकनीकें, रैंडम इनपुट मानों के साथ अनुबंध कोड को निष्पादित करती हैं ताकि उन संचालनों का पता लगाया जा सके जो सुरक्षा गुणों का उल्लंघन करते हैं।

औपचारिक सत्यापन स्मार्ट अनुबंधों में सुरक्षा गुणों को सत्यापित करने के लिए एक अन्य तकनीक है। नियमित परीक्षण के विपरीत, औपचारिक सत्यापन एक स्मार्ट अनुबंध में त्रुटियां न होने को निर्णायक रूप से साबित कर सकता है। यह एक औपचारिक विनिर्देश बनाकर प्राप्त किया जाता है जो वांछित सुरक्षा गुणों को कैप्चर करता है और यह साबित करता है कि अनुबंधों का एक औपचारिक मॉडल इस विनिर्देश का पालन करता है।

4. अपने कोड की अलग समीक्षा के लिए पूछें

अपने कॉन्ट्रैक्ट का परीक्षण करने के बाद, किसी भी सुरक्षा समस्या के लिए दूसरों से सोर्स कोड की जांच करने के लिए कहना अच्छा है। परीक्षण एक स्मार्ट अनुबंध में हर खामी का पता नहीं लगाएगा, लेकिन एक स्वतंत्र समीक्षा प्राप्त करने से कमजोरियों का पता लगाने की संभावना बढ़ जाती है।

ऑडिट

एक स्मार्ट अनुबंध ऑडिट शुरू करना एक स्वतंत्र कोड समीक्षा आयोजित करने का एक तरीका है। ऑडिटर यह सुनिश्चित करने में महत्वपूर्ण भूमिका निभाते हैं कि स्मार्ट अनुबंध सुरक्षित हैं और गुणवत्ता दोषों और डिज़ाइन की त्रुटियों से मुक्त हैं।

हालांकि, आपको ऑडिट को रामबाण के रूप में नहीं देखना चाहिए। स्मार्ट अनुबंध ऑडिट हर गड़बड़ी को नहीं पकड़ पाएंगे और ये मुख्य रूप से समीक्षा का एक अतिरिक्त दौर प्रदान करने के लिए बनाए गए हैं, जो शुरुआती विकास और परीक्षण के दौरान डेवलपर्स से छूटी समस्याओं का पता लगाने में मदद कर सकते हैं। आपको ऑडिटर्स के साथ काम करने के लिए सर्वोत्तम प्रथाओं का भी पालन करना चाहिए, जैसे कोड को ठीक से प्रलेखित करना और इनलाइन टिप्पणियां जोड़ना, ताकि स्मार्ट अनुबंध ऑडिट का लाभ अधिकतम हो सके।

बग बाउंटी

बग बाउंटी कार्यक्रम शुरू करना बाहरी कोड समीक्षा लागू करने का एक और तरीका है। बग बाउंटी एक आर्थिक इनाम है जो उन व्यक्तियों (आमतौर पर व्हाइटहैट हैकर्स) को दिया जाता है जो किसी एप्लिकेशन में कमजोरियों का पता लगाते हैं।

सही तरीके से उपयोग किए जाने पर, बग बाउंटी हैकर समुदाय के सदस्यों को आपके कोड में गंभीर खामियों की जांच करने के लिए प्रोत्साहित करते हैं। एक वास्तविक उदाहरण “अनंत धन बग” है जो एक हमलावर को ऑप्टिमिज़्म(opens in a new tab) पर असीमित मात्रा में ईथर बनाने की अनुमति देता, जो एथेरियम पर चलने वाला एक परत 2 प्रोटोकॉल है। सौभाग्य से, एक व्हाइटहैट हैकर ने इस खामी का पता(opens in a new tab) लगाया और टीम को सूचित किया, जिससे उसे एक बड़ा भुगतान मिला(opens in a new tab)

एक उपयोगी रणनीति बग बाउंटी कार्यक्रम का भुगतान स्टेक पर लगी राशि के अनुपात में निर्धारित करना है। “स्केलिंग बग बाउंटी(opens in a new tab)” के रूप में वर्णित, यह दृष्टिकोण व्यक्तियों को कमजोरियों का शोषण करने के बजाय उन्हें जिम्मेदारी से उजागर करने के लिए आर्थिक प्रोत्साहन प्रदान करता है।

5. स्मार्ट अनुबंध विकास के दौरान सर्वोत्तम प्रथाओं का पालन करें

ऑडिट और बग बाउंटी का अस्तित्व आपको उच्च-गुणवत्ता वाला कोड लिखने की जिम्मेदारी से मुक्त नहीं करता। अच्छी स्मार्ट अनुबंध सुरक्षा उचित डिज़ाइन और विकास प्रक्रियाओं का पालन करने से शुरू होती है:

  • सभी कोड को गिट जैसी संस्करण नियंत्रण प्रणाली में संग्रहीत करें

  • सभी कोड संशोधन को पुल अनुरोधों के माध्यम से करें

  • सुनिश्चित करें कि पुल अनुरोधों में कम से कम एक स्वतंत्र समीक्षक हो—यदि आप किसी प्रोजेक्ट पर अकेले काम कर रहे हैं, तो अन्य डेवलपर्स को खोजने और कोड समीक्षाओं को ट्रेड करने पर विचार करें

  • स्मार्ट अनुबंध के परीक्षण, संकलन, परिनियोजन के लिए एक विकास परिवेश का उपयोग करें

  • अपने कोड को Cyfrin Aaderyn(opens in a new tab), Mythril और Slither जैसे बुनियादी कोड विश्लेषण उपकरणों से गुजारें। आदर्श रूप से, आपको यह हर पुल अनुरोध को मर्ज करने से पहले करना चाहिए और आउटपुट में अंतरों की तुलना करनी चाहिए

  • सुनिश्चित करें कि आपका कोड बिना किसी त्रुटि के संकलित होता है, और Solidity कंपाइलर कोई चेतावनी नहीं देता

  • अपने कोड को ठीक से प्रलेखित करें (NatSpec(opens in a new tab) का उपयोग करके) और अनुबंध आर्किटेक्चर के बारे में विवरण को आसानी से समझने योग्य भाषा में वर्णित करें। यह दूसरों के लिए आपके कोड का ऑडिट और समीक्षा करना आसान बना देगा।

6. मजबूत आपदा बहाली योजनाएं लागू करें

सुरक्षित एक्सेस नियंत्रण डिजाइन करना, फंक्शन संशोधकों को लागू करना और अन्य सुझाव स्मार्ट अनुबंध सुरक्षा में सुधार कर सकते हैं, लेकिन वे दुर्भावनापूर्ण शोषण की संभावना को खारिज नहीं कर सकते। सुरक्षित स्मार्ट अनुबंध बनाने के लिए “विफलता के लिए तैयारी” और हमलों का प्रभावी ढंग से जवाब देने के लिए एक वैकल्पिक योजना होना आवश्यक है। एक उचित आपदा बहाली योजना में निम्नलिखित घटकों में से कुछ या सभी शामिल होंगे:

अनुबंध अपग्रेड करें

हालांकि एथेरियम स्मार्ट अनुबंध डिफ़ॉल्ट रूप से अपरिवर्तनीय होते हैं, अपग्रेड पैटर्न का उपयोग करके कुछ हद तक परिवर्तनशीलता प्राप्त करना संभव है। अनुबंधों को अपग्रेड करना उन मामलों में आवश्यक है जहां एक गंभीर खामी आपके पुराने अनुबंध को अनुपयोगी बना देती है और नए तर्क को परिनियोजित करना सबसे व्यवहार्य विकल्प होता है।

कॉन्ट्रैक्ट अपग्रेड तंत्र अलग-अलग तरीके से काम करते हैं, लेकिन "प्रॉक्सी पैटर्न" स्मार्ट कॉन्ट्रैक्ट्स को अपग्रेड करने के लिए अधिक लोकप्रिय दृष्टिकोणों में से एक है। प्रॉक्सी पैटर्न(opens in a new tab) एक एप्लिकेशन की स्थिति और तर्क को दो अनुबंधों के बीच विभाजित करते हैं। पहला अनुबंध (जिसे ‘प्रॉक्सी अनुबंध’ कहा जाता है) स्टेट वेरिएबल्स (जैसे, यूज़र शेष राशि) को संग्रहीत करता है, जबकि दूसरा अनुबंध (जिसे 'तर्क अनुबंध' कहा जाता है) अनुबंध फंक्शंस को निष्पादित करने के लिए कोड रखता है।

खाते प्रॉक्सी अनुबंध के साथ इंटरैक्ट करते हैं, जो delegatecall()(opens in a new tab) निम्न-स्तरीय कॉल का उपयोग करके सभी फंक्शन कॉल को तर्क अनुबंध को भेजता है। एक नियमित संदेश कॉल के विपरीत, delegatecall() सुनिश्चित करता है कि तर्क अनुबंध के पते पर चलने वाला कोड कॉलिंग अनुबंध के संदर्भ में निष्पादित होता है। इसका मतलब है कि तर्क अनुबंध हमेशा प्रॉक्सी के भंडारण में लिखेगा (अपने स्वयं के भंडारण के बजाय) और msg.sender और msg.value के मूल मान संरक्षित रहते हैं।

तर्क अनुबंध को कॉल सौंपने के लिए इसके पते को प्रॉक्सी अनुबंध के भंडारण में संग्रहित करने की आवश्यकता होती है। इसलिए, अनुबंध के लॉजिक को अपग्रेड करना केवल एक अन्य तर्क अनुबंध को परिनियोजित करने और नए पते को प्रॉक्सी अनुबंध में संग्रहित करने का मामला है। चूंकि प्रॉक्सी अनुबंध के बाद के कॉल स्वचालित रूप से नए तर्क अनुबंध को रूट किए जाते हैं, आप वास्तव में कोड को संशोधित किए बिना अनुबंध को “अपग्रेड” कर चुके होंगे।

अनुबंधों को अपग्रेड करने के बारे में अधिक जानकारी

आपातकालीन रोक

जैसा कि उल्लेख किया गया है, व्यापक ऑडिटिंग और परीक्षण एक स्मार्ट अनुबंध में सभी बग का पता नहीं लगा सकते। यदि परिनियोजन के बाद आपके कोड में कोई कमजोरी दिखाई देती है, तो उसे ठीक करना असंभव है क्योंकि आप अनुबंध पते पर चलने वाले कोड को नहीं बदल सकते। इसके अलावा, अपग्रेड मैकेनिज्म (जैसे, प्रॉक्सी पैटर्न) को लागू करने में समय लग सकता है (उन्हें अक्सर विभिन्न पक्षों से अनुमोदन की आवश्यकता होती है), जो हमलावरों को और अधिक नुकसान पहुंचाने के लिए और अधिक समय देता है।

परमाणु विकल्प एक “आपातकालीन रोक” फंक्शन लागू करना है जो एक अनुबंध में कमजोर फंक्शंस के लिए कॉल को ब्लॉक करता है। आपातकालीन रोक में आमतौर पर निम्नलिखित घटक शामिल होते हैं:

  1. एक वैश्विक बूलियन वेरिएबल जो इंगित करता है कि स्मार्ट अनुबंध रुकी हुई अवस्था में है या नहीं। अनुबंध सेट करते समय यह वेरिएबल false पर सेट किया जाता है, लेकिन अनुबंध रुकने पर true पर वापस आ जाएगा।

  2. ऐसे फंक्शन जो अपने निष्पादन में बूलियन वेरिएबल का संदर्भ देते हैं। ऐसे फंक्शन तब सुलभ होते हैं जब स्मार्ट अनुबंध नहीं रुका होता है और आपातकालीन रोक सुविधा ट्रिगर होने पर अगम्य हो जाते हैं।

  3. एक इकाई जिसके पास आपातकालीन रोक फंक्शन की एक्सेस है, जो बूलियन वेरिएबल को true पर सेट करती है। दुर्भावनापूर्ण कार्यों को रोकने के लिए, इस फंक्शन के लिए कॉल को एक विश्वसनीय पते (जैसे, अनुबंध स्वामी) तक सीमित किया जा सकता है।

एक बार जब अनुबंध आपातकालीन रोक को सक्रिय करता है, तो कुछ फंक्शंस को कॉल नहीं किया जा सकेगा। यह चुनिंदा फंक्शंस को एक मॉडिफायर में लपेटकर प्राप्त किया जाता है जो वैश्विक वेरिएबल का संदर्भ देता है। नीचे अनुबंधों में इस पैटर्न के कार्यान्वयन का वर्णन करने वाला एक उदाहरण(opens in a new tab) दिया गया है:

1// This code has not been professionally audited and makes no promises about safety or correctness. Use at your own risk.
2
3contract EmergencyStop {
4
5 bool isStopped = false;
6
7 modifier stoppedInEmergency {
8 require(!isStopped);
9 _;
10 }
11
12 modifier onlyWhenStopped {
13 require(isStopped);
14 _;
15 }
16
17 modifier onlyAuthorized {
18 // Check for authorization of msg.sender here
19 _;
20 }
21
22 function stopContract() public onlyAuthorized {
23 isStopped = true;
24 }
25
26 function resumeContract() public onlyAuthorized {
27 isStopped = false;
28 }
29
30 function deposit() public payable stoppedInEmergency {
31 // Deposit logic happening here
32 }
33
34 function emergencyWithdraw() public onlyWhenStopped {
35 // Emergency withdraw happening here
36 }
37}
सभी दिखाएँ
कॉपी करें

यह उदाहरण आपातकालीन रोक की मूल विशेषताओं को दर्शाता है:

  • isStopped एक बूलियन है जो शुरुआत में false और अनुबंध के आपातकालीन मोड में प्रवेश करने पर true का मूल्यांकन करता है।

  • फंक्शन मॉडिफायर onlyWhenStopped और stoppedInEmergency isStopped वेरिएबल की जांच करते हैं। stoppedInEmergency का उपयोग उन फंक्शंस को नियंत्रित करने के लिए किया जाता है जो अनुबंध के कमजोर होने पर अगम्य होने चाहिए (जैसे deposit())। इन फंक्शंस के लिए कॉल बस वापस लौट जाएंगे।

onlyWhenStopped का उपयोग उन फंक्शंस के लिए किया जाता है जो आपातकाल के दौरान कॉल करने योग्य होने चाहिए (जैसे emergencyWithdraw())। ऐसे फंक्शन स्थिति को हल करने में मदद कर सकते हैं, इसलिए उन्हें “प्रतिबंधित फंक्शंस“ सूची से बाहर रखा गया है।

आपातकालीन रोक कार्यक्षमता का उपयोग आपके स्मार्ट अनुबंध में गंभीर कमजोरियों से निपटने के लिए एक प्रभावी अस्थायी समाधान प्रदान करता है। हालांकि, इससे यूज़र को डेवलपर्स पर भरोसा करने की आवश्यकता बढ़ जाती है कि वे इसे स्वार्थी कारणों से सक्रिय नहीं करेंगे। इस उद्देश्य के लिए, आपातकालीन रोक के नियंत्रण को विकेंद्रीकृत करना जैसे कि इसे एक ऑन-चेन मतदान मैकेनिज्म, टाइमलॉक, या एक मल्टीसिग वॉलेट से अनुमोदन के अधीन करना संभावित समाधान हैं।

इवेंट मॉनिटरिंग

इवेंट्स(opens in a new tab) आपको स्मार्ट अनुबंध फंक्शंस के कॉल्स को ट्रैक करने और स्टेट वेरिएबल्स में परिवर्तनों की निगरानी करने की अनुमति देते हैं। यह आदर्श है कि आप अपने स्मार्ट अनुबंध को इस तरह प्रोग्राम करें कि जब भी कोई पक्ष कोई सुरक्षा-महत्वपूर्ण कार्रवाई करता है (जैसे, फंड निकालना), तो वह एक इवेंट उत्सर्जित करे।

इवेंट्स को लॉग करना और उनकी ऑफ-चेन निगरानी करना अनुबंध संचालन पर अंतर्दृष्टि प्रदान करता है और दुर्भावनापूर्ण कार्यों की तेज़ खोज में मदद करता है। इसका मतलब है कि आपकी टीम हैक्स पर तेज़ी से प्रतिक्रिया दे सकती है और यूज़र पर प्रभाव को कम करने के लिए कार्रवाई कर सकती है, जैसे कि फंक्शंस को रोकना या अपग्रेड करना।

आप एक तैयार मॉनिटरिंग उपकरण का विकल्प भी चुन सकते हैं जो तब स्वचालित रूप से अलर्ट भेजता है जब कोई आपके अनुबंधों के साथ इंटरैक्ट करता है। ये उपकरण आपको विभिन्न ट्रिगर्स के आधार पर कस्टम अलर्ट, जैसे लेनदेन की मात्रा, फंक्शन कॉल्स की आवृत्ति या शामिल विशिष्ट फंक्शंस बनाने की अनुमति देंगे। उदाहरण के लिए, आप एक अलर्ट प्रोग्राम कर सकते हैं जो तब आता है जब एकल लेनदेन में निकाली गई राशि एक विशेष सीमा को पार कर जाती है।

7. सुरक्षित शासन सिस्टम डिज़ाइन करें

आप अपने एप्लिकेशन को विकेंद्रीकृत करना चाह सकते हैं, जिसमें मुख्य स्मार्ट अनुबंध का नियंत्रण समुदाय के सदस्यों को सौंप दिया जाता है। इस मामले में, स्मार्ट अनुबंध सिस्टम में एक गवर्नेंस मॉड्यूल शामिल होगा—एक मैकेनिज्म जो समुदाय के सदस्यों को एक ऑन-चेन गवर्नेंस सिस्टम के माध्यम से प्रशासनिक कार्यों को अनुमोदित करने की अनुमति देता है। उदाहरण के लिए, एक नए कार्यान्वयन के लिए एक प्रॉक्सी अनुबंध को अपग्रेड करने के प्रस्ताव पर टोकन-धारकों द्वारा मतदान किया जा सकता है।

विकेंद्रीकृत शासन लाभदायक हो सकता है, विशेष रूप से क्योंकि यह डेवलपर्स और अंतिम उपयोगकर्ताओं के हितों को संरेखित करता है। फिर भी, स्मार्ट अनुबंध शासन मैकेनिज्म गलत तरीके से लागू किए जाने पर नए जोखिम पैदा कर सकते हैं। एक संभावित परिदृश्य यह है कि एक हमलावर फ्लैश लोन लेकर भारी मतदान शक्ति (धारित टोकन की संख्या में मापी गई) हासिल करता है और एक दुर्भावनापूर्ण प्रस्ताव को आगे बढ़ाता है।

ऑन-चेन शासन से संबंधित समस्याओं को रोकने का एक तरीका टाइमलॉक का उपयोग करना है(opens in a new tab)। टाइमलॉक एक स्मार्ट अनुबंध को कुछ निश्चित कार्यों को तब तक निष्पादित करने से रोकता है जब तक कि एक विशिष्ट समय न बीत जाए। अन्य रणनीतियों में प्रत्येक टोकन को एक “वोटिंग वेट” असाइन करना शामिल है, जो इस बात पर आधारित होता है कि वह कितने समय से लॉक किया गया है, या वर्तमान ब्लॉक के बजाय किसी पते की वोटिंग पावर को एक ऐतिहासिक अवधि (उदाहरण के लिए, पिछले 2-3 ब्लॉक्स) में मापना शामिल है। दोनों तरीके ऑन-चेन वोट को प्रभावित करने के लिए तेजी से वोटिंग पावर जमा करने की संभावना को कम करते हैं।

साझा किए गए लिंक्स में सुरक्षित शासन प्रणालियां डिज़ाइन(opens in a new tab) करने, डीएओ में विभिन्न मतदान मैकेनिज्म(opens in a new tab) और DeFi का लाभ उठाने वाले सामान्य डीएओ हमला वेक्टर्स(opens in a new tab) के बारे में अधिक जानकारी है।

8. कोड में जटिलता को न्यूनतम करें

पारंपरिक सॉफ्टवेयर डेवलपर्स KISS (“इसे सरल रखो, बेवकूफ़“) सिद्धांत से परिचित हैं, जो सॉफ्टवेयर डिज़ाइन में अनावश्यक जटिलता लाने के खिलाफ सलाह देता है। यह लंबे समय से चली आ रही सोच का अनुसरण करता है कि “जटिल प्रणालियां जटिल तरीकों से विफल होती हैं” और महंगी त्रुटियों के प्रति अधिक संवेदनशील होते हैं।

स्मार्ट अनुबंध लिखते समय चीजों को सरल रखना विशेष रूप से महत्वपूर्ण है, क्योंकि स्मार्ट अनुबंध संभवतः बड़ी मात्रा में मूल्य को नियंत्रित कर रहे हैं। स्मार्ट अनुबंध लिखते समय सरलता प्राप्त करने के लिए एक सुझाव है कि जहां संभव हो, OpenZeppelin अनुबंधों(opens in a new tab) जैसी मौजूदा लाइब्रेरीज का पुन: उपयोग करें। चूंकि इन लाइब्रेरीज की डेवलपर्स द्वारा व्यापक रूप से ऑडिट और परीक्षण किया गया है, इनका उपयोग करने से नई कार्यक्षमता को शुरू से लिखने की तुलना में बग पेश करने की संभावना कम हो जाती है।

एक अन्य सामान्य सलाह छोटे फंक्शंस लिखना और व्यावसायिक तर्क को कई अनुबंधों में विभाजित करके कॉन्ट्रैक्ट्स को मॉड्यूलर रखना है। न केवल सरल कोड लिखने से स्मार्ट अनुबंध में हमले की सतह कम होती है, बल्कि यह समग्र सिस्टम की सटीकता के बारे में तर्क करना और संभावित डिज़ाइन त्रुटियों का जल्दी पता लगाना भी आसान बनाता है।

9. सामान्य स्मार्ट अनुबंध कमजोरियों से बचाव करें

रीएंट्रेंसी

EVM समवर्तिता की अनुमति नहीं देता है, जिसका अर्थ है कि एक संदेश कॉल में शामिल दो अनुबंध एक साथ नहीं चल सकते। एक बाहरी कॉल कॉलिंग अनुबंध के निष्पादन और मेमोरी को तब तक रोक देता है जब तक कि कॉल वापस नहीं आता, जिस बिंदु पर निष्पादन सामान्य रूप से आगे बढ़ता है। इस प्रक्रिया को औपचारिक रूप से दूसरे अनुबंध को नियंत्रण प्रवाह(opens in a new tab) स्थानांतरित करने के रूप में वर्णित किया जा सकता है।

हालांकि ज्यादातर हानिरहित, अविश्वसनीय अनुबंधों को नियंत्रण प्रवाह स्थानांतरित करने से समस्याएं हो सकती हैं, जैसे रीएंट्रेंसी। एक रीएंट्रेंसी अटैक तब होता है जब एक दुर्भावनापूर्ण अनुबंध मूल फंक्शन इनवोकेशन पूरा होने से पहले एक कमजोर अनुबंध में वापस कॉल करता है। इस प्रकार के हमले को एक उदाहरण के साथ सबसे अच्छी तरह से समझाया जाता है।

एक सरल स्मार्ट अनुबंध (‘विक्टिम’) पर विचार करें जो किसी को भी ईथर जमा करने और निकालने की अनुमति देता है:

1// This contract is vulnerable. Do not use in production
2
3contract Victim {
4 mapping (address => uint256) public balances;
5
6 function deposit() external payable {
7 balances[msg.sender] += msg.value;
8 }
9
10 function withdraw() external {
11 uint256 amount = balances[msg.sender];
12 (bool success, ) = msg.sender.call.value(amount)("");
13 require(success);
14 balances[msg.sender] = 0;
15 }
16}
सभी दिखाएँ
कॉपी करें

यह अनुबंध एक withdraw() फंक्शन को एक्सपोज़ करता है जो उपयोगकर्ताओं को पहले अनुबंध में जमा किए गए ETH को निकालने की अनुमति देता है। निकासी को संसाधित करते समय, अनुबंध निम्नलिखित कार्य करता है:

  1. यूज़र के ETH बैलेंस की जांच करता है
  2. कॉलिंग एड्रेस को फंड भेजता है
  3. उस यूज़र से अतिरिक्त निकासी को रोकने के लिए उनके बैलेंस को 0 में रीसेट करता है

Victim अनुबंध में withdraw() फंक्शन “चेक्स-इंटरैक्शंस-इफेक्ट्स” पैटर्न का पालन करता है। यह चेक यदि निष्पादन के लिए आवश्यक शर्तें संतुष्ट हैं (यानी, यूज़र के पास सकारात्मक ETH शेष है) और लेनदेन के प्रभाव को लागू करने से पहले, कॉलर के पते पर ETH भेजकर इंटरैक्शन निष्पादित करता है (यानी, यूज़र की शेष राशि को कम करना)।

यदि बाहरी स्वामित्व वाले खाते (EOA) से withdraw() को कॉल किया जाता है, तो फंक्शन अपेक्षित रूप से निष्पादित होता है: msg.sender.call.value() कॉलर को ETH भेजता है। हालाँकि, यदि msg.sender एक स्मार्ट अनुबंध खाता कॉल withdraw() है, तो msg.sender.call.value() का उपयोग करके धन भेजना भी उस पते पर संग्रहित कोड को चलाने के लिए ट्रिगर करेगा।

कल्पना कीजिए कि यह अनुबंध पते पर परिनियोजित कोड है:

1 contract Attacker {
2 function beginAttack() external payable {
3 Victim(victim_address).deposit.value(1 ether)();
4 Victim(victim_address).withdraw();
5 }
6
7 function() external payable {
8 if (gasleft() > 40000) {
9 Victim(victim_address).withdraw();
10 }
11 }
12}
सभी दिखाएँ
कॉपी करें

यह अनुबंध तीन काम करने के लिए डिज़ाइन किया गया है:

  1. किसी अन्य खाते से जमा स्वीकार करें (संभवतः हमलावर का EOA)
  2. विक्टिम कॉन्ट्रैक्ट में 1 ETH को जमा करें
  3. स्मार्ट अनुबंध में संग्रहित 1 ETH को निकालें

यहां कुछ भी गलत नहीं है, सिवाय इसके कि Attacker के पास एक और फंक्शन है जो Victim में फिर से withdraw() को कॉल करता है यदि इनकमिंग msg.sender.call.value से बची हुई गैस 40,000 से अधिक है। यह Attacker को Victim को फिर से दर्ज करने और निकासी का पहला प्रयास पूरा होने से पहले अधिक धनराशि निकालने की क्षमता देता है। चक्र इस तरह दिखता है:

1- Attacker's EOA calls `Attacker.beginAttack()` with 1 ETH
2- `Attacker.beginAttack()` deposits 1 ETH into `Victim`
3- `Attacker` calls `withdraw() in `Victim`
4- `Victim` checks `Attacker`’s balance (1 ETH)
5- `Victim` sends 1 ETH to `Attacker` (which triggers the default function)
6- `Attacker` calls `Victim.withdraw()` again (note that `Victim` hasn’t reduced `Attacker`’s balance from the first withdrawal)
7- `Victim` checks `Attacker`’s balance (which is still 1 ETH because it hasn’t applied the effects of the first call)
8- `Victim` sends 1 ETH to `Attacker` (which triggers the default function and allows `Attacker` to reenter the `withdraw` function)
9- The process repeats until `Attacker` runs out of gas, at which point `msg.sender.call.value` returns without triggering additional withdrawals
10- `Victim` finally applies the results of the first transaction (and subsequent ones) to its state, so `Attacker`’s balance is set to 0
सभी दिखाएँ
कॉपी करें

सारांश यह है कि क्योंकि फंक्शन निष्पादन पूरा होने तक कॉलर की शेष राशि 0 पर सेट नहीं होती है, बाद के प्रयास सफल होंगे और कॉलर को कई बार अपनी शेष राशि वापस लेने की अनुमति देंगे। इस तरह के हमले का उपयोग अपने धन के एक स्मार्ट अनुबंध को निकालने के लिए किया जा सकता है, जैसा कि 2016 डीएओ हैक(opens in a new tab) में हुआ था। रीएंट्रेंसी हमले आज भी स्मार्ट अनुबंध के लिए एक महत्वपूर्ण मुद्दा है जैसा कि रीएंट्रेंसी शोषण की सार्वजनिक सूचियां(opens in a new tab) दिखाती है।

रीएंट्रेंसी हमलों को कैसे रोकें

रीएंट्रेंसी से निपटने के लिए एक दृष्टिकोण चेक-इफेक्ट-इंटरैक्शन पैटर्न(opens in a new tab) का अनुसरण करना है। यह पैटर्न इस तरह से कार्यों के निष्पादन का आदेश देता है कि निष्पादन से पहले आवश्यक जांच करने वाला कोड पहले आता है, उसके बाद अनुबंध स्थिति में हेरफेर करने वाला कोड आता है, और अन्य अनुबंधों या EOA के साथ इंटरैक्शन करने वाला कोड अंत में आता है।

चेक-इफेक्ट-इंटरैक्शन पैटर्न का इस्तेमाल Victim अनुबंध के संशोधित संस्करण में किया गया है, जो नीचे दिखाया गया है:

1contract NoLongerAVictim {
2 function withdraw() external {
3 uint256 amount = balances[msg.sender];
4 balances[msg.sender] = 0;
5 (bool success, ) = msg.sender.call.value(amount)("");
6 require(success);
7 }
8}
कॉपी करें

यह अनुबंध यूज़र की शेष राशि की जांच करता है, withdraw() फंक्शन के प्रभावों को लागू करता है (यूज़र की शेष राशि को 0 पर रीसेट करके), और इंटरैक्शन करने के लिए आगे बढ़ता है (यूज़र के पते पर ETH भेजना)। यह सुनिश्चित करता है कि अनुबंध बाहरी कॉल से पहले अपने भंडारण को अपडेट करता है, फिर से प्रवेश की स्थिति को समाप्त करता है जिसने पहले हमले को सक्षम किया था। Attacker अनुबंध अभी भी NoLongerAVictim में वापस कॉल कर सकता है, लेकिन चूंकि balances[msg.sender] को 0 पर सेट किया गया है, अतिरिक्त निकासी एक त्रुटि देगी।

एक अन्य विकल्प एक पारस्परिक बहिष्करण लॉक (आमतौर पर "म्यूटेक्स" के रूप में वर्णित) का उपयोग करना है जो एक अनुबंध के राज्य के एक हिस्से को तब तक लॉक करता है जब तक कि एक फंक्शन आमंत्रण पूरा नहीं हो जाता। यह एक बूलियन वेरिएबल का उपयोग करके कार्यान्वित किया जाता है जो फंक्शन निष्पादित होने से पहले true पर सेट होता है और प्रयास किए जाने के बाद false पर वापस आ जाता है। जैसा कि नीचे दिए गए उदाहरण में देखा गया है, म्यूटेक्स का उपयोग रिकर्सिव कॉल के खिलाफ एक फंक्शन की रक्षा करता है, जबकि मूल प्रयास अभी भी प्रोसेस हो रहा है, प्रभावी रूप से पुनरावृत्ति को रोक रहा है।

1pragma solidity ^0.7.0;
2
3contract MutexPattern {
4 bool locked = false;
5 mapping(address => uint256) public balances;
6
7 modifier noReentrancy() {
8 require(!locked, "Blocked from reentrancy.");
9 locked = true;
10 _;
11 locked = false;
12 }
13 // This function is protected by a mutex, so reentrant calls from within `msg.sender.call` cannot call `withdraw` again.
14 // The `return` statement evaluates to `true` but still evaluates the `locked = false` statement in the modifier
15 function withdraw(uint _amount) public payable noReentrancy returns(bool) {
16 require(balances[msg.sender] >= _amount, "No balance to withdraw.");
17
18 balances[msg.sender] -= _amount;
19 bool (success, ) = msg.sender.call{value: _amount}("");
20 require(success);
21
22 return true;
23 }
24}
सभी दिखाएँ
कॉपी करें

आप एक पुल भुगतान(opens in a new tab) प्रणाली का भी उपयोग कर सकते हैं जिसमें उपयोगकर्ताओं को "पुश भुगतान" प्रणाली के बजाय स्मार्ट अनुबंधों से धन निकालने की आवश्यकता होती है जो खातों में धनराशि भेजती है। यह अज्ञात पतों पर अनजाने में कोड ट्रिगर करने की संभावना को हटा देता है (और कुछ इनकार-की-सेवा हमलों को भी रोक सकता है)।

इन्टिजर अंडरफ्लो और ओवरफ्लो

एक इन्टिजर ओवरफ्लो तब होता है जब एक अंकगणितीय ऑपरेशन के परिणाम मूल्यों की स्वीकार्य सीमा से बाहर हो जाते हैं, जिससे यह सबसे कम प्रतिनिधित्व योग्य मूल्य पर "रोल ओवर" हो जाता है। उदाहरण के लिए, एक uint8 केवल 2^8-1=255 तक के मान संग्रहित कर सकता है। अंकगणितीय संचालन जिसके परिणामस्वरूप 255 से अधिक मान होते हैं, ओवरफ्लो हो जाएंगे और uint को 0 पर रीसेट कर देंगे, ठीक उसी तरह जैसे कार पर ओडोमीटर अधिकतम माइलेज (999999) तक पहुंचने के बाद 0 पर रीसेट हो जाता है।

इन्टिजर अंडरफ्लो समान कारणों से होता है: अंकगणितीय ऑपरेशन के परिणाम स्वीकार्य सीमा से नीचे आते हैं। मान लें कि आपने uint8 में 0 को कम करने का प्रयास किया है, तो परिणाम केवल अधिकतम प्रतिनिधित्व योग्य मूल्य (255) पर रोल करेगा।

इन्टिजर ओवरफ्लो और अंडरफ्लो दोनों एक अनुबंध के स्टेट वेरिएबल्स में अप्रत्याशित परिवर्तन कर सकते हैं और परिणामस्वरूप अनियोजित निष्पादन हो सकता है। नीचे एक उदाहरण दिखाया गया है कि कैसे एक हमलावर एक अमान्य संचालन करने के लिए एक स्मार्ट अनुबंध में अंकगणितीय ओवरफ्लो का फायदा उठा सकता है:

1pragma solidity ^0.7.6;
2
3// This contract is designed to act as a time vault.
4// User can deposit into this contract but cannot withdraw for at least a week.
5// User can also extend the wait time beyond the 1 week waiting period.
6
7/*
81. Deploy TimeLock
92. Deploy Attack with address of TimeLock
103. Call Attack.attack sending 1 ether. You will immediately be able to
11 withdraw your ether.
12
13What happened?
14Attack caused the TimeLock.lockTime to overflow and was able to withdraw
15before the 1 week waiting period.
16*/
17
18contract TimeLock {
19 mapping(address => uint) public balances;
20 mapping(address => uint) public lockTime;
21
22 function deposit() external payable {
23 balances[msg.sender] += msg.value;
24 lockTime[msg.sender] = block.timestamp + 1 weeks;
25 }
26
27 function increaseLockTime(uint _secondsToIncrease) public {
28 lockTime[msg.sender] += _secondsToIncrease;
29 }
30
31 function withdraw() public {
32 require(balances[msg.sender] > 0, "Insufficient funds");
33 require(block.timestamp > lockTime[msg.sender], "Lock time not expired");
34
35 uint amount = balances[msg.sender];
36 balances[msg.sender] = 0;
37
38 (bool sent, ) = msg.sender.call{value: amount}("");
39 require(sent, "Failed to send Ether");
40 }
41}
42
43contract Attack {
44 TimeLock timeLock;
45
46 constructor(TimeLock _timeLock) {
47 timeLock = TimeLock(_timeLock);
48 }
49
50 fallback() external payable {}
51
52 function attack() public payable {
53 timeLock.deposit{value: msg.value}();
54 /*
55 if t = current lock time then we need to find x such that
56 x + t = 2**256 = 0
57 so x = -t
58 2**256 = type(uint).max + 1
59 so x = type(uint).max + 1 - t
60 */
61 timeLock.increaseLockTime(
62 type(uint).max + 1 - timeLock.lockTime(address(this))
63 );
64 timeLock.withdraw();
65 }
66}
सभी दिखाएँ
इन्टिजर अंडरफ्लो और ओवरफ्लो को कैसे रोकें

संस्करण 0.8.0 के रूप में, Solidity कंपाइलर कोड को अस्वीकार करता है जिसके परिणामस्वरूप इन्टिजर अंडरफ्लो और ओवरफ्लो होता है। हालांकि, निचले कंपाइलर संस्करण के साथ संकलित अनुबंधों को या तो अंकगणितीय संचालन से जुड़े फंक्शंस पर जांच करनी चाहिए या एक लाइब्रेरी का उपयोग करना चाहिए (उदाहरण के लिए, SafeMath(opens in a new tab)) जो अंडरफ्लो/ओवरफ्लो की जांच करती है।

ओरेकल हेरफेर

ओरेकल्स ऑफ-चेन जानकारी और स्मार्ट अनुबंधों का उपयोग करने के लिए इसे ऑन-चेन भेजता है। ओरेकल्स के साथ, आप स्मार्ट अनुबंधों को डिज़ाइन कर सकते हैं जो ऑफ-चेन सिस्टम जैसे कि पूंजी बाजार के साथ इंटरऑपरेट करते हैं, जिससे उनके एप्लिकेशन का विस्तार होता है।

लेकिन अगर ओरेकल खराब है और गलत जानकारी भेजता है तो ऑन-चेन, स्मार्ट अनुबंध गलत इनपुट के आधार पर निष्पादित होंगे, जिससे समस्याएं हो सकती हैं। यह “ओरेकल समस्या” का आधार है, जो यह सुनिश्चित करने के कार्य से संबंधित है कि ब्लॉकचेन ऑरेकल से जानकारी सटीक, अद्यतित और समय पर है।

एक संबंधित सुरक्षा चिंता एक ऑन-चेन ओरेकल का उपयोग कर रही है, जैसे कि विकेन्द्रीकृत एक्सचेंज, ताकि किसी संपत्ति के लिए स्पॉट मूल्य प्राप्त किया जा सके। विकेंद्रीकृत वित्त (DeFi) उद्योग में उधार देने वाले प्लेटफॉर्म अक्सर यूज़र के कोलेट्रल मूल्य को निर्धारित करने के लिए ऐसा करते हैं ताकि यह निर्धारित किया जा सके कि वे कितना उधार ले सकते हैं।

DEX की कीमतें अक्सर सटीक होती हैं, मुख्यतः मध्यस्थों द्वारा बाजारों में समानता बहाल करने के कारण। हालांकि, वे हेरफेर के लिए खुले हैं, खासकर अगर ऑन-चेन ओरेकल ऐतिहासिक ट्रेडिंग पैटर्न के आधार पर परिसंपत्ति की कीमतों की गणना करता है (जैसा कि आमतौर पर होता है)।

उदाहरण के लिए, एक हमलावर आपके उधार अनुबंध के साथ इंटरैक्ट करने से ठीक पहले फ्लैश ऋण लेकर किसी संपत्ति के स्पॉट मूल्य को कृत्रिम रूप से बढ़ा सकता है। संपत्ति की कीमत के लिए DEX को क्वेरी करने से सामान्य से अधिक मूल्य वापस आ जाएगा (हमलावर के बड़े “खरीद ऑर्डर” के कारण संपत्ति की मांग में कमी आएगी), जिससे उन्हें जरूरत से अधिक उधार लेने की अनुमति मिलती है। इस तरह के "फ्लैश लोन अटैक" का उपयोग DeFi एप्लिकेशन के बीच मूल्य ओरेकल्स पर निर्भरता का फायदा उठाने के लिए किया गया है, जिससे प्रोटोकॉल को लाखों डॉलर का नुकसान हुआ है।

ओरेकल हेरफेर को कैसे रोकें

ओरेकल हेरफेर से बचने(opens in a new tab) की न्यूनतम आवश्यकता एक विकेन्द्रीकृत ओरेकल नेटवर्क का उपयोग करना है, जो विफलता के एकल बिंदुओं से बचने के लिए कई स्रोतों से जानकारी लेता है। ज्यादातर मामलों में, विकेन्द्रीकृत ओरेकल्स में ओरेकल नोड्स को सही जानकारी की रिपोर्ट करने के लिए प्रोत्साहित करने के लिए बिल्ट-इन क्रिप्टोइकॉनॉमिक प्रोत्साहन होते हैं, जिससे वे केंद्रीकृत ओरेकल्स की तुलना में अधिक सुरक्षित हो जाते हैं।

यदि आप परिसंपत्ति की कीमतों के लिए ऑन-चेन ओरेकल को क्वेरी करने की योजना बनाते हैं, तो समय-भारित औसत मूल्य (TWAP) मैकेनिज्म को लागू करने वाले का उपयोग करने पर विचार करें। TWAP ओरेकल(opens in a new tab) समय में दो अलग-अलग बिंदुओं पर एक परिसंपत्ति की कीमत पूछता है (जिसे आप संशोधित कर सकते हैं) और प्राप्त औसत के आधार पर स्पॉट मूल्य की गणना करता है। लंबी समयावधि चुनना आपके प्रोटोकॉल को मूल्य हेरफेर से बचाता है क्योंकि हाल ही में निष्पादित बड़े ऑर्डर परिसंपत्ति की कीमतों को प्रभावित नहीं कर सकते हैं।

डेवलपर्स के लिए स्मार्ट अनुबंध सुरक्षा संसाधन

स्मार्ट अनुबंध के विश्लेषण और कोड सटीकता की पुष्टि के लिए उपकरण

  • टेस्टिंग उपकरण और लाइब्रेरीज - स्मार्ट अनुबंधों पर यूनिट टेस्ट, स्टेटिक विश्लेषण और डायनामिक विश्लेषण करने के लिए उद्योग-मानक उपकरण और लाइब्रेरीज का संग्रह।

  • फॉर्मल सत्यापन उपकरण - स्मार्ट अनुबंधों में फंक्शनल सटीकता की पुष्टि करने और इनवेरिएंट्स की जांच करने के लिए उपकरण।

  • स्मार्ट अनुबंध ऑडिटिंग की सेवाएं - एथेरियम डेवलपमेंट प्रोजेक्ट्स के लिए स्मार्ट अनुबंध ऑडिटिंग सेवाएं प्रदान करने वाले संगठनों की सूची।

  • बग बाउंटी प्लेटफॉर्म - बग बाउंटी के समन्वय और स्मार्ट अनुबंधों में महत्वपूर्ण कमजोरियों के जिम्मेदार प्रकटीकरण को पुरस्कृत करने के लिए प्लेटफॉर्म।

  • फोर्क चेकर(opens in a new tab) - किसी भी फोर्क्ड अनुबंध के बारे में सभी उपलब्ध जानकारी की जांच करने के लिए एक मुफ्त ऑनलाइन उपकरण।

  • ABI एनकोडर(opens in a new tab) - Solidity अनुबंध फंक्शंस और कंस्ट्रक्टर आर्ग्यूमेंट्स के लिए एक मुफ्त ऑनलाइन सेवा।

  • ऐडर्न(opens in a new tab) - Solidity स्टेटिक विश्लेषक, एब्सट्रैक्ट सिंटैक्स ट्रीज (AST) के माध्यम से संदिग्ध कमजोरियों की पहचान करने और मार्कडाउन प्रारूप में मुद्दों का प्रिंटआउट करने के लिए एक उपकरण।

स्मार्ट अनुबंधों की निगरानी के लिए उपकरण

स्मार्ट अनुबंधों के सुरक्षित प्रशासन के लिए उपकरण

स्मार्ट अनुबंध ऑडिटिंग सेवाएँ

बग बाउंटी प्लेटफॉर्म

ज्ञात स्मार्ट अनुबंध कमजोरियों और शोषण के प्रकाशन

स्मार्ट अनुबंध सुरक्षा सीखने के लिए चुनौतियाँ

स्मार्ट अनुबंधों को सुरक्षित करने के लिए सर्वोत्तम प्रथाएँ

स्मार्ट अनुबंध सुरक्षा पर ट्यूटोरियल

क्या यह लेख सहायक था?