Optimalisering av lagring
Pakking og slots
Optimalisering av lagring er en gratis leksjon i Grunnleggende om Web3- og DApp-utvikling på CoddyKit. Dette er leksjon 2 av 4. Du kan lese valgfritt 3 leksjoner fra denne læringsstien gratis i sin helhet – deretter låser CoddyKit PRO opp alle leksjoner, samt praktisk øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Den er en del av læringsløpet i Grunnleggende om Web3- og DApp-utvikling, og fremdriften din synkroniseres mellom nettet og CoddyKit-appen. Kurset i Grunnleggende om Web3- og DApp-utvikling inneholder totalt 4 leksjoner.
Grunnleggende om lagringsslots
Kontraktlagring er en enorm matrise med 32-bytes slots, indeksert fra slot 0. Tilstandsvariabler tildeles slots i deklarasjonsrekkefølgen.
Hver slot du skriver til, koster gas. Jo færre slots dataene dine opptar, desto billigere er kontrakten å bruke. Å forstå slot-oppsettet er grunnlaget for å optimalisere lagring.
contract Layout {
uint256 a; // slot 0
uint256 b; // slot 1
uint256 c; // slot 2
}Pakking av variabler
Solidity-kompilatoren pakker flere små variabler inn i én enkelt 32-bytes slot når de passer sammen fortløpende.
En uint128 bruker 16 byte, så to slike deler én slot. En bool bruker 1 byte, og en uint8 bruker 1 byte. Pakking reduserer både lagringskostnadene ved utrulling og under kjøring.
contract Packed {
uint128 a; // slot 0 (bytes 0-15)
uint128 b; // slot 0 (bytes 16-31)
uint256 c; // slot 1
}Deklarasjonsrekkefølgen er viktig
Pakking fungerer bare for variabler som står ved siden av hverandre i deklarasjonen. Et dårlig ordnet oppsett sløser med slots.
I eksempelet nedenfor tvinger uint256 de to uint128-variablene inn i separate slots. Hvis du endrer rekkefølgen slik at de små typene står sammen, kan de pakkes.
// BAD: 3 slots
uint128 a; // slot 0
uint256 b; // slot 1
uint128 c; // slot 2
// GOOD: 2 slots
uint128 a; // slot 0
uint128 c; // slot 0
uint256 b; // slot 1Velge heltallsstørrelser
Mindre heltall sparer bare gas når de pakkes. En frittstående uint8 i sin egen slot er ikke billigere enn en uint256, og kan til og med koste mer på grunn av maskeringsoperasjoner.
Tommelfingerregel: Bruk uint256 som standard, og reduser størrelsen bare når du kan få flere små verdier inn i én slot.
Pakking av strukturer
Strukturer følger de samme pakker reglene. Ordne strukturmedlemmene slik at små typer grupperes sammen. En godt pakket struktur kan redusere antallet SSTORE-operasjoner betydelig.
struct Order {
uint128 amount; // slot 0
uint64 timestamp;// slot 0
uint64 id; // slot 0
address maker; // slot 1
}Konstanter og uforanderlige verdier
Verdier som aldri endres, bør ikke ligge i lagring i det hele tatt.
constant— bygges direkte inn i bytekoden ved kompilering, uten lagringimmutable— settes én gang i konstruktøren og lagres i bytekoden, ikke i lagringen
Begge unngår kostbare SLOAD-operasjoner fullstendig.
uint256 public constant MAX_SUPPLY = 10000;
address public immutable owner;
constructor() {
owner = msg.sender;
}Mappinger og dynamiske matriser
Mappinger og dynamiske matriser pakkes ikke. Hver oppføring opptar sin egen slot, beregnet ved å hashe nøkkelen sammen med basissloten.
Du kan ikke pakke på tvers av mapping-oppføringer, men du kan pakke strukturen som lagres som mapping-verdi. Hvis du utformer verdistrukturen slik at den får plass i færre slots, sparer du gas ved hver skriving.
mapping(address => Order) public orders;
// each Order packs into 2 slots regardless of mappingMellomlagring av lagringslesinger
Hvis du leser en lagringsvariabel gjentatte ganger i en funksjon, betaler du for hver tilgang. Kopier den én gang til en lokal minnevariabel, og bruk deretter den lokale variabelen.
Dette er særlig nyttig i løkker, der hver iterasjon ellers ville lest lagringen på nytt.
uint256 len = items.length; // cache length once
for (uint256 i = 0; i < len; i++) {
// process items[i]
}Skriving i grupper
Når du oppdaterer flere felt i en pakket struktur, laster du strukturen inn i minnet, endrer den og skriver den deretter tilbake én gang. Kompilatoren kan slå sammen tilstøtende felt til én enkelt SSTORE.
Hvis du skriver feltene ett om gangen, kan det utløse flere les–endre–skriv-sykluser på den samme sloten.
Order memory o = orders[id];
o.amount = newAmount;
o.timestamp = uint64(block.timestamp);
orders[id] = o; // single packed write of slot 0Straff ved null til ikke-null
Det koster 20000 gas å initialisere en slot fra null til en verdi som ikke er null, mens det bare koster 5000 gas å oppdatere en slot som allerede har en verdi som ikke er null.
Derfor forhåndsvarmer noen kontrakter slots eller bruker en vaktverdi (for eksempel 1 i stedet for 0) for å holde slots på en verdi som ikke er null. Slik byttes en engangskostnad mot billigere gjentatte oppdateringer.
// Using 1 as 'false' and 2 as 'true' keeps the slot non-zero
uint256 private locked = 1; // never goes back to 0Sjekkliste for gjennomgang av oppsett
Ved gjennomgang av lagring med tanke på gas:
- Gruppér små typer slik at de pakkes i delte slots
- Bruk
constant/immutablefor faste verdier - Mellomlagre gjentatte lagringslesinger i minnet
- Utfør struktur-skrivinger i grupper
- Unngå unødvendige overganger fra null til ikke-null
Kontroller alltid endringene med en gasrapport.
Kort test
Du deklarerer en uint128, deretter en uint256 og så enda en uint128. Hvor mange lagringsslots bruker de?
Oppsummering
Du har lært å optimalisere lagringsoppsettet:
- Lagring består av 32-bytes slots; tilstøtende små typer pakkes sammen
- Deklarasjonsrekkefølgen avgjør pakkingen
constantogimmutableunngår lagring fullstendig- Mellomlagre lesinger og utfør struktur-skrivinger i grupper
- Ta hensyn til kostnaden ved skriving fra null til ikke-null
Deretter ser vi på optimalisering av løkker og håndtering av calldata.
Lær deg Grunnleggende om Web3- og DApp-utvikling med en AI-veileder – gratis
Skriv og kjør ekte kode i nettleseren, få umiddelbar hjelp fra en AI-veileder som er tilgjengelig døgnet rundt, og fortsett der du slapp – på nettet eller i appen.
- Kurs
- 29
- Leksjoner
- 105
Ofte stilte spørsmål
Er leksjonen «Optimalisering av lagring» gratis?
Ja – du kan lese valgfritt 3 av leksjonene i læringsstien Grunnleggende om Web3- og DApp-utvikling, inkludert «Optimalisering av lagring», gratis i sin helhet her på nettet. Deretter låser CoddyKit PRO opp alle leksjoner, samt interaktiv øving med en innebygd kodeeditor og en AI-veileder som er tilgjengelig døgnet rundt. Kurset i Grunnleggende om Web3- og DApp-utvikling inneholder totalt 4 leksjoner.
Hva lærer jeg i «Optimalisering av lagring»?
Pakking og slots Du øver på Grunnleggende om Web3- og DApp-utvikling med praktisk kode som du kjører direkte i nettleseren, mens en AI-veileder som er tilgjengelig døgnet rundt, svarer på spørsmålene dine mens du jobber deg gjennom leksjonen.
Trenger jeg erfaring for å begynne med Grunnleggende om Web3- og DApp-utvikling?
Ingen tidligere erfaring er nødvendig. Grunnleggende om Web3- og DApp-utvikling på CoddyKit er lagt opp for både nybegynnere og viderekomne, så De kan begynne her eller helt fra start og lære i Deres eget tempo. Dette er leksjon 2 av 4.
Hvor lang tid tar leksjonen «Optimalisering av lagring»?
De fleste CoddyKit-leksjoner tar omtrent 5–10 minutter. Hver leksjon er kort og interaktiv, slik at De gjør jevne fremskritt og kan fortsette akkurat der De slapp – både på nettet og i appen.
Kan jeg skrive og kjøre kode i denne Grunnleggende om Web3- og DApp-utvikling-leksjonen?
Ja. Alle Grunnleggende om Web3- og DApp-utvikling-leksjoner har en innebygd kodeeditor, slik at De kan skrive og kjøre ekte kode direkte i nettleseren og få umiddelbar tilbakemelding fra AI – uten lokal konfigurering.
Alle leksjonene i dette kurset
- Gas-kostnadsmodell
- Optimalisering av lagring
- Triks for løkker og calldata
- Måle gas