स्मार्ट कॉन्ट्रॅक्ट्सची चाचणी घेण्यासाठी Echidna चा वापर कसा करावा
इन्स्टॉलेशन
Echidna डॉकरद्वारे किंवा प्री-कंपाइल बायनरी वापरून इन्स्टॉल केले जाऊ शकते.
डॉकरद्वारे Echidna
docker pull trailofbits/eth-security-toolboxdocker run -it -v "$PWD":/home/training trailofbits/eth-security-toolboxशेवटचा कमांड तुमच्या सध्याच्या डिरेक्टरीमध्ये ऍक्सेस असलेल्या docker मध्ये eth-security-toolbox चालवतो. तुम्ही तुमच्या होस्टमधून फाइल्स बदलू शकता, आणि docker मधून फाइल्सवर टूल्स चालवू शकता
डॉकरमध्ये, चालवा :
solc-select 0.5.11cd /home/trainingबायनरी
https://github.com/crytic/echidna/releases/tag/v1.4.0.0 (opens in a new tab)
प्रॉपर्टी-आधारित फझिंगची ओळख
Echidna एक प्रॉपर्टी-आधारित फझर आहे, ज्याचे वर्णन आम्ही आमच्या मागील ब्लॉगपोस्टमध्ये केले आहे (1 (opens in a new tab), 2 (opens in a new tab), 3 (opens in a new tab)).
फझिंग
Fuzzing (opens in a new tab) हे सुरक्षा समुदायामध्ये एक सुप्रसिद्ध तंत्र आहे. यात प्रोग्राममधील बग शोधण्यासाठी कमी-अधिक प्रमाणात यादृच्छिक इनपुट तयार करणे समाविष्ट आहे. पारंपारिक सॉफ्टवेअरसाठी फझर्स (जसे की AFL (opens in a new tab) किंवा LibFuzzer (opens in a new tab)) बग शोधण्यासाठी कार्यक्षम साधने म्हणून ओळखले जातात.
केवळ यादृच्छिक इनपुट तयार करण्यापलीकडे, चांगले इनपुट तयार करण्यासाठी अनेक तंत्रे आणि धोरणे आहेत, ज्यात खालील गोष्टींचा समावेश आहे:
- प्रत्येक अंमलबजावणीतून अभिप्राय मिळवा आणि त्याचा वापर करून पिढीला मार्गदर्शन करा. उदाहरणार्थ, जर नवीन तयार केलेल्या इनपुटमुळे नवीन मार्ग सापडला, तर त्याच्या जवळ नवीन इनपुट तयार करणे अर्थपूर्ण ठरू शकते.
- रचनात्मक मर्यादांचा आदर करून इनपुट तयार करणे. उदाहरणार्थ, जर तुमच्या इनपुटमध्ये चेकसमसह हेडर असेल, तर फझरला चेकसम प्रमाणित करणारे इनपुट तयार करू देणे अर्थपूर्ण ठरेल.
- नवीन इनपुट तयार करण्यासाठी ज्ञात इनपुट वापरणे: जर तुमच्याकडे वैध इनपुटच्या मोठ्या डेटासेटमध्ये प्रवेश असेल, तर तुमचा फझर सुरवातीपासून त्याची निर्मिती सुरू करण्याऐवजी त्यातून नवीन इनपुट तयार करू शकतो. यांना सहसा seeds म्हटले जाते.
प्रॉपर्टी-आधारित फझिंग
Echidna फझरच्या एका विशिष्ट कुटुंबाशी संबंधित आहे: QuickCheck (opens in a new tab) द्वारे मोठ्या प्रमाणावर प्रेरित प्रॉपर्टी-आधारित फझिंग. क्रॅश शोधण्याचा प्रयत्न करणाऱ्या क्लासिक फझरच्या विपरीत, Echidna वापरकर्ता-परिभाषित इनव्हेरियंट्स तोडण्याचा प्रयत्न करेल.
स्मार्ट कॉन्ट्रॅक्ट्समध्ये, इनव्हेरियंट्स हे Solidity फंक्शन्स असतात, जे कॉन्ट्रॅक्ट पोहोचू शकणाऱ्या कोणत्याही चुकीच्या किंवा अवैध स्थितीचे प्रतिनिधित्व करू शकतात, ज्यात खालील गोष्टींचा समावेश आहे:
- चुकीचे प्रवेश नियंत्रण: आक्रमणकर्ता कॉन्ट्रॅक्टचा मालक बनला.
- चुकीचे स्टेट मशीन: कॉन्ट्रॅक्ट थांबवलेले असताना टोकन हस्तांतरित केले जाऊ शकतात.
- चुकीचे अंकगणित: वापरकर्ता त्याचे शिल्लक कमी करू शकतो आणि अमर्यादित विनामूल्य टोकन मिळवू शकतो.
Echidna सह प्रॉपर्टीची चाचणी करणे
आम्ही Echidna सह स्मार्ट कॉन्ट्रॅक्टची चाचणी कशी करायची ते पाहू. लक्ष्य खालील स्मार्ट कॉन्ट्रॅक्ट आहे token.sol (opens in a new tab):
1contract Token{2 mapping(address => uint) public balances;3 function airdrop() public{4 balances[msg.sender] = 1000;5 }6 function consume() public{7 require(balances[msg.sender]>0);8 balances[msg.sender] -= 1;9 }10 function backdoor() public{11 balances[msg.sender] += 1;12 }13}आम्ही असे गृहीत धरू की या टोकनमध्ये खालील गुणधर्म असणे आवश्यक आहे:
- कोणाकडेही जास्तीत जास्त 1000 टोकन असू शकतात
- टोकन हस्तांतरित केले जाऊ शकत नाही (ते ERC20 टोकन नाही)
एक प्रॉपर्टी लिहा
Echidna प्रॉपर्टीज या Solidity फंक्शन्स आहेत. एका प्रॉपर्टीमध्ये हे असणे आवश्यक आहे:
- कोणतेही आर्ग्युमेंट नसावे
- यशस्वी झाल्यास
trueपरत करा - त्याचे नाव
echidnaने सुरू झाले पाहिजे
Echidna हे करेल:
- प्रॉपर्टीची चाचणी घेण्यासाठी आपोआप अनियंत्रित व्यवहार तयार करा.
- एखाद्या प्रॉपर्टीला
falseपरत करण्यास किंवा त्रुटी निर्माण करण्यास कारणीभूत ठरलेल्या कोणत्याही व्यवहारांची तक्रार करा. - प्रॉपर्टी कॉल करताना साईड-इफेक्ट टाळा (म्हणजे, जर प्रॉपर्टी स्टेट व्हेरिएबल बदलत असेल, तर चाचणीनंतर ते टाकून दिले जाते)
खालील प्रॉपर्टी तपासते की कॉलरकडे 1000 पेक्षा जास्त टोकन नाहीत:
1function echidna_balance_under_1000() public view returns(bool){2 return balances[msg.sender] <= 1000;3}तुमच्या कॉन्ट्रॅक्टला तुमच्या प्रॉपर्टीजपासून वेगळे करण्यासाठी इनहेरिटन्स वापरा:
1contract TestToken is Token{2 function echidna_balance_under_1000() public view returns(bool){3 return balances[msg.sender] <= 1000;4 }5 }token.sol (opens in a new tab) प्रॉपर्टी लागू करते आणि टोकनमधून इनहेरिट करते.
एक कॉन्ट्रॅक्ट सुरू करा
Echidna ला आर्ग्युमेंटशिवाय constructor ची आवश्यकता आहे. जर तुमच्या कॉन्ट्रॅक्टला विशिष्ट इनिशिएलायझेशनची आवश्यकता असेल, तर तुम्हाला ते कन्स्ट्रक्टरमध्ये करावे लागेल.
Echidna मध्ये काही विशिष्ट ॲड्रेसेस आहेत:
0x00a329c0648769A73afAc7F9381E08FB43dBEA72जे कन्स्ट्रक्टरला कॉल करते.0x10000,0x20000, आणि0x00a329C0648769a73afAC7F9381e08fb43DBEA70जे यादृच्छिकपणे इतर फंक्शन्सना कॉल करतात.
आमच्या सध्याच्या उदाहरणात आम्हाला कोणत्याही विशिष्ट इनिशिएलायझेशनची आवश्यकता नाही, परिणामी आमचा कन्स्ट्रक्टर रिकामा आहे.
Echidna चालवा
Echidna यासह लॉन्च केले जाते:
echidna-test contract.solजर contract.sol मध्ये अनेक कॉन्ट्रॅक्ट्स असतील, तर तुम्ही लक्ष्य निर्दिष्ट करू शकता:
echidna-test contract.sol --contract MyContractसारांश: एका प्रॉपर्टीची चाचणी करणे
खालील आमच्या उदाहरणावरील Echidna च्या रनचा सारांश देते:
1contract TestToken is Token{2 constructor() public {}3 function echidna_balance_under_1000() public view returns(bool){4 return balances[msg.sender] <= 1000;5 }6 }echidna-test testtoken.sol --contract TestToken...
echidna_balance_under_1000: failed!💥 Call sequence, shrinking (1205/5000): airdrop() backdoor()
...Echidna ला आढळले की जर backdoor कॉल केला तर प्रॉपर्टीचे उल्लंघन होते.
फझिंग मोहिमेदरम्यान कॉल करण्यासाठी फंक्शन्स फिल्टर करणे
आम्ही फझ करण्यासाठी फंक्शन्स कसे फिल्टर करायचे ते पाहू. लक्ष्य खालील स्मार्ट कॉन्ट्रॅक्ट आहे:
1contract C {2 bool state1 = false;3 bool state2 = false;4 bool state3 = false;5 bool state4 = false;6
7 function f(uint x) public {8 require(x == 12);9 state1 = true;10 }11
12 function g(uint x) public {13 require(state1);14 require(x == 8);15 state2 = true;16 }17
18 function h(uint x) public {19 require(state2);20 require(x == 42);21 state3 = true;22 }23
24 function i() public {25 require(state3);26 state4 = true;27 }28
29 function reset1() public {30 state1 = false;31 state2 = false;32 state3 = false;33 return;34 }35
36 function reset2() public {37 state1 = false;38 state2 = false;39 state3 = false;40 return;41 }42
43 function echidna_state4() public returns (bool) {44 return (!state4);45 }46}हे लहान उदाहरण Echidna ला स्टेट व्हेरिएबल बदलण्यासाठी व्यवहारांचा एक विशिष्ट क्रम शोधण्यास भाग पाडते. हे फझरसाठी कठीण आहे (यासाठी Manticore (opens in a new tab) सारखे सिम्बॉलिक एक्झिक्युशन टूल वापरण्याची शिफारस केली जाते). हे तपासण्यासाठी आपण Echidna चालवू शकतो:
echidna-test multi.sol...echidna_state4: passed! 🎉Seed: -3684648582249875403फिल्टरिंग फंक्शन्स
Echidna ला या कॉन्ट्रॅक्टची चाचणी घेण्यासाठी योग्य क्रम शोधण्यात अडचण येत आहे कारण दोन रीसेट फंक्शन्स (reset1 आणि reset2) सर्व स्टेट व्हेरिएबल्स false वर सेट करतील.
तथापि, आपण एक विशेष Echidna वैशिष्ट्य वापरू शकतो, एकतर रीसेट फंक्शनला ब्लॅकलिस्ट करण्यासाठी किंवा फक्त f, g,
h आणि i फंक्शन्सना व्हाइटलिस्ट करण्यासाठी.
फंक्शन्स ब्लॅकलिस्ट करण्यासाठी, आम्ही ही कॉन्फिगरेशन फाइल वापरू शकतो:
1filterBlacklist: true2filterFunctions: ["reset1", "reset2"]फंक्शन्स फिल्टर करण्याचा दुसरा दृष्टिकोन म्हणजे व्हाइटलिस्ट केलेल्या फंक्शन्सची यादी करणे. ते करण्यासाठी, आम्ही ही कॉन्फिगरेशन फाइल वापरू शकतो:
1filterBlacklist: false2filterFunctions: ["f", "g", "h", "i"]filterBlacklistहे डीफॉल्टनुसारtrueअसते.- फिल्टरिंग केवळ नावाने केले जाईल (पॅरामीटर्सशिवाय). जर तुमच्याकडे
f()आणिf(uint256)असेल, तर"f"फिल्टर दोन्ही फंक्शन्सना जुळेल.
Echidna चालवा
blacklist.yaml कॉन्फिगरेशन फाइलसह Echidna चालवण्यासाठी:
echidna-test multi.sol --config blacklist.yaml...echidna_state4: failed!💥 Call sequence: f(12) g(8) h(42) i()Echidna जवळजवळ त्वरित प्रॉपर्टीला खोटे ठरवण्यासाठी व्यवहारांचा क्रम शोधेल.
सारांश: फिल्टरिंग फंक्शन्स
Echidna फझिंग मोहिमेदरम्यान कॉल करण्यासाठी फंक्शन्स ब्लॅकलिस्ट किंवा व्हाइटलिस्ट करू शकते:
1filterBlacklist: true2filterFunctions: ["f1", "f2", "f3"]echidna-test contract.sol --config config.yaml...filterBlacklist बुलियनच्या मूल्यांनुसार Echidna f1, f2 आणि f3 ला ब्लॅकलिस्ट करून किंवा फक्त त्यांना कॉल करून फझिंग मोहीम सुरू करते.
Echidna सह Solidity's assert ची चाचणी कशी करावी
या लहान ट्युटोरियलमध्ये, आम्ही कॉन्ट्रॅक्ट्समध्ये अॅसर्शन चेकिंगची चाचणी घेण्यासाठी Echidna चा वापर कसा करायचा हे दाखवणार आहोत. समजा आपल्याकडे यासारखा एक कॉन्ट्रॅक्ट आहे:
1contract Incrementor {2 uint private counter = 2**200;3
4 function inc(uint val) public returns (uint){5 uint tmp = counter;6 counter += val;7 // tmp <= counter8 return (counter - tmp);9 }10}एक अॅसर्शन लिहा
त्यातील फरक परत केल्यानंतर tmp हे counter पेक्षा कमी किंवा समान आहे याची आम्ही खात्री करू इच्छितो. आपण Echidna
प्रॉपर्टी लिहू शकतो, पण आपल्याला tmp मूल्य कुठेतरी साठवावे लागेल. त्याऐवजी, आपण यासारखे अॅसर्शन वापरू शकतो:
1contract Incrementor {2 uint private counter = 2**200;3
4 function inc(uint val) public returns (uint){5 uint tmp = counter;6 counter += val;7 assert (tmp <= counter);8 return (counter - tmp);9 }10}Echidna चालवा
अॅसर्शन अयशस्वी चाचणी सक्षम करण्यासाठी, एक Echidna कॉन्फिगरेशन फाइल (opens in a new tab) config.yaml तयार करा:
1checkAsserts: trueजेव्हा आपण Echidna मध्ये हा कॉन्ट्रॅक्ट चालवतो, तेव्हा आपल्याला अपेक्षित परिणाम मिळतात:
echidna-test assert.sol --config config.yamlAnalyzing contract: assert.sol:Incrementorassertion in inc: failed!💥 Call sequence, shrinking (2596/5000): inc(21711016731996786641919559689128982722488122124807605757398297001483711807488) inc(7237005577332262213973186563042994240829374041602535252466099000494570602496) inc(86844066927987146567678238756515930889952488499230423029593188005934847229952)
Seed: 1806480648350826486तुम्ही बघू शकता, Echidna inc फंक्शनमध्ये काही अॅसर्शन अयशस्वी झाल्याची तक्रार करते. प्रत्येक फंक्शनमध्ये एकापेक्षा जास्त अॅसर्शन जोडणे शक्य आहे, परंतु कोणते अॅसर्शन अयशस्वी झाले हे Echidna सांगू शकत नाही.
अॅसर्शन्स केव्हा आणि कसे वापरावे
अॅसर्शन्स स्पष्ट प्रॉपर्टीजसाठी पर्याय म्हणून वापरले जाऊ शकतात, विशेषतः जर तपासण्याची परिस्थिती थेट काही ऑपरेशन f च्या योग्य वापराशी संबंधित असेल. काही कोडनंतर अॅसर्शन्स जोडल्याने हे सुनिश्चित होईल की तपासणी त्याच्या अंमलबजावणीनंतर लगेच होईल:
1function f(..) public {2 // काही जटिल कोड3 ...4 assert (condition);5 ...6}7
याउलट, स्पष्ट Echidna प्रॉपर्टी वापरल्याने व्यवहार यादृच्छिकपणे अंमलात येतील आणि ते केव्हा तपासले जाईल हे लागू करण्याचा कोणताही सोपा मार्ग नाही. हा वर्कअराउंड करणे अजूनही शक्य आहे:
1function echidna_assert_after_f() public returns (bool) {2 f(..);3 return(condition);4}तथापि, काही समस्या आहेत:
- जर
fहेinternalकिंवाexternalम्हणून घोषित केले असेल तर ते अयशस्वी होते. fला कॉल करण्यासाठी कोणते आर्ग्युमेंट्स वापरावे हे अस्पष्ट आहे.- जर
fरिव्हर्ट झाले, तर प्रॉपर्टी अयशस्वी होईल.
सर्वसाधारणपणे, आम्ही अॅसर्शन्स कसे वापरावे यावर जॉन रेगेहर यांच्या शिफारसीचे (opens in a new tab) पालन करण्याची शिफारस करतो:
- अॅसर्शन तपासणी दरम्यान कोणताही साईड इफेक्ट जबरदस्तीने करू नका. उदाहरणार्थ:
assert(ChangeStateAndReturn() == 1) - स्पष्ट विधाने निश्चित करू नका. उदाहरणार्थ,
assert(var >= 0)जेथेvarहेuintम्हणून घोषित केले आहे.
शेवटी, कृपया assert ऐवजी require वापरू नका, कारण Echidna ते शोधू शकणार नाही (परंतु कॉन्ट्रॅक्ट तरीही रिव्हर्ट होईल).
सारांश: अॅसर्शन चेकिंग
खालील आमच्या उदाहरणावरील Echidna च्या रनचा सारांश देते:
1contract Incrementor {2 uint private counter = 2**200;3
4 function inc(uint val) public returns (uint){5 uint tmp = counter;6 counter += val;7 assert (tmp <= counter);8 return (counter - tmp);9 }10}echidna-test assert.sol --config config.yamlAnalyzing contract: assert.sol:Incrementorassertion in inc: failed!💥 Call sequence, shrinking (2596/5000): inc(21711016731996786641919559689128982722488122124807605757398297001483711807488) inc(7237005577332262213973186563042994240829374041602535252466099000494570602496) inc(86844066927987146567678238756515930889952488499230423029593188005934847229952)
Seed: 1806480648350826486Echidna ला आढळले की inc मधील अॅसर्शन अयशस्वी होऊ शकते जर हे फंक्शन मोठ्या आर्ग्युमेंट्ससह अनेक वेळा कॉल केले गेले.
Echidna कॉर्पस गोळा करणे आणि त्यात बदल करणे
आम्ही Echidna सह व्यवहारांचा कॉर्पस कसा गोळा करायचा आणि वापरायचा ते पाहू. लक्ष्य खालील स्मार्ट कॉन्ट्रॅक्ट आहे magic.sol (opens in a new tab):
1contract C {2 bool value_found = false;3 function magic(uint magic_1, uint magic_2, uint magic_3, uint magic_4) public {4 require(magic_1 == 42);5 require(magic_2 == 129);6 require(magic_3 == magic_4+333);7 value_found = true;8 return;9 }10
11 function echidna_magic_values() public returns (bool) {12 return !value_found;13 }14
15}हे लहान उदाहरण Echidna ला स्टेट व्हेरिएबल बदलण्यासाठी काही विशिष्ट मूल्ये शोधण्यास भाग पाडते. हे फझरसाठी कठीण आहे (यासाठी Manticore (opens in a new tab) सारखे सिम्बॉलिक एक्झिक्युशन टूल वापरण्याची शिफारस केली जाते). हे तपासण्यासाठी आपण Echidna चालवू शकतो:
echidna-test magic.sol...
echidna_magic_values: passed! 🎉
Seed: 2221503356319272685तथापि, ही फझिंग मोहीम चालवताना कॉर्पस गोळा करण्यासाठी आम्ही अजूनही Echidna वापरू शकतो.
कॉर्पस गोळा करणे
कॉर्पस संकलन सक्षम करण्यासाठी, एक कॉर्पस डिरेक्टरी तयार करा:
mkdir corpus-magicआणि एक Echidna कॉन्फिगरेशन फाइल (opens in a new tab) config.yaml:
1coverage: true2corpusDir: "corpus-magic"आता आपण आपले टूल चालवू शकतो आणि गोळा केलेला कॉर्पस तपासू शकतो:
echidna-test magic.sol --config config.yamlEchidna अजूनही योग्य मॅजिक व्हॅल्यूज शोधू शकत नाही, परंतु आपण त्याने गोळा केलेल्या कॉर्पसवर एक नजर टाकू शकतो. उदाहरणार्थ, यापैकी एक फाइल होती:
1[2 {3 "_gas'": "0xffffffff",4 "_delay": ["0x13647", "0xccf6"],5 "_src": "00a329c0648769a73afac7f9381e08fb43dbea70",6 "_dst": "00a329c0648769a73afac7f9381e08fb43dbea72",7 "_value": "0x0",8 "_call": {9 "tag": "SolCall",10 "contents": [11 "magic",12 [13 {14 "contents": [15 256,16 "93723985220345906694500679277863898678726808528711107336895287282192244575836"17 ],18 "tag": "AbiUInt"19 },20 {21 "contents": [256, "334"],22 "tag": "AbiUInt"23 },24 {25 "contents": [26 256,27 "68093943901352437066264791224433559271778087297543421781073458233697135179558"28 ],29 "tag": "AbiUInt"30 },31 {32 "tag": "AbiUInt",33 "contents": [256, "332"]34 }35 ]36 ]37 },38 "_gasprice'": "0xa904461f1"39 }40]स्पष्टपणे, हे इनपुट आमच्या प्रॉपर्टीमध्ये अपयश आणणार नाही. तथापि, पुढील चरणात, आम्ही त्यासाठी त्यात कसे बदल करायचे ते पाहू.
कॉर्पस सीडिंग करणे
magic फंक्शन हाताळण्यासाठी Echidna ला काही मदतीची गरज आहे. आम्ही इनपुट कॉपी करणार आहोत आणि त्यासाठी योग्य
पॅरामीटर्स वापरण्यासाठी त्यात बदल करणार आहोत:
cp corpus/2712688662897926208.txt corpus/new.txtआम्ही magic(42,129,333,0) ला कॉल करण्यासाठी new.txt मध्ये बदल करू. आता, आपण Echidna पुन्हा चालवू शकतो:
echidna-test magic.sol --config config.yaml...echidna_magic_values: failed!💥 Call sequence: magic(42,129,333,0)
Unique instructions: 142Unique codehashes: 1Seed: -7293830866560616537
यावेळी, त्याला आढळले की प्रॉपर्टीचे त्वरित उल्लंघन झाले आहे.
उच्च गॅस वापरासह व्यवहार शोधणे
आम्ही Echidna सह उच्च गॅस वापरासह व्यवहार कसे शोधायचे ते पाहू. लक्ष्य खालील स्मार्ट कॉन्ट्रॅक्ट आहे:
1contract C {2 uint state;3
4 function expensive(uint8 times) internal {5 for(uint8 i=0; i < times; i++)6 state = state + i;7 }8
9 function f(uint x, uint y, uint8 times) public {10 if (x == 42 && y == 123)11 expensive(times);12 else13 state = 0;14 }15
16 function echidna_test() public returns (bool) {17 return true;18 }19
20}येथे expensive मध्ये मोठा गॅस वापर असू शकतो.
सध्या, Echidna ला नेहमी चाचणीसाठी एक प्रॉपर्टीची आवश्यकता असते: येथे echidna_test नेहमी true परत करते.
हे तपासण्यासाठी आपण Echidna चालवू शकतो:
1echidna-test gas.sol2...3echidna_test: passed! 🎉4
5Seed: 2320549945714142710गॅस वापर मोजणे
Echidna सह गॅस वापर सक्षम करण्यासाठी, एक कॉन्फिगरेशन फाइल config.yaml तयार करा:
1estimateGas: trueया उदाहरणात, आम्ही परिणाम समजण्यास सोपे करण्यासाठी व्यवहार क्रमाचा आकार देखील कमी करू:
1seqLen: 22estimateGas: trueEchidna चालवा
एकदा आम्ही कॉन्फिगरेशन फाइल तयार केल्यावर, आम्ही Echidna याप्रमाणे चालवू शकतो:
echidna-test gas.sol --config config.yaml...echidna_test: passed! 🎉
f used a maximum of 1333608 gas Call sequence: f(42,123,249) Gas price: 0x10d5733f0a Time delay: 0x495e5 Block delay: 0x88b2
Unique instructions: 157Unique codehashes: 1Seed: -325611019680165325
- दाखवलेला गॅस हा HEVM (opens in a new tab) द्वारे प्रदान केलेला एक अंदाज आहे.
गॅस-कमी करणारे कॉल्स फिल्टर करणे
वरील फझिंग मोहिमेदरम्यान कॉल करण्यासाठी फंक्शन्स फिल्टर करणे यावरील ट्युटोरियल तुमच्या चाचणीमधून काही फंक्शन्स कसे काढायचे हे दाखवते.
अचूक गॅस अंदाज मिळवण्यासाठी हे महत्त्वपूर्ण असू शकते.
खालील उदाहरण विचारात घ्या:
1contract C {2 address [] addrs;3 function push(address a) public {4 addrs.push(a);5 }6 function pop() public {7 addrs.pop();8 }9 function clear() public{10 addrs.length = 0;11 }12 function check() public{13 for(uint256 i = 0; i < addrs.length; i++)14 for(uint256 j = i+1; j < addrs.length; j++)15 if (addrs[i] == addrs[j])16 addrs[j] = address(0x0);17 }18 function echidna_test() public returns (bool) {19 return true;20 }21}जर Echidna सर्व फंक्शन्सना कॉल करू शकत असेल, तर त्याला उच्च गॅस खर्चासह व्यवहार सहज सापडणार नाहीत:
1echidna-test pushpop.sol --config config.yaml2...3pop used a maximum of 10746 gas4...5check used a maximum of 23730 gas6...7clear used a maximum of 35916 gas8...9push used a maximum of 40839 gasकारण खर्च addrs च्या आकारावर अवलंबून असतो आणि यादृच्छिक कॉल्समुळे ॲरे जवळजवळ रिकामा राहतो.
तथापि, pop आणि clear ला ब्लॅकलिस्ट केल्याने आम्हाला बरेच चांगले परिणाम मिळतात:
1filterBlacklist: true2filterFunctions: ["pop", "clear"]1echidna-test pushpop.sol --config config.yaml2...3push used a maximum of 40839 gas4...5check used a maximum of 1484472 gasसारांश: उच्च गॅस वापरासह व्यवहार शोधणे
estimateGas कॉन्फिगरेशन पर्याय वापरून Echidna उच्च गॅस वापरासह व्यवहार शोधू शकते:
1estimateGas: trueechidna-test contract.sol --config config.yaml...एकदा फझिंग मोहीम संपली की, Echidna प्रत्येक फंक्शनसाठी कमाल गॅस वापरासह एक क्रम नोंदवेल.
पृष्ठ अखेरचे अद्यतन: 3 मार्च, 2026