Vanliga sårbarheter (reentrancy med mera)
Förstå och motverka vanliga sårbarheter i smarta kontrakt, till exempel reentrancy, heltalsöverflöden och underflöden samt front-running-attacker.
Vanliga sårbarheter (reentrancy med mera) är en gratis lektion i Smarta blockkedjekontrakt med Solidity på CoddyKit. Detta är lektion 1 av 4. Ni kan läsa hela lektionen gratis nedan och sedan öva praktiskt i webbläsaren med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt. Den ingår i lärvägen för Smarta blockkedjekontrakt med Solidity, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Smarta blockkedjekontrakt med Solidity innehåller totalt 4 lektioner.
Säkerhet för smarta kontrakt: översikt
Välkommen till denna viktiga lektion om säkerhet för smarta kontrakt! Till skillnad från traditionell programvara kan buggar i smarta kontrakt leda till oåterkalleliga förluster av tillgångar.
Eftersom kontrakt på blockkedjan ofta är oföränderliga är det oerhört svårt, om inte omöjligt, att åtgärda sårbarheter efter distributionen. Säkerhet måste vara högsta prioritet från första dagen.
Förstå återinträdesattacker
Återinträde är en kritisk sårbarhet där ett externt anrop till ett opålitligt kontrakt kan återgå till det ursprungliga kontraktet innan det första funktionsanropet har slutförts.
Detta gör det möjligt för angriparen att upprepade gånger tömma tillgångar eller manipulera tillståndet genom att anropa den sårbara funktionen flera gånger.
Återinträde: Ett sårbart exempel
Betrakta detta förenklade uttagskontrakt. Kan du upptäcka det potentiella problemet?
Tillståndet (balances[msg.sender]) uppdateras *efter* det externa anropet till msg.sender.call. Denna fördröjning skapar ett utrymme för en attack.
pragma solidity ^0.8.0;
contract VulnerableWithdraw {
mapping(address => uint) public balances;
constructor() payable {
// Fund contract for demo purposes
}
function deposit() public payable {
balances[msg.sender] += msg.value;
}
function withdraw(uint _amount) public {
require(balances[msg.sender] >= _amount, "Insufficient balance");
// External call FIRST, state update LATER
(bool success, ) = msg.sender.call{value: _amount}("");
require(success, "Transfer failed");
balances[msg.sender] -= _amount; // This line is vulnerable!
}
function getBalance() public view returns (uint) {
return address(this).balance;
}
}Så går återinträdesattacken till
Så här utnyttjar en angripare det föregående kontraktet:
- 1. Insättning: Angriparen sätter in tillgångar i
VulnerableWithdraw. - 2. Uttag: Angriparen anropar
withdraw(amount). - 3. Återinträde: När
msg.sender.callöverför Ether till angriparen aktiveras dennes skadliga fallback-funktion. - 4. Upprepning: Fallback-funktionen anropar omedelbart
withdraw(amount)igen, innan det ursprungliga anropet uppdaterar saldot. Detta upprepas tills tillgångarna är tömda.
Förhindra återinträde: Lösningen
Det effektivaste sättet att förhindra återinträde är att följa mönstret Checks-Effects-Interactions (CEI):
- 1. Checks: Kontrollera alla villkor, till exempel
require-satser. - 2. Effects: Uppdatera alla tillståndsvariabler, till exempel
balances[msg.sender] -= _amount. - 3. Interactions: Gör externa anrop, till exempel
msg.sender.call.
Detta säkerställer att tillståndet uppdateras *innan* opålitlig extern kod kan köras.
Återinträde: Det korrigerade kontraktet
Här är den korrigerade versionen av uttagskontraktet, där CEI-mönstret tillämpas. Observera ordningen på operationerna.
Nu minskas saldot *innan* det externa anropet, vilket stänger utrymmet för återinträde.
pragma solidity ^0.8.0;
contract SafeWithdraw {
mapping(address => uint) public balances;
constructor() payable {
// Fund contract for demo purposes
}
function deposit() public payable {
balances[msg.sender] += msg.value;
}
function withdraw(uint _amount) public {
// 1. Checks
require(balances[msg.sender] >= _amount, "Insufficient balance");
// 2. Effects: Update state BEFORE external call
balances[msg.sender] -= _amount;
// 3. Interactions: Make external call LAST
(bool success, ) = msg.sender.call{value: _amount}("");
require(success, "Transfer failed");
}
function getBalance() public view returns (uint) {
return address(this).balance;
}
}Heltalsöverflöden och heltalsunderflöden
Heltalsöverflöden inträffar när en aritmetisk operation resulterar i ett värde som är större än det maximala värdet som variabeltypen kan lagra. Värdet 'slår runt' till sitt minsta värde.
Heltalsunderflöden är motsatsen: resultatet är mindre än det minsta värdet och slår runt till det maximala värdet.
En uint8 kan till exempel innehålla värden från 0 till 255. Om värdet är 255 och du adderar 1 blir det 0 (överflöde). Om värdet är 0 och du subtraherar 1 blir det 255 (underflöde).
Exempel på överflöde och underflöde
Före Solidity 0.8.0 slog dessa operationer tyst runt. Sedan Solidity 0.8.0 kontrolleras aritmetiska operationer som standard med avseende på överflöden och underflöden, och operationen återställs om ett sådant inträffar.
Det är ändå viktigt att förstå konceptet, särskilt när du arbetar med äldre kodbaser eller använder unchecked-block för gasoptimering.
pragma solidity ^0.8.0;
contract MathVulnerabilities {
uint8 public smallNumber = 255; // Max for uint8
function triggerOverflow() public {
// In Solidity 0.8.0+, this transaction will revert.
// In older versions, smallNumber would become 0.
smallNumber = smallNumber + 1;
}
function triggerUnderflow() public {
smallNumber = 0; // Reset for demo
// In Solidity 0.8.0+, this transaction will revert.
// In older versions, smallNumber would become 255.
smallNumber = smallNumber - 1;
}
}Front-running-attacker
Front-running är en attack där en angripare observerar en väntande transaktion och skickar in en egen transaktion med högre gasavgift för att få den körd först.
Detta är vanligt inom DeFi (decentraliserad finans), där transaktioner som stora byten eller likvideringar kan förutses och utnyttjas för att skapa vinst.
Förhindra front-running
Det är svårt att förhindra front-running på grund av mempoolens offentliga natur (poolen med väntande transaktioner). Det finns dock några strategier:
- Commit-reveal-scheman: Användare skickar in en hashad version av sin avsikt (commit) och avslöjar sedan de faktiska uppgifterna.
- Batchning: Transaktioner grupperas för att minska synligheten för enskilda transaktioner.
- Decentraliserade sequencers/L2-lösningar: Lösningar används som erbjuder mer privat eller kontrollerad ordning för transaktioner.
- Slippagekontroll: Användare anger den högsta accepterade prisförändringen för byten.
Sårbarhetskontroll
Du har lärt dig om tre stora sårbarheter i smarta kontrakt. Nu testar vi dina kunskaper!
Sammanfattning: Säkerheten först
I den här lektionen gick vi igenom kritiska sårbarheter i smarta kontrakt: återinträde, heltalsöverflöden och heltalsunderflöden samt front-running.
- Vi såg hur återinträde utnyttjar externa anrop och hur mönstret Checks-Effects-Interactions ger ett robust skydd.
- Vi förstod hur heltalsaritmetik kan leda till oväntade värden och hur viktigt det är med kompilatorkontroller (Solidity 0.8.0+).
- Slutligen diskuterade vi front-running och metoder som commit-reveal för att begränsa det.
Prioritera alltid säkerheten när du utvecklar smarta kontrakt!
Lär dig Smarta blockkedjekontrakt med Solidity med en AI-lärare – gratis
Skriv och kör riktig kod i webbläsaren, få omedelbar hjälp av en AI-lärare dygnet runt och fortsätt där du slutade – på webben eller i appen.
- Kurser
- 12
- Lektioner
- 48
Vanliga frågor
Är lektionen ”Vanliga sårbarheter (reentrancy med mera)” gratis?
Ja – hela texten till ”Vanliga sårbarheter (reentrancy med mera)” kan läsas gratis här på webben. Om Ni vill öva interaktivt med en inbyggd kodredigerare och en AI-handledare som är tillgänglig dygnet runt och låsa upp resten av kursen i Smarta blockkedjekontrakt med Solidity, kan Ni uppgradera till CoddyKit PRO. Kursen i Smarta blockkedjekontrakt med Solidity innehåller totalt 4 lektioner.
Vad lär jag mig i ”Vanliga sårbarheter (reentrancy med mera)”?
Förstå och motverka vanliga sårbarheter i smarta kontrakt, till exempel reentrancy, heltalsöverflöden och underflöden samt front-running-attacker. Ni övar på Smarta blockkedjekontrakt med Solidity med praktisk kod som körs direkt i webbläsaren, medan en AI-handledare som är tillgänglig dygnet runt svarar på Era frågor under lektionen.
Behöver jag någon erfarenhet för att börja lära mig Smarta blockkedjekontrakt med Solidity?
Du behöver inga förkunskaper. Utbildningen i Smarta blockkedjekontrakt med Solidity på CoddyKit är upplagd för allt från nybörjare till avancerade elever, så att du kan börja här eller från början och gå fram i din egen takt. Detta är lektion 1 av 4.
Hur lång tid tar lektionen ”Vanliga sårbarheter (reentrancy med mera)”?
De flesta CoddyKit-lektioner tar cirka 5–10 minuter. Varje lektion är kort och interaktiv, så att du gör stadiga framsteg och kan fortsätta precis där du slutade – på webben eller i appen.
Kan jag skriva och köra kod i den här Smarta blockkedjekontrakt med Solidity-lektionen?
Ja. Varje Smarta blockkedjekontrakt med Solidity-lektion innehåller en inbyggd kodredigerare, så att du kan skriva och köra riktig kod direkt i webbläsaren och få omedelbar AI-feedback – utan lokal installation.
Alla lektioner i den här kursen
- Vanliga sårbarheter (reentrancy med mera)
- Mönster för åtkomstkontroll
- Säker kodning med SafeMath
- Granskning, testning och bug bounty-program