Grunderna i Web3- och DApp-utveckling · Lektion

Tekniker för gasoptimering

Lär er strategier för att skriva gaseffektiv Solidity-kod, minska transaktionskostnaderna och förbättra DApp-prestandan på blockkedjan.

Lektion 3 av 311 steg

Tekniker för gasoptimering är en gratis lektion i Grunderna i Web3- och DApp-utveckling på CoddyKit. Detta är lektion 3 av 3. Du kan läsa vilka 3 lektioner som helst i den här lärvägen kostnadsfritt i sin helhet – därefter låser CoddyKit PRO upp alla lektioner, plus praktisk övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Den ingår i lärvägen för Grunderna i Web3- och DApp-utveckling, och Era framsteg synkroniseras mellan webben och CoddyKit-appen. Kursen i Grunderna i Web3- och DApp-utveckling innehåller totalt 3 lektioner.

Varför gasoptimering är viktig

Välkommen till den sista lektionen i DApp-säkerhet och granskning! I dag ska vi bemästra tekniker för gasoptimering.

Gas är avgiften som betalas för att köra transaktioner på Ethereum-nätverket. Det fungerar ungefär som bränsle i en bil.

  • Kostnadsminskning: Lägre gasavgifter innebär billigare transaktioner för användarna.
  • Prestanda: Optimerade kontrakt körs snabbare.
  • Användarupplevelse: Bättre prestanda leder till nöjdare användare och smidigare DApps.

Förstå gaskostnader

Varje operation som Ethereum Virtual Machine (EVM) utför kostar en viss mängd gas. Komplexa operationer kostar mer.

När ni distribuerar eller interagerar med ett smartkontrakt betalar ni gas för att:

  • Lagra data på blockkedjan (dyrast).
  • Utföra beräkningar.
  • Skicka Ether.

Målet är att skriva kod som använder färre av dessa kostsamma operationer.

Storage kontra memory kontra calldata

Att förstå var era data finns är avgörande för att spara gas. Varje lagringsplats har olika kostnader:

  • Storage: Permanent och lagrad on-chain. Dyrast att läsa från och skriva till (SSTORE/SLOAD).
  • Memory: Tillfällig och finns endast medan funktionen körs. Billigare än storage.
  • Calldata: Oföränderlig, skrivskyddad och tillfällig. Används för argument till externa funktioner. Billigast för externa indata.

Prioritera calldata eller memory för variabler som inte behöver finnas kvar on-chain.

Minimera skrivningar till storage (SSTORE)

Att skriva till storage (SSTORE) är den enskilt dyraste operationen i Solidity. Fråga alltid: behöver den här variabeln verkligen lagras on-chain?

I stället för att uppdatera en räknare i storage vid varje iteration kan ni beräkna värdet en gång i slutet eller använda events för att logga ändringar.

Se följande enkla exempel:

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract StorageCostExample {
    uint256 public counter;

    // High gas cost: writes to storage every call
    function incrementBad() public {
        counter++;
    }

    // Lower gas cost: only reads state
    function getCounter() public view returns (uint256) {
        return counter;
    }
}

Packa storage-variabler

Solidity lagrar variabler i 256-bitars (32-byte) ”slots”. Om ni deklarerar flera variabler som ryms i samma slot kan de packas tillsammans, vilket sparar gas.

Tre variabler av typen uint8 tar till exempel mindre lagringsutrymme än tre variabler av typen uint256 om de deklareras efter varandra. Det sparar SSTORE-operationer.

  • Deklarera mindre datatyper (t.ex. uint8, bool) när det är möjligt.
  • Gruppera variabler av liknande storlek tillsammans.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract StoragePacking {
    // These will likely pack into one slot
    uint8 public value1;
    bool public isActive;
    uint8 public value2;

    // This will take a separate slot
    address public owner;

    function setValues(uint8 _v1, bool _active, uint8 _v2) public {
        value1 = _v1;
        isActive = _active;
        value2 = _v2;
    }
}

Kortslutning av villkor

När logiska operatorer som && (AND) eller || (OR) används tillämpar Solidity ”short-circuiting”. Det innebär att utvärderingen av villkoren stoppas så snart resultatet är känt.

Ni kan spara gas genom att placera det billigare villkoret, det som troligast misslyckas eller det som troligast blir sant, först.

  • För && placerar ni villkoret som troligast blir false först.
  • För || placerar ni villkoret som troligast blir true först.
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract ShortCircuitExample {
    uint256 public data = 100;

    function checkCondition(uint256 _input) public view returns (bool) {
        // Cheaper check (input) before more expensive check (storage read)
        return (_input > 0 && data > 50); 
    }
}

Effektiva loopar och iterationer

Loopar kan vara kostsamma i gas, särskilt om de itererar över stora arrayer som lagras i storage. Undvik om möjligt obegränsade loopar eller loopar över dynamiska arrayer i storage.

  • Bearbeta data off-chain om det är möjligt.
  • Använd arrayer med fast storlek i stället för dynamiska när storleken är känd.
  • Strukturera om logiken för att undvika loopar eller minska antalet iterationer.
  • Överväg ett pull-baserat system för utbetalningar i stället för att skicka till många mottagare i en och samma transaktion.

Använda `view`- och `pure`-funktioner

Funktioner som markerats med view eller pure ändrar inte blockkedjans tillstånd. När de anropas externt kostar de ingen gas!

  • view: Läser tillståndsvariabler men ändrar dem inte.
  • pure: Varken läser eller ändrar tillståndsvariabler.

Interna anrop till view/pure-funktioner förbrukar fortfarande gas (som en del av den större transaktionen), men korrekt användning av dem för externa frågor sparar mycket gas åt användarna.

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract ViewPureExample {
    uint256 public myNumber = 42;

    // Costs no gas for external calls
    function getNumber() public view returns (uint256) {
        return myNumber;
    }

    // Costs no gas for external calls
    function add(uint256 a, uint256 b) public pure returns (uint256) {
        return a + b;
    }
}

Gaskostnader vid felhantering

Solidity erbjuder flera sätt att hantera fel: require(), revert() och assert().

  • require(): Används för att validera indata och villkor. Återbetalar oanvänd gas när det misslyckas. (Rekommenderas för de flesta kontroller.)
  • revert(): Liknar require och återbetalar också oanvänd gas.
  • assert(): Används för interna invariansvillkor och bör *aldrig* misslyckas. Förbrukar ALL återstående gas när det misslyckas. (Använd sparsamt för kritiska interna kontroller.)

Det är mycket dyrare att misslyckas med en assert än med en require, så välj felhantering med omsorg.

Fråga: gasoptimering

Ta följande Solidity-kodfragment i beaktande. Vilken ändring skulle sannolikt leda till den STÖRSTA gasbesparingen för en användare som anropar updateStatus?

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract GasPuzzle {
    uint256 public statusId;
    string public statusName;
    address public owner;

    constructor() {
        owner = msg.sender;
        statusId = 1;
        statusName = "Initial";
    }

    function updateStatus(uint256 _newId, string memory _newName) public {
        require(msg.sender == owner, "Not owner");
        statusId = _newId;
        statusName = _newName;
    }
}

Repetition: bemästra gasoptimering

Ni har lärt er viktiga strategier för att skriva gaseffektiv Solidity-kod!

Kom ihåg dessa principer:

  • Minimera skrivningar till storage: Den gyllene regeln.
  • Packa variabler: Gruppera mindre variabler så att de ryms i slots.
  • Använd effektiva datalokationer: Föredra calldata/memory framför storage.
  • Optimera loopar: Undvik obegränsade eller stora iterationer.
  • Utnyttja view/pure: För externa läsningar utan gaskostnad.
  • Smart felhantering: Använd require/revert, inte assert, för användarindata.

Genom att tillämpa dessa tekniker blir era DApps billigare, snabbare och mer användarvänliga. Fortsätt öva!

Gratis att börja

Lär dig Grunderna i Web3- och DApp-utveckling 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
29
Lektioner
105

Vanliga frågor

Är lektionen ”Tekniker för gasoptimering” gratis?

Ja – du kan läsa vilka 3 lektioner som helst i lärvägen Grunderna i Web3- och DApp-utveckling, inklusive ”Tekniker för gasoptimering”, kostnadsfritt i sin helhet här på webben. Därefter låser CoddyKit PRO upp alla lektioner, plus interaktiv övning med en inbyggd kodredigerare och en AI-lärare dygnet runt. Kursen i Grunderna i Web3- och DApp-utveckling innehåller totalt 3 lektioner.

Vad lär jag mig i ”Tekniker för gasoptimering”?

Lär er strategier för att skriva gaseffektiv Solidity-kod, minska transaktionskostnaderna och förbättra DApp-prestandan på blockkedjan. Ni övar på Grunderna i Web3- och DApp-utveckling 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 Grunderna i Web3- och DApp-utveckling?

Du behöver inga förkunskaper. Utbildningen i Grunderna i Web3- och DApp-utveckling 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 3 av 3.

Hur lång tid tar lektionen ”Tekniker för gasoptimering”?

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 Grunderna i Web3- och DApp-utveckling-lektionen?

Ja. Varje Grunderna i Web3- och DApp-utveckling-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

  1. Vanliga sårbarheter i smarta kontrakt
  2. Säkerhetsverktyg och granskningar
  3. Tekniker för gasoptimering
← Tillbaka till Grunderna i Web3- och DApp-utveckling