स्मार्ट अनुबंधों का परीक्षण वास्तव में महत्वपूर्ण है। क्यों? स्मार्ट अनुबंध आम तौर पर उत्पादन, सार्वजनिक , हैकर्स के लक्ष्य में अपरिवर्तनीय होते हैं, और अक्सर महत्वपूर्ण वित्तीय प्रभाव शामिल होते हैं। लघुकथा? स्मार्ट अनुबंधों के साथ, आप पंगा नहीं लेना चाहते हैं। आपको बहुत परीक्षण करने, अक्सर परीक्षण करने और पूरी तरह से परीक्षण करने की आवश्यकता है। स्मार्ट कॉन्ट्रैक्ट टेस्टिंग में सभी सामान्य संदिग्ध शामिल हैं- यूनिट टेस्टिंग, इंटीग्रेशन टेस्टिंग, ऑटोमेटेड टेस्टिंग- लेकिन यह भी अत्यधिक अनुशंसित है कि यह आपके कोड को यादृच्छिक इनपुट के एक समूह के साथ बमबारी करने का एक तरीका है, यह देखने के लिए कि क्या होता है।
आइए एक नज़र डालते हैं कि परीक्षण विधि के रूप में फ़ज़िंग वास्तव में क्या है और आप कॉन्सेनस डिलिजेंस फ़ज़िंग जैसे टूल का उपयोग करके इसे अपने सॉफ़्टवेयर परीक्षण वर्कफ़्लो में आसानी से कैसे शामिल कर सकते हैं। यह कैसे किया जाता है यह देखने के लिए हम डेफी स्मार्ट संपर्क के उदाहरण का उपयोग करके एक ट्यूटोरियल के माध्यम से चलेंगे।
फ़ज़्ज़िंग टेस्टिंग (या फ़ज़्ज़ टेस्टिंग) में अनपेक्षित व्यवहार पैदा करने और कमजोरियों का पता लगाने के प्रयास में एक स्मार्ट अनुबंध के विरुद्ध लाखों अमान्य, अप्रत्याशित और (अर्ध) यादृच्छिक डेटा भेजना शामिल है। यह किनारे के मामलों और परिदृश्यों का परीक्षण करने का एक तेज़, कुशल, क्रूर-बल तरीका है जिसके बारे में आप सोच भी नहीं सकते। यह आपके अन्य परीक्षण प्रवाहों और आपके ऑडिट का पूरक है।
पारंपरिक पूर्ण-स्टैक विकास में फ़ज़िंग कुछ समय के लिए रहा है, लेकिन यहाँ उपकरणों का एक नया वर्ग है जो वेब 3 में स्मार्ट अनुबंध परीक्षण के लिए फ़ज़िंग लागू कर सकता है। कुछ फ़ज़िंग टूल में ओपन सोर्स इकिडना और मिथएक्स शामिल हैं।
हालांकि, इस लेख में, मैं Diligence Fuzzing में एक गहरा गोता लगाऊंगा, जो फ़ज़िंग को एक सेवा के रूप में पेश करता है - फ़ज़ करने का एक बहुत अच्छा और आसान तरीका।
परिश्रम फ़ज़िंग का उपयोग करने के लिए, आप स्क्रिबल का उपयोग करके अपने स्मार्ट अनुबंधों की व्याख्या करते हैं। मूल रूप से, आप फ़ज़र को यह बताने के लिए अपने कोड में स्क्रिबल एनोटेशन का उपयोग करते हैं कि उस फ़ंक्शन के लिए किस प्रकार के आउटपुट की अपेक्षा की जाए।
ऐसा कुछ दिखता है:
/// #invariant {:msg "balances are in sync"} unchecked_sum(_balances) == _totalSupply;
आप फ़ज़र को एक वेब UI से कॉल करते हैं जहाँ आप स्मार्ट कॉन्ट्रैक्ट कोड सबमिट करते हैं। आप रन हिट करते हैं, और लगभग 10 मिनट बाद, आपको मिली समस्याओं, समस्याओं का स्थान, कवरेज %, और बहुत कुछ के साथ एक रिपोर्ट प्राप्त होती है।
कुछ किनारे के मामलों की जांच करने का यह एक आसान और शक्तिशाली तरीका है।
मान लीजिए कि हमारे पास एक नया डेफी प्रोटोकॉल और संबंधित टोकन है जिसे हम लॉन्च करना चाहते हैं। डेफी अत्याधुनिक वित्त है, लिखने में मजेदार है, और यह महत्वपूर्ण है कि हमारे पास कोई बग नहीं है। डेफी स्मार्ट कॉन्ट्रैक्ट्स में अक्सर यूजर फंड में लाखों (या अधिक) शामिल होते हैं। इसलिए हम यह सुनिश्चित करना चाहते हैं कि हमारे स्मार्ट अनुबंधों का यथासंभव परीक्षण (और ऑडिट) किया जाए।
महत्वपूर्ण नोट: इस कोड में जानबूझ कर भेद्यताएं हैं! ऐसा इसलिए है ताकि हम दिखा सकें कि फ़ज़िंग इन गलतियों को कैसे पकड़ सकता है। कृपया किसी भी चीज़ के लिए वास्तव में इस कोड का उपयोग न करें।
आएँ शुरू करें।
सबसे पहले, हमें अपने परिश्रम खाते की आवश्यकता है। परिश्रम पर साइन अप करें। चीजों को आजमाने के लिए आपको मुफ्त में 10 घंटे की फ़ज़िंग मिलती है।
शीर्ष दाईं ओर अपने खाते के नाम पर क्लिक करें, "नई एपीआई कुंजी बनाएं" पर क्लिक करें और इसे एक नाम दें। यह एपीआई कुंजी हमें FaaS से जुड़ने की अनुमति देती है।
निम्नलिखित रिपॉजिटरी को क्लोन करें:
https://github.com/ConsenSys/scribble-exercise-1.git
कमांड लाइन से, रिपॉजिटरी फोल्डर में नेविगेट करें, जो अब आपका प्रोजेक्ट रूट फोल्डर होगा। यदि आपकी मशीन के लिए आवश्यक हो, तो Python venv को सक्रिय करें। फिर, अपनी परियोजना निर्भरताएँ स्थापित करने के लिए निम्नलिखित कमांड चलाएँ:
$ npm i -g eth-scribble ganache truffle $ pip3 install diligence-fuzzing
कुंजी के मान के लिए अपनी Diligence खाता API कुंजी का उपयोग करने के लिए .fuzz.yml
फ़ाइल संपादित करें।
आपकी परिणामी फ़ाइल इस तरह दिखनी चाहिए:
.fuzz.yml fuzz: # Tell the CLI where to find the compiled contracts and compilation artifacts build_directory: build/contracts ... campaign_name_prefix: "ERC20 campaign" # Point to your ganache node which holds the seed rpc_url: "http://localhost:8545" key: "DILIGENCE API KEY GOES HERE" ...
आइए अब हमारे स्मार्ट कॉन्ट्रैक्ट को contracts/vulnerableERC20.sol
पर देखें। यहां हमारे नए डेफी प्रोटोकॉल के लिए एक कमजोर टोकन (जैसा कि इसका नाम है!) है। हमें स्पष्ट रूप से इसका यथासंभव परीक्षण करने की आवश्यकता है। तो चलिए स्क्रिबल का उपयोग करके एक चेक जोड़ते हैं कि फ़ज़र उम्मीद से पकड़ लेगा।
अनुबंध परिभाषा के ऊपर, जोड़ें:
/// #invariant "balances are in sync" unchecked_sum(_balances) == _totalSupply;
और स्थानांतरण समारोह के ऊपर, जोड़ें:
/// #if_succeeds msg.sender != _to ==> _balances[_to] == old(_balances[_to]) + _value; /// #if_succeeds msg.sender != _to ==> _balances[msg.sender] == old(_balances[msg.sender]) - _value; /// #if_succeeds msg.sender == _to ==> _balances[msg.sender] == old(_balances[_to]); /// #if_succeeds old(_balances[msg.sender]) >= _value;
तो अब देखते हैं कि फ़ज़िंग टेस्टर कुछ पकड़ पाएगा या नहीं। परीक्षक को यह समझने में मदद करने के लिए अनुबंध में जोड़े गए एनोटेशन पर ध्यान दें कि हम क्या होने की उम्मीद करते हैं। और ध्यान दें कि कॉन्फ़िगरेशन में परीक्षक अधिकतम 10 मिनट तक चलने के लिए तैयार है, इसलिए यह सब कुछ नहीं पकड़ सकता है।
अब हम परीक्षण के लिए तैयार हैं! प्रोजेक्ट रूट फोल्डर से, मेक फाइल को कॉल करने के लिए make fuzz
रन करें, जो कंपाइल, बिल्ड और सब कुछ FaaS को भेज देगा।
अपने डैशबोर्ड पर वापस जाएं, और आपको नीचे जैसा कुछ दिखाई देना चाहिए। अभियान शुरू होने के लिए कुछ सेकंड प्रतीक्षा करें।
इसके जनरेट होने के बाद, आपको नीचे दिखाए गए जैसा कुछ दिखाई देना चाहिए:
हम कोड कवरेज भी देखते हैं!
और कुछ ही मिनटों के बाद, हम एक विफलता देखते हैं!
संपत्तियों पर क्लिक करने पर, हमें कोई भी उल्लंघन दिखाई देता है। और हाँ हमारे पास एक बग है! हमारी संभावित कोड कमजोरियों का विवरण देखने के लिए लाइन स्थान पर क्लिक करें।
हम वहीं रुकेंगे, लेकिन अगर आप फ़ज़र को चलने देते हैं, तो यह और खोज सकता है!
फ़ज़िंग आपके सॉफ़्टवेयर विकास और परीक्षण प्रक्रिया में एक महत्वपूर्ण चरण हो सकता है। यह आपको संभावित कमजोरियों की पहचान करने में मदद करता है जो अन्यथा किसी का ध्यान नहीं जा सकता। इसका उपयोग करके, आप सामान्य नुकसानों और चुनौतियों को पहचानने और समझने लगते हैं। Diligence Fuzzing जैसे टूल का लाभ उठाएं, बेहतर स्मार्ट अनुबंध लिखें और एक बेहतर डेवलपर बनें!