प्रमुख मजकुराकडे जा
Change page

स्मार्ट कॉन्ट्रॅक्ट सुरक्षा

पृष्ठ अखेरचे अद्यतन: २६ फेब्रुवारी, २०२६

स्मार्ट कॉन्ट्रॅक्ट्स अत्यंत लवचिक आहेत आणि ब्लॉकचेनवर तैनात केलेल्या कोडवर आधारित अपरिवर्तनीय तर्क चालवताना मोठ्या प्रमाणात मूल्य आणि डेटा नियंत्रित करण्यास सक्षम आहेत. यामुळे विश्वासहीन आणि विकेंद्रित ॲप्लिकेशन्सची एक उत्साही इकोसिस्टम तयार झाली आहे जी जुन्या सिस्टीमपेक्षा अनेक फायदे प्रदान करते. ते स्मार्ट कॉन्ट्रॅक्ट्समधील असुरक्षिततेचा फायदा घेऊन नफा मिळवू पाहणाऱ्या हल्लेखोरांसाठी संधी देखील दर्शवतात.

Ethereum सारखे सार्वजनिक ब्लॉकचेन्स, स्मार्ट कॉन्ट्रॅक्ट्स सुरक्षित करण्याच्या समस्येला आणखी गुंतागुंतीचे करतात. तैनात केलेला कॉन्ट्रॅक्ट कोड सहसा सुरक्षा त्रुटी दूर करण्यासाठी बदलला जाऊ शकत नाही, तर स्मार्ट कॉन्ट्रॅक्ट्समधून चोरलेली मालमत्ता अपरिवर्तनीयतेमुळे ट्रॅक करणे अत्यंत कठीण आणि बहुतेक वेळा परत मिळवता न येण्याजोगी असते.

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

वर नमूद केलेल्या समस्यांमुळे डेव्हलपर्सना सुरक्षित, मजबूत आणि लवचिक स्मार्ट कॉन्ट्रॅक्ट्स तयार करण्यासाठी प्रयत्न करणे अनिवार्य होते. स्मार्ट कॉन्ट्रॅक्ट सुरक्षा हा एक गंभीर विषय आहे, आणि प्रत्येक डेव्हलपरने तो शिकणे चांगले आहे. हे मार्गदर्शक Ethereum डेव्हलपर्ससाठी सुरक्षा विचारांचा आढावा घेईल आणि स्मार्ट कॉन्ट्रॅक्ट सुरक्षा सुधारण्यासाठी संसाधने शोधेल.

पूर्वतयारी

सुरक्षेचा सामना करण्यापूर्वी तुम्ही स्मार्ट कॉन्ट्रॅक्ट डेव्हलपमेंटच्या मूलभूत गोष्टींशी परिचित आहात याची खात्री करा.

सुरक्षित Ethereum स्मार्ट कॉन्ट्रॅक्ट्स तयार करण्यासाठी मार्गदर्शक तत्त्वे

१. योग्य प्रवेश नियंत्रणे डिझाइन करा

स्मार्ट कॉन्ट्रॅक्ट्समध्ये, public किंवा external म्हणून चिन्हांकित केलेली फंक्शन्स कोणत्याही बाह्य मालकीच्या खात्यांद्वारे (EOAs) किंवा कॉन्ट्रॅक्ट खात्यांद्वारे कॉल केली जाऊ शकतात. जर तुम्हाला इतरांना तुमच्या कॉन्ट्रॅक्टशी संवाद साधायचा असेल तर फंक्शन्ससाठी सार्वजनिक दृश्यमानता निर्दिष्ट करणे आवश्यक आहे. तथापि, private म्हणून चिन्हांकित केलेली फंक्शन्स केवळ स्मार्ट कॉन्ट्रॅक्टमधील फंक्शन्सद्वारेच कॉल केली जाऊ शकतात, बाह्य खात्यांद्वारे नाही. प्रत्येक नेटवर्क सहभागीला कॉन्ट्रॅक्ट फंक्शन्समध्ये प्रवेश दिल्याने समस्या उद्भवू शकतात, विशेषतः जर याचा अर्थ कोणीही संवेदनशील ऑपरेशन्स करू शकतो (उदा. नवीन टोकन मिंट करणे).

स्मार्ट कॉन्ट्रॅक्ट फंक्शन्सचा अनधिकृत वापर रोखण्यासाठी, सुरक्षित प्रवेश नियंत्रणे लागू करणे आवश्यक आहे. प्रवेश नियंत्रण यंत्रणा स्मार्ट कॉन्ट्रॅक्टमधील विशिष्ट फंक्शन्स वापरण्याची क्षमता मंजूर घटकांपुरती मर्यादित ठेवते, जसे की कॉन्ट्रॅक्ट व्यवस्थापित करण्यासाठी जबाबदार खाती. Ownable पॅटर्न आणि भूमिका-आधारित नियंत्रण हे स्मार्ट कॉन्ट्रॅक्ट्समध्ये प्रवेश नियंत्रण लागू करण्यासाठी उपयुक्त असलेले दोन पॅटर्न आहेत:

Ownable पॅटर्न

Ownable पॅटर्नमध्ये, कॉन्ट्रॅक्ट-निर्मिती प्रक्रियेदरम्यान एक ॲड्रेस कॉन्ट्रॅक्टचा “मालक” म्हणून सेट केला जातो. संरक्षित फंक्शन्सना OnlyOwner मॉडिफायर दिला जातो, जो फंक्शन कार्यान्वित करण्यापूर्वी कॉन्ट्रॅक्ट कॉलिंग ॲड्रेसची ओळख प्रमाणित करतो याची खात्री करतो. कॉन्ट्रॅक्ट मालकाव्यतिरिक्त इतर ॲड्रेसवरून संरक्षित फंक्शन्सना केलेले कॉल्स नेहमी परत येतात, ज्यामुळे अवांछित प्रवेश रोखला जातो.

भूमिका-आधारित प्रवेश नियंत्रण

स्मार्ट कॉन्ट्रॅक्टमध्ये एकाच ॲड्रेसला Owner म्हणून नोंदणी केल्याने केंद्रीकरणाचा धोका निर्माण होतो आणि तो एकच अपयशाचा बिंदू दर्शवतो. जर मालकाच्या खात्याच्या कीजशी तडजोड झाली, तर हल्लेखोर मालकीच्या कॉन्ट्रॅक्टवर हल्ला करू शकतात. म्हणूनच एकाधिक प्रशासकीय खात्यांसह भूमिका-आधारित प्रवेश नियंत्रण पॅटर्न वापरणे हा एक चांगला पर्याय असू शकतो.

भूमिका-आधारित प्रवेश नियंत्रणामध्ये, संवेदनशील फंक्शन्समध्ये प्रवेश विश्वसनीय सहभागींच्या एका सेटमध्ये वितरित केला जातो. उदाहरणार्थ, एक खाते टोकन मिंट करण्यासाठी जबाबदार असू शकते, तर दुसरे खाते अपग्रेड करते किंवा कॉन्ट्रॅक्ट थांबवते. या प्रकारे प्रवेश नियंत्रणाचे विकेंद्रीकरण केल्याने अपयशाचे एकल बिंदू दूर होतात आणि वापरकर्त्यांसाठी विश्वासाची गृहितके कमी होतात.

मल्टी-सिग्नेचर वॉलेट्स वापरणे

सुरक्षित प्रवेश नियंत्रण लागू करण्याचा दुसरा दृष्टिकोन म्हणजे कॉन्ट्रॅक्ट व्यवस्थापित करण्यासाठी मल्टी-सिग्नेचर खाते वापरणे. नियमित EOA च्या विपरीत, मल्टी-सिग्नेचर खाती एकाधिक घटकांच्या मालकीची असतात आणि व्यवहार कार्यान्वित करण्यासाठी किमान संख्येच्या खात्यांकडून स्वाक्षरी आवश्यक असते — समजा 5 पैकी 3.

प्रवेश नियंत्रणासाठी मल्टीसिग वापरल्याने सुरक्षेचा एक अतिरिक्त स्तर येतो कारण लक्ष्य कॉन्ट्रॅक्टवरील क्रियांना अनेक पक्षांच्या संमतीची आवश्यकता असते. जर Ownable पॅटर्न वापरणे आवश्यक असेल तर हे विशेषतः उपयुक्त आहे, कारण यामुळे हल्लेखोर किंवा दुष्ट व्यक्तीसाठी दुर्भावनापूर्ण हेतूंसाठी संवेदनशील कॉन्ट्रॅक्ट फंक्शन्समध्ये फेरफार करणे अधिक कठीण होते.

२. कॉन्ट्रॅक्ट ऑपरेशन्सचे संरक्षण करण्यासाठी 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}
सर्व दाखवा

३. स्मार्ट कॉन्ट्रॅक्ट्सची चाचणी घ्या आणि कोडची अचूकता सत्यापित करा

Ethereum Virtual Machine मध्ये चालणाऱ्या कोडची अपरिवर्तनीयता म्हणजे स्मार्ट कॉन्ट्रॅक्ट्सना डेव्हलपमेंटच्या टप्प्यात उच्च पातळीच्या गुणवत्ता मूल्यांकनाची आवश्यकता असते. तुमच्या कॉन्ट्रॅक्टची विस्तृतपणे चाचणी करणे आणि कोणत्याही अनपेक्षित परिणामांसाठी त्याचे निरीक्षण केल्याने मोठ्या प्रमाणात सुरक्षा सुधारेल आणि दीर्घकाळात तुमच्या वापरकर्त्यांचे संरक्षण होईल.

नेहमीची पद्धत म्हणजे वापरकर्त्यांकडून कॉन्ट्रॅक्टला अपेक्षित असलेला मॉक डेटा वापरून लहान युनिट चाचण्या लिहिणे. युनिट टेस्टिंग हे विशिष्ट फंक्शन्सची कार्यक्षमता तपासण्यासाठी आणि स्मार्ट कॉन्ट्रॅक्ट अपेक्षेप्रमाणे काम करत असल्याची खात्री करण्यासाठी चांगले आहे.

दुर्दैवाने, एकटे वापरल्यास स्मार्ट कॉन्ट्रॅक्ट सुरक्षा सुधारण्यासाठी युनिट टेस्टिंग कमीतकमी प्रभावी आहे. एक युनिट चाचणी हे सिद्ध करू शकते की एखादे फंक्शन मॉक डेटासाठी योग्यरित्या कार्यान्वित होते, परंतु युनिट चाचण्या केवळ लिहिलेल्या चाचण्यांइतक्याच प्रभावी असतात. यामुळे तुमच्या स्मार्ट कॉन्ट्रॅक्टची सुरक्षितता धोक्यात आणू शकणारे सुटलेले एज केसेस आणि असुरक्षितता शोधणे कठीण होते.

एक चांगला दृष्टीकोन म्हणजे स्थिर आणि गतिशील विश्लेषण वापरून केलेल्या मालमत्ता-आधारित चाचणीसह युनिट चाचणी एकत्र करणे. स्थिर विश्लेषण पोहोचण्यायोग्य प्रोग्राम स्थिती आणि अंमलबजावणी मार्गांचे विश्लेषण करण्यासाठी कंट्रोल फ्लो ग्राफ्स (opens in a new tab) आणि ॲबस्ट्रॅक्ट सिंटॅक्स ट्रीज (opens in a new tab) सारख्या निम्न-स्तरीय प्रतिनिधित्वांवर अवलंबून असते. दरम्यान, स्मार्ट कॉन्ट्रॅक्ट फझिंग (opens in a new tab) सारखी गतिशील विश्लेषण तंत्रे, सुरक्षा गुणधर्मांचे उल्लंघन करणाऱ्या ऑपरेशन्स शोधण्यासाठी यादृच्छिक इनपुट मूल्यांसह कॉन्ट्रॅक्ट कोड कार्यान्वित करतात.

औपचारिक पडताळणी हे स्मार्ट कॉन्ट्रॅक्ट्समधील सुरक्षा गुणधर्म सत्यापित करण्याचे आणखी एक तंत्र आहे. नियमित चाचणीच्या विपरीत, औपचारिक पडताळणी स्मार्ट कॉन्ट्रॅक्टमधील त्रुटींची अनुपस्थिती निश्चितपणे सिद्ध करू शकते. हे एक औपचारिक स्पेसिफिकेशन तयार करून साध्य केले जाते जे इच्छित सुरक्षा गुणधर्मांना कॅप्चर करते आणि कॉन्ट्रॅक्ट्सचे औपचारिक मॉडेल या स्पेसिफिकेशनचे पालन करते हे सिद्ध करते.

४. तुमच्या कोडचे स्वतंत्र पुनरावलोकन करण्यास सांगा

तुमच्या कॉन्ट्रॅक्टची चाचणी घेतल्यानंतर, इतरांना कोणत्याही सुरक्षा समस्यांसाठी स्त्रोत कोड तपासण्यास सांगणे चांगले. चाचणीमुळे स्मार्ट कॉन्ट्रॅक्टमधील प्रत्येक त्रुटी उघड होणार नाही, परंतु स्वतंत्र पुनरावलोकन मिळाल्याने असुरक्षितता शोधण्याची शक्यता वाढते.

ऑडिट्स

स्मार्ट कॉन्ट्रॅक्ट ऑडिट करणे हा स्वतंत्र कोड पुनरावलोकन करण्याचा एक मार्ग आहे. ऑडिटर हे स्मार्ट कॉन्ट्रॅक्ट्स सुरक्षित आहेत आणि गुणवत्ता दोष आणि डिझाइन त्रुटींपासून मुक्त आहेत याची खात्री करण्यात महत्त्वाची भूमिका बजावतात.

तरीही, तुम्ही ऑडिटला रामबाण उपाय म्हणून मानणे टाळावे. स्मार्ट कॉन्ट्रॅक्ट ऑडिट्स प्रत्येक बग पकडणार नाहीत आणि बहुतेकदा पुनरावलोकनांची अतिरिक्त फेरी प्रदान करण्यासाठी डिझाइन केलेले असतात, जे प्रारंभिक डेव्हलपमेंट आणि चाचणी दरम्यान डेव्हलपर्सकडून सुटलेल्या समस्या शोधण्यात मदत करू शकतात. तुम्ही ऑडिटर्ससोबत काम करण्यासाठी सर्वोत्तम पद्धतींचे पालन केले पाहिजे, जसे की कोडचे योग्यरित्या दस्तऐवजीकरण करणे आणि इनलाइन टिप्पण्या जोडणे, जेणेकरून स्मार्ट कॉन्ट्रॅक्ट ऑडिटचा जास्तीत जास्त फायदा घेता येईल.

बग बाउंटीज

बग बाउंटी प्रोग्राम सेट करणे हा बाह्य कोड पुनरावलोकन लागू करण्याचा आणखी एक दृष्टीकोन आहे. बग बाउंटी हे ॲप्लिकेशनमधील असुरक्षितता शोधणाऱ्या व्यक्तींना (सहसा व्हाईटहॅट हॅकर्सना) दिलेले आर्थिक बक्षीस आहे.

योग्यरित्या वापरल्यास, बग बाउंटीज हॅकर समुदायाच्या सदस्यांना तुमच्या कोडमधील गंभीर त्रुटी तपासण्यासाठी प्रोत्साहन देतात. एक वास्तविक-जीवनातील उदाहरण म्हणजे “अनंत पैशाचा बग” ज्याने एका हल्लेखोराला Ethereum वर चालणाऱ्या लेयर 2 प्रोटोकॉल Optimism (opens in a new tab) वर अमर्याद प्रमाणात इथर तयार करण्याची परवानगी दिली असती. सुदैवाने, एका व्हाईटहॅट हॅकरने ही त्रुटी शोधली (opens in a new tab) आणि टीमला सूचित केले, या प्रक्रियेत मोठे बक्षीस मिळवले (opens in a new tab).

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

५. स्मार्ट कॉन्ट्रॅक्ट डेव्हलपमेंट दरम्यान सर्वोत्तम पद्धतींचे पालन करा

ऑडिट्स आणि बग बाउंटीजचे अस्तित्व उच्च-गुणवत्तेचा कोड लिहिण्याच्या तुमच्या जबाबदारीतून तुम्हाला सूट देत नाही. चांगली स्मार्ट कॉन्ट्रॅक्ट सुरक्षा योग्य डिझाइन आणि डेव्हलपमेंट प्रक्रियांचे पालन करण्यापासून सुरू होते:

  • सर्व कोड git सारख्या आवृत्ती नियंत्रण प्रणालीमध्ये संग्रहित करा

  • सर्व कोड बदल पुल रिक्वेस्ट्सद्वारे करा

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

  • स्मार्ट कॉन्ट्रॅक्ट्सची चाचणी, संकलन आणि उपयोजन करण्यासाठी विकास पर्यावरण वापरा

  • तुमचा कोड Cyfrin Aderyn (opens in a new tab), Mythril आणि Slither सारख्या मूलभूत कोड विश्लेषण साधनांमधून चालवा. आदर्शपणे, तुम्ही प्रत्येक पुल रिक्वेस्ट विलीन होण्यापूर्वी हे केले पाहिजे आणि आउटपुटमधील फरकांची तुलना केली पाहिजे

  • तुमचा कोड त्रुटींशिवाय संकलित होतो आणि सॉलिडिटी कंपाइलर कोणतीही चेतावणी देत नाही याची खात्री करा

  • तुमच्या कोडचे योग्यरित्या दस्तऐवजीकरण करा (NatSpec (opens in a new tab) वापरून) आणि कॉन्ट्रॅक्ट आर्किटेक्चरबद्दलचे तपशील समजण्यास सोप्या भाषेत वर्णन करा. यामुळे इतरांना तुमच्या कोडचे ऑडिट आणि पुनरावलोकन करणे सोपे होईल.

6. मजबूत आपत्कालीन पुनर्प्राप्ती योजना लागू करा

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

कॉन्ट्रॅक्ट अपग्रेड

Ethereum स्मार्ट कॉन्ट्रॅक्ट्स डीफॉल्टनुसार अपरिवर्तनीय असले तरी, अपग्रेड पॅटर्न वापरून काही प्रमाणात बदलक्षमता प्राप्त करणे शक्य आहे. ज्या प्रकरणांमध्ये गंभीर त्रुटीमुळे तुमचा जुना कॉन्ट्रॅक्ट निरुपयोगी होतो आणि नवीन तर्क तैनात करणे हा सर्वात व्यवहार्य पर्याय असतो, अशा प्रकरणांमध्ये कॉन्ट्रॅक्ट अपग्रेड करणे आवश्यक आहे.

कॉन्ट्रॅक्ट अपग्रेड यंत्रणा वेगवेगळ्या प्रकारे काम करतात, परंतु “प्रॉक्सी पॅटर्न” हा स्मार्ट कॉन्ट्रॅक्ट्स अपग्रेड करण्यासाठी अधिक लोकप्रिय दृष्टिकोनांपैकी एक आहे. प्रॉक्सी पॅटर्न्स (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), DAOs मधील विविध मतदान यंत्रणा (opens in a new tab), आणि DeFi चा लाभ घेणारे सामान्य DAO हल्ला वेक्टर (opens in a new tab) यावर अधिक.

8. कोडमधील गुंतागुंत कमीतकमी ठेवा

पारंपारिक सॉफ्टवेअर डेव्हलपर्स KISS (“keep it simple, stupid”) तत्त्वाशी परिचित आहेत, जे सॉफ्टवेअर डिझाइनमध्ये अनावश्यक गुंतागुंत आणण्याविरुद्ध सल्ला देते. हे “गुंतागुंतीच्या प्रणाली गुंतागुंतीच्या मार्गांनी अयशस्वी होतात” आणि महागड्या चुकांना अधिक बळी पडतात या दीर्घकालीन विचाराचे अनुसरण करते.

स्मार्ट कॉन्ट्रॅक्ट्स लिहिताना गोष्टी सोप्या ठेवणे विशेष महत्त्वाचे आहे, कारण स्मार्ट कॉन्ट्रॅक्ट्स संभाव्यतः मोठ्या प्रमाणात मूल्य नियंत्रित करतात. स्मार्ट कॉन्ट्रॅक्ट्स लिहिताना साधेपणा साधण्यासाठी एक टीप म्हणजे शक्य असेल तेथे OpenZeppelin Contracts (opens in a new tab) सारख्या विद्यमान लायब्ररींचा पुन्हा वापर करणे. कारण या लायब्ररींचे डेव्हलपर्सकडून विस्तृतपणे ऑडिट आणि चाचणी केली गेली आहे, त्यामुळे त्यांचा वापर केल्याने सुरवातीपासून नवीन कार्यक्षमता लिहून बग येण्याची शक्यता कमी होते.

आणखी एक सामान्य सल्ला म्हणजे लहान फंक्शन्स लिहिणे आणि एकाधिक कॉन्ट्रॅक्ट्समध्ये व्यावसायिक तर्क विभाजित करून कॉन्ट्रॅक्ट्स मॉड्यूलर ठेवणे. सोपा कोड लिहिल्याने केवळ स्मार्ट कॉन्ट्रॅक्टमधील हल्ल्याची पृष्ठभाग कमी होत नाही, तर संपूर्ण प्रणालीच्या अचूकतेबद्दल तर्क करणे आणि संभाव्य डिझाइन त्रुटी लवकर शोधणे देखील सोपे होते.

9. सामान्य स्मार्ट कॉन्ट्रॅक्ट असुरक्षिततेपासून बचाव करा

रीएन्ट्रन्सी

EVM समवर्तीतेस परवानगी देत नाही, याचा अर्थ मेसेज कॉलमध्ये सामील असलेले दोन कॉन्ट्रॅक्ट्स एकाच वेळी चालू शकत नाहीत. एक बाह्य कॉल कॉलिंग कॉन्ट्रॅक्टची अंमलबजावणी आणि मेमरी थांबवतो जोपर्यंत कॉल परत येत नाही, त्यानंतर अंमलबजावणी सामान्यपणे पुढे जाते. या प्रक्रियेचे औपचारिकपणे वर्णन कंट्रोल फ्लो (opens in a new tab) दुसऱ्या कॉन्ट्रॅक्टकडे हस्तांतरित करणे असे केले जाऊ शकते.

जरी बहुतेक वेळा निरुपद्रवी असले तरी, अविश्वासू कॉन्ट्रॅक्ट्सकडे कंट्रोल फ्लो हस्तांतरित केल्याने समस्या निर्माण होऊ शकतात, जसे की रीएन्ट्रन्सी. जेव्हा मूळ फंक्शनची विनंती पूर्ण होण्यापूर्वी एखादा दुर्भावनापूर्ण कॉन्ट्रॅक्ट असुरक्षित कॉन्ट्रॅक्टमध्ये परत कॉल करतो तेव्हा रीएन्ट्रन्सी हल्ला होतो. या प्रकारचा हल्ला एका उदाहरणासह उत्तम प्रकारे स्पष्ट केला आहे.

एक साधा स्मार्ट कॉन्ट्रॅक्ट (‘Victim’) विचारात घ्या जो कोणालाही इथर जमा आणि काढण्याची परवानगी देतो:

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}
सर्व दाखवा

हा कॉन्ट्रॅक्ट वापरकर्त्यांना कॉन्ट्रॅक्टमध्ये पूर्वी जमा केलेला ETH काढण्याची परवानगी देण्यासाठी withdraw() फंक्शन उघड करतो. पैसे काढण्याची प्रक्रिया करताना, कॉन्ट्रॅक्ट खालील ऑपरेशन्स करतो:

  1. वापरकर्त्याची ETH शिल्लक तपासते
  2. कॉलिंग ॲड्रेसवर निधी पाठवते
  3. त्यांची शिल्लक 0 वर रीसेट करते, ज्यामुळे वापरकर्त्याकडून अतिरिक्त पैसे काढणे प्रतिबंधित होते

Victim कॉन्ट्रॅक्टमधील withdraw() फंक्शन “चेक्स-इंटरॅक्शन्स-इफेक्ट्स” पॅटर्नचे अनुसरण करते. ते अंमलबजावणीसाठी आवश्यक असलेल्या अटी पूर्ण झाल्या आहेत का हे तपासते (उदा., वापरकर्त्याकडे सकारात्मक ETH शिल्लक आहे) आणि व्यवहाराचे परिणाम लागू करण्यापूर्वी कॉलरच्या ॲड्रेसवर ETH पाठवून संवाद साधते (उदा., वापरकर्त्याची शिल्लक कमी करणे).

जर withdraw() बाह्य मालकीच्या खात्यातून (EOA) कॉल केले असेल, तर फंक्शन अपेक्षेप्रमाणे कार्यान्वित होते: 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. Victim कॉन्ट्रॅक्टमध्ये 1 ETH जमा करा
  3. स्मार्ट कॉन्ट्रॅक्टमध्ये संग्रहित 1 ETH काढा

येथे काहीही चुकीचे नाही, फक्त Attacker कडे आणखी एक फंक्शन आहे जे Victim मधील withdraw() ला पुन्हा कॉल करते जर येणाऱ्या msg.sender.call.value मधून उरलेला गॅस 40,000 पेक्षा जास्त असेल. हे Attacker ला Victim मध्ये पुन्हा प्रवेश करण्याची आणि withdraw ची पहिली विनंती पूर्ण होण्यापूर्वी अधिक निधी काढण्याची क्षमता देते. हे चक्र असे दिसते:

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 च्या DAO हॅक (opens in a new tab) मध्ये घडल्याप्रमाणे, या प्रकारचा हल्ला स्मार्ट कॉन्ट्रॅक्टमधील निधी काढून घेण्यासाठी वापरला जाऊ शकतो. आजही स्मार्ट कॉन्ट्रॅक्ट्ससाठी रीएन्ट्रन्सी हल्ले ही एक गंभीर समस्या आहे, जसे की रीएन्ट्रन्सी शोषणांची सार्वजनिक सूची (opens in a new tab) दर्शवते.

रीएन्ट्रन्सी हल्ले कसे टाळावे

रीएन्ट्रन्सी हाताळण्याचा एक दृष्टीकोन म्हणजे चेक्स-इफेक्ट्स-इंटरॅक्शन्स पॅटर्न (opens in a new tab) चे अनुसरण करणे. हा पॅटर्न फंक्शन्सची अंमलबजावणी अशा प्रकारे क्रमबद्ध करतो की अंमलबजावणीसह पुढे जाण्यापूर्वी आवश्यक तपासणी करणारा कोड प्रथम येतो, त्यानंतर कॉन्ट्रॅक्ट स्थितीमध्ये फेरफार करणारा कोड आणि शेवटी इतर कॉन्ट्रॅक्ट्स किंवा EOAs शी संवाद साधणारा कोड येतो.

चेक्स-इफेक्ट-इंटरॅक्शन पॅटर्न 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 पासून, सॉलिडिटी कंपाइलर पूर्णांक अंडरफ्लो आणि ओव्हरफ्लोस कारणीभूत ठरणारा कोड नाकारतो. तथापि, कमी कंपाइलर आवृत्तीसह संकलित केलेल्या कॉन्ट्रॅक्ट्सनी एकतर अंकगणितीय ऑपरेशन्स असलेल्या फंक्शन्सवर तपासणी करावी किंवा अंडरफ्लो/ओव्हरफ्लोसाठी तपासणारी लायब्ररी (उदा. SafeMath (opens in a new tab)) वापरावी.

ओरॅकल मॅनिपुलेशन

ओरॅकल्स ऑफचेन माहिती मिळवतात आणि स्मार्ट कॉन्ट्रॅक्ट्सना वापरण्यासाठी ऑनचेन पाठवतात. ओरॅकल्ससह, तुम्ही स्मार्ट कॉन्ट्रॅक्ट्स डिझाइन करू शकता जे ऑफचेन सिस्टम्स, जसे की भांडवली बाजार, यांच्याशी आंतरकार्य करतात, ज्यामुळे त्यांच्या ॲप्लिकेशनचा विस्तार होतो.

परंतु जर ओरॅकल भ्रष्ट असेल आणि चुकीची माहिती ऑनचेन पाठवत असेल, तर स्मार्ट कॉन्ट्रॅक्ट्स चुकीच्या इनपुटवर आधारित कार्यान्वित होतील, ज्यामुळे समस्या निर्माण होऊ शकतात. हे “ओरॅकल समस्येचा” आधार आहे, जे ब्लॉकचेन ओरॅकलकडून आलेली माहिती अचूक, अद्ययावत आणि वेळेवर असल्याची खात्री करण्याच्या कार्याशी संबंधित आहे.

एका मालमत्तेची स्पॉट किंमत मिळविण्यासाठी ऑनचेन ओरॅकल, जसे की विकेंद्रित एक्सचेंज, वापरणे ही एक संबंधित सुरक्षा चिंता आहे. विकेंद्रित वित्त (DeFi) उद्योगातील कर्ज देणारे प्लॅटफॉर्म वापरकर्त्याच्या तारण मालमत्तेचे मूल्य निश्चित करण्यासाठी हे अनेकदा करतात, जेणेकरून ते किती कर्ज घेऊ शकतात हे ठरवता येईल.

DEX किमती अनेकदा अचूक असतात, मुख्यत्वे बाजारात समता पुनर्संचयित करणाऱ्या आर्बिट्रेजर्समुळे. तथापि, त्या फेरफारीसाठी खुल्या आहेत, विशेषतः जर ऑनचेन ओरॅकल ऐतिहासिक ट्रेडिंग पॅटर्नवर आधारित मालमत्ता किमतींची गणना करत असेल (जे सहसा घडते).

उदाहरणार्थ, एक हल्लेखोर तुमच्या कर्ज देणाऱ्या कॉन्ट्रॅक्टशी संवाद साधण्यापूर्वी फ्लॅश लोन घेऊन मालमत्तेची स्पॉट किंमत कृत्रिमरित्या वाढवू शकतो. मालमत्तेच्या किमतीसाठी DEX ची चौकशी केल्यास सामान्यपेक्षा जास्त मूल्य परत येईल (हल्लेखोराच्या मोठ्या “खरेदी ऑर्डर” मुळे मालमत्तेची मागणी विस्कळीत झाल्यामुळे), ज्यामुळे त्यांना गरजेपेक्षा जास्त कर्ज घेता येईल. अशा "फ्लॅश लोन हल्ल्यांचा" वापर DeFi ॲप्लिकेशन्समध्ये किंमत ओरॅकल्सवरील अवलंबित्व शोषण्यासाठी केला गेला आहे, ज्यामुळे प्रोटोकॉलना लाखो डॉलर्सचा निधी गमावावा लागला आहे.

ओरॅकल मॅनिपुलेशन कसे टाळावे

ओरॅकल मॅनिपुलेशन टाळण्यासाठी (opens in a new tab) किमान आवश्यकता म्हणजे विकेंद्रित ओरॅकल नेटवर्क वापरणे जे अपयशाचे एकल बिंदू टाळण्यासाठी अनेक स्त्रोतांकडून माहिती मिळवते. बहुतेक प्रकरणांमध्ये, विकेंद्रित ओरॅकल्समध्ये ओरॅकल नोड्सना योग्य माहिती कळवण्यासाठी प्रोत्साहित करण्यासाठी अंगभूत क्रिप्टोकॉनॉमिक प्रोत्साहन असते, ज्यामुळे ते केंद्रीकृत ओरॅकल्सपेक्षा अधिक सुरक्षित बनतात.

जर तुम्ही मालमत्ता किमतींसाठी ऑनचेन ओरॅकलची चौकशी करण्याची योजना आखत असाल, तर टाइम-वेटेड सरासरी किंमत (TWAP) यंत्रणा लागू करणारी एक वापरण्याचा विचार करा. एक TWAP ओरॅकल (opens in a new tab) दोन वेगवेगळ्या वेळी (जे तुम्ही सुधारू शकता) मालमत्तेच्या किमतीची चौकशी करते आणि मिळालेल्या सरासरीवर आधारित स्पॉट किंमत मोजते. लांब कालावधी निवडल्याने तुमचे प्रोटोकॉल किंमत फेरफारीपासून संरक्षित होते कारण अलीकडेच कार्यान्वित झालेल्या मोठ्या ऑर्डर्स मालमत्ता किमतींवर परिणाम करू शकत नाहीत.

डेव्हलपर्ससाठी स्मार्ट कॉन्ट्रॅक्ट सुरक्षा संसाधने

स्मार्ट कॉन्ट्रॅक्ट्सचे विश्लेषण करण्यासाठी आणि कोडची अचूकता सत्यापित करण्यासाठी साधने

  • चाचणी साधने आणि लायब्ररी - स्मार्ट कॉन्ट्रॅक्ट्सवर युनिट चाचण्या, स्थिर विश्लेषण आणि गतिशील विश्लेषण करण्यासाठी उद्योग-मानक साधने आणि लायब्ररींचा संग्रह.

  • औपचारिक पडताळणी साधने - स्मार्ट कॉन्ट्रॅक्ट्समध्ये कार्यात्मक अचूकता सत्यापित करण्यासाठी आणि अपरिवर्तनीयता तपासण्यासाठी साधने.

  • स्मार्ट कॉन्ट्रॅक्ट ऑडिटिंग सेवा - Ethereum विकास प्रकल्पांसाठी स्मार्ट कॉन्ट्रॅक्ट ऑडिटिंग सेवा प्रदान करणाऱ्या संस्थांची सूची.

  • बग बाउंटी प्लॅटफॉर्म - बग बाउंटीज समन्वयित करण्यासाठी आणि स्मार्ट कॉन्ट्रॅक्ट्समधील गंभीर असुरक्षिततेच्या जबाबदार प्रकटीकरणासाठी बक्षीस देण्यासाठी प्लॅटफॉर्म.

  • फोर्क चेकर (opens in a new tab) - फोर्क केलेल्या कॉन्ट्रॅक्टबद्दल सर्व उपलब्ध माहिती तपासण्यासाठी एक विनामूल्य ऑनलाइन साधन.

  • ABI एनकोडर (opens in a new tab) - तुमची सॉलिडिटी कॉन्ट्रॅक्ट फंक्शन्स आणि कन्स्ट्रक्टर युक्तिवाद एनकोड करण्यासाठी एक विनामूल्य ऑनलाइन सेवा.

  • Aderyn (opens in a new tab) - सॉलिडिटी स्टॅटिक ॲनालायझर, ॲबस्ट्रॅक्ट सिंटॅक्स ट्रीज (AST) मधून जात संशयित असुरक्षितता शोधतो आणि सोप्या-वाचण्यायोग्य मार्कडाउन स्वरूपात समस्या प्रिंट करतो.

स्मार्ट कॉन्ट्रॅक्ट्सचे निरीक्षण करण्यासाठी साधने

  • Tenderly रिअल-टाइम अलर्टिंग (opens in a new tab) - तुमच्या स्मार्ट कॉन्ट्रॅक्ट्स किंवा वॉलेट्सवर असामान्य किंवा अनपेक्षित घटना घडल्यास रिअल-टाइम सूचना मिळवण्यासाठी एक साधन.

स्मार्ट कॉन्ट्रॅक्ट्सच्या सुरक्षित प्रशासनासाठी साधने

  • Safe (opens in a new tab) - Ethereum वर चालणारा स्मार्ट कॉन्ट्रॅक्ट वॉलेट ज्यासाठी व्यवहार होण्यापूर्वी किमान संख्येच्या लोकांची मंजुरी आवश्यक असते (M-of-N).

  • OpenZeppelin Contracts (opens in a new tab) - कॉन्ट्रॅक्ट मालकी, अपग्रेड, प्रवेश नियंत्रणे, शासन, थांबवण्याची क्षमता आणि बरेच काही यासह प्रशासकीय वैशिष्ट्ये लागू करण्यासाठी कॉन्ट्रॅक्ट लायब्ररीज.

स्मार्ट कॉन्ट्रॅक्ट ऑडिटिंग सेवा

  • ConsenSys Diligence (opens in a new tab) - स्मार्ट कॉन्ट्रॅक्ट ऑडिटिंग सेवा जी ब्लॉकचेन इकोसिस्टममधील प्रकल्पांना त्यांचे प्रोटोकॉल लॉन्चसाठी तयार आहेत आणि वापरकर्त्यांचे संरक्षण करण्यासाठी तयार आहेत याची खात्री करण्यास मदत करते.

  • CertiK (opens in a new tab) - ब्लॉकचेन सुरक्षा फर्म जी स्मार्ट कॉन्ट्रॅक्ट्स आणि ब्लॉकचेन नेटवर्क्सवर अत्याधुनिक औपचारिक पडताळणी तंत्रज्ञानाचा वापर करण्यात अग्रणी आहे.

  • Trail of Bits (opens in a new tab) - सायबर सुरक्षा कंपनी जी धोका कमी करण्यासाठी आणि कोड मजबूत करण्यासाठी हल्लेखोर मानसिकतेसह सुरक्षा संशोधन एकत्र करते.

  • PeckShield (opens in a new tab) - ब्लॉकचेन सुरक्षा कंपनी जी संपूर्ण ब्लॉकचेन इकोसिस्टमच्या सुरक्षा, गोपनीयता आणि उपयोगितेसाठी उत्पादने आणि सेवा देते.

  • QuantStamp (opens in a new tab) - सुरक्षा आणि जोखीम मूल्यांकन सेवांद्वारे ब्लॉकचेन तंत्रज्ञानाचा मुख्य प्रवाहात अवलंब सुलभ करणारी ऑडिटिंग सेवा.

  • OpenZeppelin (opens in a new tab) - वितरित प्रणालींसाठी सुरक्षा ऑडिट प्रदान करणारी स्मार्ट कॉन्ट्रॅक्ट सुरक्षा कंपनी.

  • Runtime Verification (opens in a new tab) - स्मार्ट कॉन्ट्रॅक्ट्सच्या औपचारिक मॉडेलिंग आणि पडताळणीमध्ये विशेषज्ञ असलेली सुरक्षा कंपनी.

  • Hacken (opens in a new tab) - वेब3 सायबर सुरक्षा ऑडिटर जो ब्लॉकचेन सुरक्षेसाठी 360-डिग्री दृष्टिकोन आणतो.

  • Nethermind (opens in a new tab) - Solidity आणि Cairo ऑडिटिंग सेवा, Ethereum आणि Starknet वर स्मार्ट कॉन्ट्रॅक्ट्सची अखंडता आणि वापरकर्त्यांच्या सुरक्षिततेची खात्री करते.

  • HashEx (opens in a new tab) - HashEx ब्लॉकचेन आणि स्मार्ट कॉन्ट्रॅक्ट ऑडिटिंगवर लक्ष केंद्रित करते ज्यामुळे क्रिप्टोकरन्सीची सुरक्षा सुनिश्चित होते, स्मार्ट कॉन्ट्रॅक्ट डेव्हलपमेंट, पेनिट्रेशन टेस्टिंग, ब्लॉकचेन कन्सल्टिंग यासारख्या सेवा प्रदान करते.

  • Code4rena (opens in a new tab) - एक स्पर्धात्मक ऑडिट प्लॅटफॉर्म जो स्मार्ट कॉन्ट्रॅक्ट सुरक्षा तज्ञांना असुरक्षितता शोधण्यासाठी आणि वेब3 अधिक सुरक्षित बनविण्यात मदत करण्यासाठी प्रोत्साहन देतो.

  • CodeHawks (opens in a new tab) - सुरक्षा संशोधकांसाठी स्मार्ट कॉन्ट्रॅक्ट ऑडिटिंग स्पर्धा आयोजित करणारा स्पर्धात्मक ऑडिट प्लॅटफॉर्म.

  • Cyfrin (opens in a new tab) - वेब3 सुरक्षा पॉवरहाऊस, उत्पादने आणि स्मार्ट कॉन्ट्रॅक्ट ऑडिटिंग सेवांद्वारे क्रिप्टो सुरक्षा विकसित करते.

  • ImmuneBytes (opens in a new tab) - वेब3 सुरक्षा फर्म जी अनुभवी ऑडिटर्स आणि सर्वोत्तम साधनांच्या टीमद्वारे ब्लॉकचेन प्रणालींसाठी सुरक्षा ऑडिट प्रदान करते.

  • Oxorio (opens in a new tab) - क्रिप्टो फर्म्स आणि DeFi प्रकल्पांसाठी EVM, Solidity, ZK, क्रॉस-चेन टेक मध्ये कौशल्यासह स्मार्ट कॉन्ट्रॅक्ट ऑडिट आणि ब्लॉकचेन सुरक्षा सेवा.

  • Inference (opens in a new tab) - सुरक्षा ऑडिटिंग कंपनी, EVM-आधारित ब्लॉकचेनसाठी स्मार्ट कॉन्ट्रॅक्ट ऑडिटिंगमध्ये विशेषज्ञ. त्यांच्या तज्ञ ऑडिटर्समुळे ते संभाव्य समस्या ओळखतात आणि उपयोजनापूर्वी त्या दुरुस्त करण्यासाठी कृतीशील उपाय सुचवतात.

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

  • Immunefi (opens in a new tab) - स्मार्ट कॉन्ट्रॅक्ट्स आणि DeFi प्रकल्पांसाठी बग बाउंटी प्लॅटफॉर्म, जिथे सुरक्षा संशोधक कोडचे पुनरावलोकन करतात, असुरक्षितता उघड करतात, पैसे मिळवतात आणि क्रिप्टो अधिक सुरक्षित करतात.

  • HackerOne (opens in a new tab) - असुरक्षितता समन्वय आणि बग बाउंटी प्लॅटफॉर्म जो व्यवसायांना पेनिट्रेशन टेस्टर्स आणि सायबर सुरक्षा संशोधकांशी जोडतो.

  • HackenProof (opens in a new tab) - क्रिप्टो प्रकल्पांसाठी (DeFi, स्मार्ट कॉन्ट्रॅक्ट्स, वॉलेट्स, CEX आणि बरेच काही) तज्ञ बग बाउंटी प्लॅटफॉर्म, जिथे सुरक्षा व्यावसायिक ट्रायज सेवा प्रदान करतात आणि संशोधकांना संबंधित, सत्यापित बग अहवालांसाठी पैसे मिळतात.

  • Sherlock (opens in a new tab) - वेब3 मध्ये स्मार्ट कॉन्ट्रॅक्ट सुरक्षेसाठी अंडररायटर, ऑडिटर्ससाठी पेआउट स्मार्ट कॉन्ट्रॅक्ट्सद्वारे व्यवस्थापित केले जातात ज्यामुळे संबंधित बग्स योग्यरित्या दिले जातात हे सुनिश्चित होते.

  • CodeHawks (opens in a new tab) - स्पर्धात्मक बग बाउंटी प्लॅटफॉर्म जिथे ऑडिटर्स सुरक्षा स्पर्धा आणि आव्हानांमध्ये भाग घेतात, आणि (लवकरच) त्यांच्या स्वतःच्या खाजगी ऑडिटमध्ये.

ज्ञात स्मार्ट कॉन्ट्रॅक्ट असुरक्षितता आणि शोषणांची प्रकाशने

  • ConsenSys: ज्ञात स्मार्ट कॉन्ट्रॅक्ट हल्ले (opens in a new tab) - सर्वात महत्त्वपूर्ण कॉन्ट्रॅक्ट असुरक्षिततेचे नवशिक्यांसाठी अनुकूल स्पष्टीकरण, बहुतेक प्रकरणांसाठी नमुना कोडसह.

  • SWC रजिस्ट्री (opens in a new tab) - कॉमन वीकनेस एन्यूमरेशन (CWE) आयटमची क्युरेट केलेली सूची जी Ethereum स्मार्ट कॉन्ट्रॅक्ट्सना लागू होते.

  • Rekt (opens in a new tab) - उच्च-प्रोफाइल क्रिप्टो हॅक आणि शोषणांचे नियमितपणे अद्यतनित केलेले प्रकाशन, तपशीलवार पोस्ट-मॉर्टम अहवालांसह.

स्मार्ट कॉन्ट्रॅक्ट सुरक्षा शिकण्यासाठी आव्हाने

  • Awesome BlockSec CTF (opens in a new tab) - ब्लॉकचेन सुरक्षा वॉरगेम्स, आव्हाने आणि कॅप्चर द फ्लॅग (opens in a new tab) स्पर्धा आणि सोल्यूशन राइटअप्सची क्युरेट केलेली सूची.

  • Damn Vulnerable DeFi (opens in a new tab) - DeFi स्मार्ट कॉन्ट्रॅक्ट्सची आक्षेपार्ह सुरक्षा शिकण्यासाठी आणि बग-हंटिंग आणि सुरक्षा ऑडिटिंगमध्ये कौशल्ये तयार करण्यासाठी वॉरगेम.

  • Ethernaut (opens in a new tab) - वेब3/सॉलिडिटी-आधारित वॉरगेम जिथे प्रत्येक स्तर एक स्मार्ट कॉन्ट्रॅक्ट आहे ज्याला 'हॅक' करणे आवश्यक आहे.

  • HackenProof x HackTheBox (opens in a new tab) - एका काल्पनिक साहसात सेट केलेले स्मार्ट कॉन्ट्रॅक्ट हॅकिंग आव्हान. आव्हान यशस्वीरित्या पूर्ण केल्यावर खाजगी बग बाउंटी प्रोग्राममध्ये प्रवेश देखील मिळतो.

स्मार्ट कॉन्ट्रॅक्ट्स सुरक्षित करण्यासाठी सर्वोत्तम पद्धती

स्मार्ट कॉन्ट्रॅक्ट सुरक्षेवरील ट्युटोरियल्स

हा लेख उपयुक्त होता का?