స్మార్ట్ కాంట్రాక్ట్ బగ్స్ను కనుగొనడానికి స్లిథర్ను ఎలా ఉపయోగించాలి
స్లిథర్ను ఎలా ఉపయోగించాలి
స్మార్ట్ కాంట్రాక్ట్లలో బగ్స్ను స్వయంచాలకంగా కనుగొనడానికి స్లిథర్ను ఎలా ఉపయోగించాలో చూపడమే ఈ ట్యుటోరియల్ లక్ష్యం.
- ఇన్స్టాలేషన్
- కమాండ్ లైన్ వినియోగం
- స్టాటిక్ అనాలిసిస్కు పరిచయం: స్టాటిక్ అనాలిసిస్కు సంక్షిప్త పరిచయం
- API: పైథాన్ API వివరణ
సంస్థాపన
స్లిథర్కు పైథాన్ >= 3.6 అవసరం. దీనిని పిప్ ద్వారా లేదా డాకర్ని ఉపయోగించి ఇన్స్టాల్ చేయవచ్చు.
pip ద్వారా స్లిథర్:
pip3 install --user slither-analyzer
డాకర్ ద్వారా స్లిథర్:
docker pull trailofbits/eth-security-toolbox
docker run -it -v "$PWD":/home/trufflecon trailofbits/eth-security-toolbox
చివరి కమాండ్ మీ ప్రస్తుత డైరెక్టరీకి యాక్సెస్ ఉన్న డాకర్లో eth-security-toolboxను రన్ చేస్తుంది. మీరు మీ హోస్ట్ నుండి ఫైల్లను మార్చవచ్చు, మరియు డాకర్ నుండి ఫైల్లపై సాధనాలను అమలు చేయండి
డాకర్ లోపల, రన్ చేయండి:
solc-select 0.5.11
cd /home/trufflecon/
ఒక స్క్రిప్ట్ను అమలు చేయడం
పైథాన్ 3 తో పైథాన్ స్క్రిప్ట్ను అమలు చేయడానికి:
python3 script.py
కమాండ్ లైన్
కమాండ్ లైన్ వర్సెస్ యూజర్-డిఫైన్డ్ స్క్రిప్ట్లు. స్లిథర్ అనేక సాధారణ బగ్లను కనుగొనే ముందే నిర్వచించిన డిటెక్టర్ల సమితితో వస్తుంది. కమాండ్ లైన్ నుండి స్లిథర్ను కాల్ చేయడం వల్ల అన్ని డిటెక్టర్లు రన్ అవుతాయి, స్టాటిక్ అనాలిసిస్ గురించి వివరణాత్మక జ్ఞానం అవసరం లేదు:
slither project_paths
డిటెక్టర్లతో పాటు, స్లిథర్ దాని ప్రింటర్లు (opens in a new tab) మరియు టూల్స్ (opens in a new tab) ద్వారా కోడ్ సమీక్ష సామర్థ్యాలను కలిగి ఉంది.
ప్రైవేట్ డిటెక్టర్లు మరియు GitHub ఇంటిగ్రేషన్కు యాక్సెస్ పొందడానికి crytic.io (opens in a new tab)ని ఉపయోగించండి.
స్టాటిక్ విశ్లేషణ
స్లిథర్ స్టాటిక్ అనాలిసిస్ ఫ్రేమ్వర్క్ యొక్క సామర్థ్యాలు మరియు డిజైన్ బ్లాగ్ పోస్టులలో (1 (opens in a new tab), 2 (opens in a new tab)) మరియు ఒక అకాడెమిక్ పేపర్ (opens in a new tab)లో వివరించబడింది.
స్టాటిక్ విశ్లేషణ వివిధ రకాలుగా ఉంటుంది. clang (opens in a new tab) మరియు gcc (opens in a new tab) వంటి కంపైలర్లు ఈ పరిశోధన పద్ధతులపై ఆధారపడతాయని మీరు బహుశా గ్రహించి ఉంటారు, కానీ ఇది (Infer (opens in a new tab), CodeClimate (opens in a new tab), FindBugs (opens in a new tab) మరియు Frama-C (opens in a new tab) మరియు Polyspace (opens in a new tab) వంటి ఫార్మల్ మెథడ్స్ ఆధారిత టూల్స్కు) కూడా ఆధారం.
మేము ఇక్కడ స్టాటిక్ విశ్లేషణ పద్ధతులు మరియు పరిశోధకులను సమగ్రంగా సమీక్షించము. దానికి బదులుగా, స్లిథర్ ఎలా పనిచేస్తుందో అర్థం చేసుకోవడానికి ఏమి అవసరమో దానిపై మేము దృష్టి పెడతాము, తద్వారా మీరు బగ్లను కనుగొనడానికి మరియు కోడ్ను అర్థం చేసుకోవడానికి దాన్ని మరింత సమర్థవంతంగా ఉపయోగించవచ్చు.
కోడ్ ప్రాతినిధ్యం
ఒకే ఒక ఎగ్జిక్యూషన్ పాత్ గురించి తర్కించే డైనమిక్ అనాలిసిస్కు విరుద్ధంగా, స్టాటిక్ అనాలిసిస్ అన్ని పాత్ల గురించి ఒకేసారి తర్కిస్తుంది. అలా చేయడానికి, ఇది వేరే కోడ్ ప్రాతినిధ్యంపై ఆధారపడుతుంది. అబ్స్ట్రాక్ట్ సింటాక్స్ ట్రీ (AST) మరియు కంట్రోల్ ఫ్లో గ్రాఫ్ (CFG) అనేవి రెండు అత్యంత సాధారణమైనవి.
అబ్స్ట్రాక్ట్ సింటాక్స్ ట్రీలు (AST)
కంపైలర్ కోడ్ను పార్స్ చేసిన ప్రతిసారీ ASTలు ఉపయోగించబడతాయి. స్టాటిక్ విశ్లేషణను నిర్వహించగల అత్యంత ప్రాథమిక నిర్మాణం బహుశా ఇదే.
సంక్షిప్తంగా, AST అనేది ఒక నిర్మాణాత్మక ట్రీ, ఇక్కడ సాధారణంగా, ప్రతి లీఫ్లో ఒక వేరియబుల్ లేదా ఒక కాన్స్టాంట్ ఉంటుంది మరియు అంతర్గత నోడ్స్ ఆపరాండ్లు లేదా కంట్రోల్ ఫ్లో ఆపరేషన్లు. కింది కోడ్ను పరిగణించండి:
function safeAdd(uint a, uint b) pure internal returns(uint){
if(a + b <= a){
revert();
}
return a + b;
}
సంబంధిత AST ఇందులో చూపబడింది:
స్లిథర్ solc ద్వారా ఎగుమతి చేయబడిన ASTని ఉపయోగిస్తుంది.
నిర్మించడానికి సులభమైనప్పటికీ, AST ఒక నెస్ట్ చేయబడిన నిర్మాణం. కొన్నిసార్లు, విశ్లేషించడానికి ఇది చాలా సరళమైనది కాదు. a + b <= a అనే ఎక్స్ప్రెషన్ ద్వారా ఉపయోగించే ఆపరేషన్లను గుర్తించడానికి, మీరు మొదట <= మరియు తర్వాత +ని విశ్లేషించాలి. ఒక సాధారణ పద్ధతి విజిటర్ ప్యాటర్న్ను ఉపయోగించడం, ఇది ట్రీ ద్వారా పునరావృతంగా నావిగేట్ చేస్తుంది. స్లిథర్ ExpressionVisitor (opens in a new tab)లో ఒక జెనరిక్ విజిటర్ను కలిగి ఉంది.
కింది కోడ్ ఒక ఎక్స్ప్రెషన్లో అడిషన్ ఉందో లేదో గుర్తించడానికి ExpressionVisitorని ఉపయోగిస్తుంది:
from slither.visitors.expression.expression import ExpressionVisitor
from slither.core.expressions.binary_operation import BinaryOperationType
class HasAddition(ExpressionVisitor):
def result(self):
return self._result
def _post_binary_operation(self, expression):
if expression.type == BinaryOperationType.ADDITION:
self._result = True
visitor = HasAddition(expression) # expression is the expression to be tested
print(f'The expression {expression} has a addition: {visitor.result()}')
కంట్రోల్ ఫ్లో గ్రాఫ్ (CFG)
రెండవ అత్యంత సాధారణ కోడ్ ప్రాతినిధ్యం కంట్రోల్ ఫ్లో గ్రాఫ్ (CFG). దాని పేరు సూచించినట్లుగా, ఇది అన్ని ఎగ్జిక్యూషన్ పాత్లను బహిర్గతం చేసే గ్రాఫ్-ఆధారిత ప్రాతినిధ్యం. ప్రతి నోడ్ ఒకటి లేదా అంతకంటే ఎక్కువ సూచనలను కలిగి ఉంటుంది. గ్రాఫ్లోని ఎడ్జ్లు కంట్రోల్ ఫ్లో ఆపరేషన్లను (if/then/else, loop, etc) సూచిస్తాయి. మా మునుపటి ఉదాహరణ యొక్క CFG:
చాలా విశ్లేషణలు నిర్మించబడిన ప్రాతినిధ్యం CFG.
అనేక ఇతర కోడ్ ప్రాతినిధ్యాలు ఉన్నాయి. మీరు చేయాలనుకుంటున్న విశ్లేషణ ప్రకారం ప్రతి ప్రాతినిధ్యానికి ప్రయోజనాలు మరియు నష్టాలు ఉన్నాయి.
విశ్లేషణ
మీరు స్లిథర్తో చేయగల సరళమైన విశ్లేషణ రకాలు సింటాక్టిక్ విశ్లేషణలు.
సింటాక్స్ విశ్లేషణ
ఒక ప్యాట్రన్ మ్యాచింగ్-లాంటి పద్ధతిని ఉపయోగించి, అననుకూలతలు మరియు లోపాలను కనుగొనడానికి స్లిథర్ కోడ్ యొక్క వివిధ భాగాలు మరియు వాటి ప్రాతినిధ్యం ద్వారా నావిగేట్ చేయగలదు.
ఉదాహరణకు, కింది డిటెక్టర్లు సింటాక్స్కు సంబంధించిన సమస్యల కోసం చూస్తాయి:
-
స్టేట్ వేరియబుల్ షాడోయింగ్ (opens in a new tab): అన్ని స్టేట్ వేరియబుల్స్పై పునరావృతమవుతుంది మరియు ఏదైనా ఒక ఇన్హెరిట్ చేయబడిన కాంట్రాక్ట్ నుండి వేరియబుల్ను షాడో చేస్తుందో లేదో తనిఖీ చేస్తుంది (state.py#L51-L62 (opens in a new tab))
-
తప్పు ERC20 ఇంటర్ఫేస్ (opens in a new tab): తప్పు ERC20 ఫంక్షన్ సంతకాల కోసం చూడండి (incorrect_erc20_interface.py#L34-L55 (opens in a new tab))
సెమాంటిక్ విశ్లేషణ
సింటాక్స్ విశ్లేషణకు విరుద్ధంగా, ఒక సెమాంటిక్ విశ్లేషణ లోతుగా వెళ్లి కోడ్ యొక్క “అర్థాన్ని” విశ్లేషిస్తుంది. ఈ కుటుంబంలో కొన్ని విస్తృత రకాల విశ్లేషణలు ఉన్నాయి. అవి మరింత శక్తివంతమైన మరియు ఉపయోగకరమైన ఫలితాలకు దారితీస్తాయి, కానీ వ్రాయడానికి కూడా చాలా క్లిష్టంగా ఉంటాయి.
అత్యంత అధునాతన దుర్బలత్వ గుర్తింపుల కోసం సెమాంటిక్ విశ్లేషణలు ఉపయోగించబడతాయి.
డేటా డిపెండెన్సీ విశ్లేషణ
variable_a విలువ variable_b ద్వారా ప్రభావితమయ్యే మార్గం ఉంటే, variable_a వేరియబుల్ variable_bపై డేటా-ఆధారితమని చెప్పబడుతుంది.
కింది కోడ్లో, variable_a variable_bపై ఆధారపడి ఉంటుంది:
// ...
variable_a = variable_b + 1;
స్లిథర్ దాని ఇంటర్మీడియట్ రిప్రజెంటేషన్ (తరువాతి విభాగంలో చర్చించబడింది) కారణంగా, అంతర్నిర్మిత డేటా డిపెండెన్సీ (opens in a new tab) సామర్థ్యాలతో వస్తుంది.
డేటా డిపెండెన్సీ వినియోగం యొక్క ఉదాహరణ ప్రమాదకరమైన కఠినమైన సమానత్వ డిటెక్టర్ (opens in a new tab)లో కనుగొనవచ్చు. ఇక్కడ స్లిథర్ ఒక ప్రమాదకరమైన విలువతో కఠినమైన సమానత్వ పోలిక కోసం చూస్తుంది (incorrect_strict_equality.py#L86-L87 (opens in a new tab)), మరియు దాడి చేసే వ్యక్తి కాంట్రాక్ట్ను ట్రాప్ చేయకుండా నిరోధించడానికి, ==కి బదులుగా >= లేదా <=ని ఉపయోగించాలని వినియోగదారునికి తెలియజేస్తుంది. ఇతర వాటితో పాటు, డిటెక్టర్ balanceOf(address)కి కాల్ యొక్క రిటర్న్ విలువను ప్రమాదకరమైనదిగా పరిగణిస్తుంది (incorrect_strict_equality.py#L63-L64 (opens in a new tab)), మరియు దాని వినియోగాన్ని ట్రాక్ చేయడానికి డేటా డిపెండెన్సీ ఇంజిన్ను ఉపయోగిస్తుంది.
ఫిక్స్డ్-పాయింట్ కంప్యూటేషన్
మీ విశ్లేషణ CFG ద్వారా నావిగేట్ చేసి, ఎడ్జ్లను అనుసరిస్తే, మీరు ఇప్పటికే సందర్శించిన నోడ్స్ను చూసే అవకాశం ఉంది. ఉదాహరణకు, ఒక లూప్ క్రింద చూపిన విధంగా ఉంటే:
for(uint i; i < range; ++){
variable_a += 1
}
మీ విశ్లేషణ ఎప్పుడు ఆపాలో తెలుసుకోవాలి. ఇక్కడ రెండు ప్రధాన వ్యూహాలు ఉన్నాయి: (1) ప్రతి నోడ్పై పరిమిత సంఖ్యలో పునరావృతం చేయడం, (2) ఫిక్స్పాయింట్ అని పిలవబడే దానిని లెక్కించడం. ఒక ఫిక్స్పాయింట్ అంటే ప్రాథమికంగా ఈ నోడ్ను విశ్లేషించడం వల్ల ఎటువంటి అర్థవంతమైన సమాచారం లభించదు.
ఫిక్స్పాయింట్ ఉపయోగించిన ఉదాహరణ రీఎంట్రన్సీ డిటెక్టర్లలో కనుగొనవచ్చు: స్లిథర్ నోడ్స్ను అన్వేషిస్తుంది మరియు బాహ్య కాల్స్, స్టోరేజ్కు వ్రాయడం మరియు చదవడం కోసం చూస్తుంది. ఒకసారి అది ఒక ఫిక్స్పాయింట్ను చేరుకున్న తర్వాత (reentrancy.py#L125-L131 (opens in a new tab)), అది అన్వేషణను ఆపివేస్తుంది మరియు వివిధ రీఎంట్రన్సీ ప్యాట్రన్ల ద్వారా రీఎంట్రన్సీ ఉందో లేదో చూడటానికి ఫలితాలను విశ్లేషిస్తుంది (reentrancy_benign.py (opens in a new tab), reentrancy_read_before_write.py (opens in a new tab), reentrancy_eth.py (opens in a new tab)).
సమర్థవంతమైన ఫిక్స్డ్ పాయింట్ కంప్యూటేషన్ను ఉపయోగించి విశ్లేషణలు రాయడానికి, విశ్లేషణ దాని సమాచారాన్ని ఎలా ప్రచారం చేస్తుందనే దానిపై మంచి అవగాహన అవసరం.
మధ్యంతర ప్రాతినిధ్యం
ఇంటర్మీడియట్ రిప్రజెంటేషన్ (IR) అనేది అసలు భాష కంటే స్టాటిక్ విశ్లేషణకు మరింత అనుకూలంగా ఉండేలా ఉద్దేశించిన భాష. స్లిథర్ సాలిడిటీని దాని స్వంత IR: SlithIR (opens in a new tab)కి అనువదిస్తుంది.
మీరు కేవలం ప్రాథమిక తనిఖీలను వ్రాయాలనుకుంటే SlithIRను అర్థం చేసుకోవడం అవసరం లేదు. అయితే, మీరు అధునాతన సెమాంటిక్ విశ్లేషణలను వ్రాయాలని ప్లాన్ చేస్తే ఇది ఉపయోగపడుతుంది. SlithIR (opens in a new tab) మరియు SSA (opens in a new tab) ప్రింటర్లు కోడ్ ఎలా అనువదించబడిందో అర్థం చేసుకోవడానికి మీకు సహాయపడతాయి.
API బేసిక్స్
స్లిథర్ ఒక APIని కలిగి ఉంది, ఇది కాంట్రాక్ట్ మరియు దాని ఫంక్షన్ల యొక్క ప్రాథమిక లక్షణాలను అన్వేషించడానికి మిమ్మల్ని అనుమతిస్తుంది.
ఒక కోడ్బేస్ను లోడ్ చేయడానికి:
from slither import Slither
slither = Slither('/path/to/project')
కాంట్రాక్ట్లు మరియు ఫంక్షన్లను అన్వేషించడం
ఒక Slither ఆబ్జెక్ట్ కలిగి ఉంది:
contracts (list(Contract): కాంట్రాక్ట్ల జాబితాcontracts_derived (list(Contract): మరొక కాంట్రాక్ట్ ద్వారా ఇన్హెరిట్ చేయబడని కాంట్రాక్ట్ల జాబితా (కాంట్రాక్ట్ల ఉపసమితి)get_contract_from_name (str): దాని పేరు నుండి ఒక కాంట్రాక్ట్ను తిరిగి ఇస్తుంది
ఒక Contract ఆబ్జెక్ట్ కలిగి ఉంది:
name (str): కాంట్రాక్ట్ పేరుfunctions (list(Function)): ఫంక్షన్ల జాబితాmodifiers (list(Modifier)): మాడిఫైయర్ల జాబితాall_functions_called (list(Function/Modifier)): కాంట్రాక్ట్ ద్వారా చేరగల అన్ని అంతర్గత ఫంక్షన్ల జాబితాinheritance (list(Contract)): ఇన్హెరిట్ చేయబడిన కాంట్రాక్ట్ల జాబితాget_function_from_signature (str): దాని సంతకం నుండి ఒక ఫంక్షన్ను తిరిగి ఇస్తుందిget_modifier_from_signature (str): దాని సంతకం నుండి ఒక మాడిఫైయర్ను తిరిగి ఇస్తుందిget_state_variable_from_name (str): దాని పేరు నుండి ఒక స్టేట్వేరియబుల్ను తిరిగి ఇస్తుంది
ఒక Function లేదా Modifier ఆబ్జెక్ట్ కలిగి ఉంది:
name (str): ఫంక్షన్ పేరుcontract (contract): ఫంక్షన్ ప్రకటించబడిన కాంట్రాక్ట్nodes (list(Node)): ఫంక్షన్/మాడిఫైయర్ యొక్క CFGని కంపోజ్ చేసే నోడ్స్ జాబితాentry_point (Node): CFG యొక్క ఎంట్రీ పాయింట్variables_read (list(Variable)): చదవబడిన వేరియబుల్స్ జాబితాvariables_written (list(Variable)): వ్రాయబడిన వేరియబుల్స్ జాబితాstate_variables_read (list(StateVariable)): చదవబడిన స్టేట్ వేరియబుల్స్ జాబితా (వేరియబుల్స్readయొక్క ఉపసమితి)state_variables_written (list(StateVariable)): వ్రాయబడిన స్టేట్ వేరియబుల్స్ జాబితా (వేరియబుల్స్writtenయొక్క ఉపసమితి)
పేజీ చివరి నవీకరణ: 15 ఏప్రిల్, 2026

