Grundlæggende udvikling af Web3- og DApp-programmer · Lektion

Almindelige sårbarheder i smart contracts

Undersøg udbredte sikkerhedsfejl i smart contracts, såsom reentrancy, heltalsoverløb og -underløb samt problemer med adgangskontrol.

Lektion 1 af 312 trin

Almindelige sårbarheder i smart contracts er en gratis Grundlæggende udvikling af Web3- og DApp-programmer-lektion på CoddyKit. Dette er lektion 1 af 3. Du kan læse alle 3 lektioner i dette læringsspor gratis i deres fulde længde — derefter låser CoddyKit PRO alle lektioner op samt praktiske øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Den er en del af læringsforløbet i Grundlæggende udvikling af Web3- og DApp-programmer, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Grundlæggende udvikling af Web3- og DApp-programmer-kurset indeholder 3 lektioner i alt.

Hvorfor sikkerhed er vigtig

Smart contracts administrerer værdifulde aktiver og udfører uigenkaldelige handlinger på blockchainen. En enkelt sårbarhed kan føre til betydelige økonomiske tab eller uautoriseret manipulation af en contract.

I modsætning til traditionel software er implementerede smart contracts ofte uforanderlige. Det betyder, at det kan være meget vanskeligt at rette fejl eller sårbarheder, når en contract først er aktiv. Det kan nogle gange kræve komplekse mekanismer til opgradering eller endda en ny implementering.

Reentrancy forklaret

Reentrancy er en kritisk sårbarhed, hvor et eksternt kald fra din contract til en anden contract eller en ekstern adresse kan "gå ind i" den kaldende contract igen, før det oprindelige funktionskald er færdigt med at blive udført.

Det gør det muligt for en angriber at udføre bestemte dele af en funktion gentagne gange, hvilket ofte fører til uautoriserede hævninger af midler eller manipulation af tilstanden, så contractens saldo tømmes.

Sårbart reentrancy-eksempel

I dette eksempel sender funktionen withdraw først Ether (et eksternt kald) og opdaterer derefter brugerens saldo. En angriber kan gå ind i withdraw igen flere gange, før saldoen sættes til nul.

pragma solidity ^0.8.0;

contract VulnerableWithdraw {
    mapping(address => uint) public balances;

    constructor() payable {
        balances[msg.sender] = msg.value;
    }

    function withdraw() public {
        uint amount = balances[msg.sender];
        require(amount > 0, "No funds to withdraw");

        // Vulnerable: External call BEFORE state update
        (bool success, ) = msg.sender.call{value: amount}("");
        require(success, "Transfer failed");

        balances[msg.sender] = 0; // State updated AFTER call
    }

    function deposit() public payable {
        balances[msg.sender] += msg.value;
    }

    function getBalance() public view returns (uint) {
        return address(this).balance;
    }
}

Forebyggelse af reentrancy

Det mest effektive forsvar mod reentrancy er mønsteret Checks-Effects-Interactions. Dette mønster fastlægger rækkefølgen af operationer i dine funktioner:

  • Checks: Bekræft alle betingelser (f.eks. require-sætninger).
  • Effects: Udfør alle nødvendige ændringer af tilstanden (f.eks. opdater saldi og rediger variable).
  • Interactions: Udfør alle eksterne kald (f.eks. send Ether eller kald en anden contract).

Opdater altid contractens tilstand *før* du sender Ether eller kalder eksterne contracts.

Sikker hævefunktion

Her er den rettede funktion withdraw. Bemærk, hvordan brugerens saldo opdateres (en "effekt") *før* Ether sendes (en "interaktion").

pragma solidity ^0.8.0;

contract SecureWithdraw {
    mapping(address => uint) public balances;

    constructor() payable {
        balances[msg.sender] = msg.value;
    }

    function withdraw() public {
        uint amount = balances[msg.sender];
        require(amount > 0, "No funds to withdraw");

        balances[msg.sender] = 0; // Effect: State updated BEFORE call

        (bool success, ) = msg.sender.call{value: amount}(""); // Interaction
        require(success, "Transfer failed");
    }

    function deposit() public payable {
        balances[msg.sender] += msg.value;
    }

    function getBalance() public view returns (uint) {
        return address(this).balance;
    }
}

Heltalsoverløb og underløb

Heltalstyper i Solidity (som uint eller int) har en fast størrelse. Et overløb opstår, når en aritmetisk operation resulterer i en værdi, der er større end det maksimale, som en heltalstype kan indeholde. Værdien går da rundt til typens minimumsværdi (f.eks. bliver 255 + 1 på en uint8 til 0).

Et underløb opstår, når en operation resulterer i en værdi, der er mindre end minimumsværdien (normalt 0 for uint), så værdien går rundt til maksimumsværdien (f.eks. bliver 0 - 1 på en uint8 til 255).

Sårbar heltalslogik

Før Solidity 0.8.0 blev denne adfærd med at gå rundt ikke automatisk kontrolleret. Dette eksempel, der bruger en ældre Solidity-version, viser, hvordan en angriber kunne udnytte et underløb til at opnå en enorm saldo.

pragma solidity ^0.7.0; // Using 0.7.x to demonstrate vulnerability

contract VulnerableCounter {
    uint public count = 0;

    // If count is 0 and _amount is 1, count becomes type(uint).max
    function decrement(uint _amount) public {
        count -= _amount; // Vulnerable to underflow
    }

    // If count + _amount exceeds type(uint).max, count wraps around to a small number
    function increment(uint _amount) public {
        count += _amount; // Vulnerable to overflow
    }
}

Begrænsning af overløb og underløb

Siden Solidity 0.8.0 medfører aritmetiske operationer automatisk en tilbagerulning (mislykkes) ved overløb eller underløb. Det giver som standard robust beskyttelse mod disse problemer og gør dine contracts meget sikrere.

For contracts, der er skrevet i ældre Solidity-versioner (før 0.8.0), var det almindeligt at bruge biblioteker som OpenZeppelin's SafeMath. SafeMath leverede funktioner (add, sub, mul, div), der udførte kontrolleret aritmetik og rullede tilbage, hvis der ville opstå et overløb eller underløb.

Problemer med adgangskontrol

Adgangskontrol sikrer, at kun godkendte brugere eller roller kan udføre bestemte følsomme handlinger i en smart contract. Forkert adgangskontrol er en meget almindelig kilde til sårbarheder.

Almindelige fejl omfatter:

  • Manglende autorisationskontroller for kritiske funktioner (f.eks. administrative funktioner).
  • Direkte brug af msg.sender uden at bekræfte ejerskab eller rolle.
  • Svage eller let gættelige autorisationsmekanismer.

Sårbar adgangskontrol

I dette eksempel er funktionen setCriticalValue beregnet til kun at kunne bruges af contractens ejer, men den mangler en kontrol, der håndhæver dette. Alle brugere kan kalde funktionen og ændre den kritiske værdi.

Modifikatoren onlyOwner viser den korrekte måde at begrænse adgangen på.

pragma solidity ^0.8.0;

contract VulnerableAccess {
    address public owner;
    uint public criticalValue;

    constructor() {
        owner = msg.sender;
        criticalValue = 100;
    }

    // Vulnerable: This function should be owner-only, but it's public!
    function setCriticalValue(uint _newValue) public {
        criticalValue = _newValue; // Anyone can call this!
    }

    // Correct way to restrict access using a modifier
    function setCriticalValueSecure(uint _newValue) public onlyOwner {
        criticalValue = _newValue;
    }

    modifier onlyOwner() {
        require(msg.sender == owner, "Not owner");
        _;
    }
}

Kontrol af sårbarheder

Hvilket af følgende mønstre er designet til at forhindre reentrancy-angreb ved at sikre, at ændringer af tilstanden sker før eksterne kald?

Opsummering: Sikre smart contracts

I dag har vi gennemgået nogle af de mest almindelige og kritiske sårbarheder i smart contracts:

  • Reentrancy: Forebygges ved at følge mønsteret Checks-Effects-Interactions.
  • Heltalsoverløb og -underløb: Begrænses ved at bruge Solidity 0.8.0+ (automatiske kontroller) eller SafeMath til ældre versioner.
  • Problemer med adgangskontrol: Sikres ved at implementere korrekte autorisationskontroller med modifikatorer som onlyOwner.

Prioritér altid sikkerhed i din udvikling af smart contracts. En grundig revision af din kode og overholdelse af bedste praksis er afgørende trin til at beskytte aktiver og sikre pålideligheden af dine decentraliserede applikationer.

Gratis at komme i gang

Lær Grundlæggende udvikling af Web3- og DApp-programmer med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
29
Lektioner
105

Ofte stillede spørgsmål

Er lektionen “Almindelige sårbarheder i smart contracts” gratis?

Ja — alle 3 lektioner i læringssporet Grundlæggende udvikling af Web3- og DApp-programmer, inklusive “Almindelige sårbarheder i smart contracts”, kan læses gratis i deres fulde længde her på webstedet. Derefter låser CoddyKit PRO alle lektioner op samt interaktive øvelser med en indbygget kodeeditor og en AI-underviser døgnet rundt. Grundlæggende udvikling af Web3- og DApp-programmer-kurset indeholder 3 lektioner i alt.

Hvad lærer jeg i “Almindelige sårbarheder i smart contracts”?

Undersøg udbredte sikkerhedsfejl i smart contracts, såsom reentrancy, heltalsoverløb og -underløb samt problemer med adgangskontrol. Du øver dig i Grundlæggende udvikling af Web3- og DApp-programmer med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Grundlæggende udvikling af Web3- og DApp-programmer?

Der kræves ingen tidligere erfaring. Grundlæggende udvikling af Web3- og DApp-programmer på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 1 af 3.

Hvor lang tid tager lektionen “Almindelige sårbarheder i smart contracts”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Grundlæggende udvikling af Web3- og DApp-programmer-lektion?

Ja. Alle Grundlæggende udvikling af Web3- og DApp-programmer-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Almindelige sårbarheder i smart contracts
  2. Sikkerhedsværktøjer og audits
  3. Teknikker til gasoptimering
← Tilbage til Grundlæggende udvikling af Web3- og DApp-programmer