Starknet har gått fra å være et nisjeprosjekt for zk-rollup-nerder til å bli en av de mest aktive Layer 2-kjedene på Ethereum, med rundt 200-210 millioner dollar i låst verdi ifølge CoinGecko og en DefiLlama-avledet forskningsrapport fra høsten 2026, etter en topp på 323,3 millioner dollar i januar samme år. Det som skiller Starknet fra Arbitrum, Base og zkSync er at hele kjeden kjører på et eget virtuelt maskinvare-miljø kalt Cairo VM, ikke en EVM-klone. Det betyr at du skriver kontrakter i et eget språk, Cairo, og at sikkerhetsfeilene ikke alltid ser ut som de klassiske Solidity-bugsene du kjenner fra Ethereum.
For norske og nordiske utviklere som allerede bygger på Base eller Arbitrum, er spørsmålet ofte om Starknet er verdt den ekstra læringskurven. Svaret avhenger av hva du bygger. Skal du lage enda en standard DeFi-vault, er EVM-kompatibilitet ofte raskere å komme i gang med. Skal du derimot bygge noe beregningstungt, med personvernkrav eller på/av-kjede-logikk som skal bevises effektivt, gir Cairo og STARK-bevis fordeler du ikke får andre steder i Ethereum-økosystemet. Denne artikkelen går gjennom alt fra installasjon av verktøyene til å skrive, teste, deploye og sikre en ekte Cairo-kontrakt på Starknets Sepolia-testnett, med en sjekkliste for når du er klar for mainnet. Du trenger grunnleggende kjennskap til smart-kontrakter og terminalbruk, men du trenger ikke å ha rørt Cairo før. Sett av 60-90 minutter til å følge alle stegene fra start til en verifisert testnett-deploy.
Hva er Starknet, og hvorfor Cairo for smart-kontrakter
Starknet er en valideringsrollup (validity rollup) som bruker STARK-bevis for å samle tusenvis av transaksjoner i én batch og sende et kryptografisk bevis på at alt er korrekt til Ethereum-mainnet. Dette gjør Starknet til det som i fagspråket kalles en Type-4 zk-rollup: den emulerer ikke EVM-bytekode instruksjon for instruksjon, men kjører sin egen virtuelle maskin. Konsekvensen er at du ikke kan ta en Solidity-kontrakt og deploye den rett på Starknet. Du må skrive den i Cairo, et språk StarkWare bygget spesifikt for å generere STARK-bevis effektivt. Starknets egen tekniske dokumentasjon beskriver arkitekturen i detalj, og det er dit du bør gå når denne artikkelen blir utdatert om noen måneder.
Mange utviklere skygger unna Starknet fordi Cairo virker som en ekstra barriere sammenlignet med å deploye rett på Base eller Arbitrum, som begge er EVM-kompatible. Men gevinsten er reell: native kontoabstraksjon fra dag én, lavere teoretisk bevisoverhead for komplekse beregninger, og et bevissystem som ifølge Starknets egen dokumentasjon ikke krever noen “trusted setup”-seremoni, i motsetning til mange SNARK-baserte systemer. For team som bygger noe beregningstungt, som on-chain spill, personvernfunksjoner eller noe som skal tåle fremtidige kvantedatamaskiner bedre, er dette ofte verdt bryet.
Verktøykjeden rundt Cairo har også modnet mye siden de første årene, da det meste måtte skrives mot interne StarkWare-verktøy uten mye dokumentasjon. I dag finnes det et eget pakkesystem (Scarb), et dedikert testrammeverk (Starknet Foundry) og flere aktive lommebøker å velge mellom. Det gjør at tidsbruken for et nytt prosjekt handler mer om å lære selve Cairo-språket og kontoabstraksjonsmodellen enn om å hacke sammen manglende tooling selv, som var situasjonen for noen år tilbake.
Starknets egen årsoppsummering for 2025 peker på at nettverket i løpet av året fikk desentraliserte sekvenserere og at gjennomsnittlig transaksjonsgebyr lå under 0,001 dollar store deler av året. Andre tredjepartsmålinger, som en sammenligning fra Coinbureau, viser høyere gebyr for enkelte transaksjonstyper, opp mot 0,19 dollar for en kompleks overføring, avhengig av datakostnader på Ethereum L1 og nettverksbelastning. Begge tall kan være riktige samtidig, de måler bare forskjellige ting. Poenget for deg som utvikler er at gebyrstrukturen avhenger av hvor mye data kontrakten din skriver til Ethereum, ikke bare hvor “tung” logikken er.
Det er også verdt å kjenne skalaen nettverket opererer på før du planlegger en kontrakt som skal håndtere mye trafikk. En sekundær analyse omtalt i flere 2026-rapporter kobler versjon 0.14.0 til rundt 992 transaksjoner i sekundet og blokktider på 4-6 sekunder, men dette tallet kommer fra en tredjepartsanalyse og ikke fra en offisiell måling, så behandle det som en indikasjon, ikke en garanti du kan bygge en kapasitetsplan på. Hvis prosjektet ditt er avhengig av et konkret gjennomstrømningstall, mål det selv på testnett før lansering.
Forutsetninger: verktøy, versjoner og lommebok du trenger
Før du starter bør du ha et par timer tilgjengelig og en Linux-, macOS- eller WSL-maskin. Starknet-verktøykjeden fungerer dårlig på ren Windows uten WSL. Du trenger ikke forkunnskap i Cairo, men grunnleggende erfaring med Rust-lignende syntaks hjelper, siden Cairo låner mye fra Rust.
| Verktøy | Hva det gjør | Versjon/status (okt. 2026) |
|---|---|---|
| Scarb | Pakkehåndterer og byggesystem for Cairo | Følger Cairo-kompilatoren, sjekk alltid nyeste stabile via Scarb sitt eget oppsettsskript |
| Cairo-kompilator | Kompilerer Cairo-kode til Sierra/CASM | Mainnet støtter kompatibilitetsspekteret 2.0.0–2.18.0 ifølge Starknets kjedeinfo-side |
| Starknet Foundry (snforge/sncast) | Testing og deploy-kommandoer | Aktivt utviklet, hent nyeste release fra det offisielle GitHub-repoet |
| Starknet-protokoll (mainnet) | Selve kjedeprotokollen kontraktene kjører på | v0.14.2, med v0.15 oppgitt på Starknets egen utgivelsesside for september 2026 |
| Starknet OS | Kjerneoperativsystemet for bevisgenerering | 1.7.0 |
| Argent X / Braavos | Lommebok for Starknet-kontoer | Begge er aktivt vedlikeholdte, native Starknet-lommebøker |
Legg merke til at Starknets versjonshistorikk kan være forvirrende fordi protokollversjon, Cairo-versjon og Starknet OS-versjon oppdateres uavhengig av hverandre. Sjekk alltid den offisielle kjedeinfo-siden rett før du deployer noe til mainnet, ikke en guide fra for seks måneder siden, inkludert denne. Du bør også ha en Node.js- eller Python-installasjon liggende, siden flere hjelpeskript i Starknet-økosystemet er skrevet i et av disse to, selv om selve kontraktsutviklingen skjer i Cairo.
Sett av litt tid til å faktisk lese gjennom den offisielle dokumentasjonen før du installerer noe. Starknet-tooling endrer seg fortere enn de fleste Ethereum L2-miljøer, og en installasjonskommando som fungerte for tre måneder siden kan allerede ha blitt byttet ut med en nyere anbefalt metode.
Steg 1-3: Installer Scarb, Starknet Foundry og sett opp testnett-lommebok
Start med å installere Scarb. Dette er verktøyet som bygger og håndterer avhengigheter for Cairo-prosjekter, på samme måte som Cargo gjør for Rust.
curl --proto '=https' --tlsv1.2 -sSf https://docs.swmansion.com/scarb/install.sh | sh
scarb --version
# Installer Starknet Foundry (snforge + sncast)
curl -L https://raw.githubusercontent.com/foundry-rs/starknet-foundry/master/scripts/install.sh | sh
snfoundryup
snforge --version
sncast --version
Når begge verktøyene svarer med et versjonsnummer, er du klar for neste del: en lommebok. Installer Argent X eller Braavos som nettleserutvidelse, opprett en ny konto, og bytt nettverk til Sepolia-testnettet inne i lommeboken. Deretter må du fylle kontoen med testnett-ETH og testnett-STRK via en offentlig kran, siden du trenger gass for å deploye kontoen din selv, før du kan deploye noe annet. Dette er en detalj nybegynnere ofte glemmer: på Starknet er lommebokkontoen din selv en smart-kontrakt som må deployes først, med en egen transaksjon, før den kan sende noe som helst.
Eksporter deretter kontoens adresse og privatnøkkel (kun for testnett, aldri for mainnet-nøkler i klartekst) slik at sncast kan signere transaksjoner på dine vegne fra terminalen. Lagre disse i en lokal profil, ikke hardkodet i skript du senere committer til Git.
Hvis du ikke finner en fungerende kran for testnett-midler i lommeboken din direkte, sjekk den offisielle Starknet-dokumentasjonen for en oppdatert liste over fungerende kraner, siden adressene til disse endrer seg fra tid til annen når gamle kraner tømmes eller legges ned. Be om både ETH og STRK samtidig, siden du får bruk for begge etter hvert, ETH til generelle transaksjonsgebyr og STRK til enkelte protokollspesifikke operasjoner.
Steg 4-5: Opprett prosjektet og skriv din første Cairo-kontrakt
Opprett et nytt Starknet-prosjekt med Scarb sin mal for kontrakter:
scarb new mitt_prosjekt --name mitt_prosjekt
cd mitt_prosjekt
# Legg til Starknet-biblioteket i Scarb.toml
cat >> Scarb.toml << 'EOF'
[dependencies]
starknet = ">=2.0.0"
[[target.starknet-contract]]
EOF
Legg merke til at edition-feltet i Scarb.toml avgjør hvilken Cairo-versjon kompilatoren tolker koden din som. Bruker du en gammel edition mens du kopierer kode fra nyere eksempler, får du ofte kryptiske parse-feil som ikke har noe med den faktiske koden din å gjøre. Hold edition synkronisert med Cairo-versjonen du faktisk har installert, og oppgrader begge samtidig, ikke én i gangen.
Nå skriver vi en enkel, men realistisk kontrakt: en tellekontrakt med en eier og en pause-funksjon, altså mønstrene du faktisk trenger i produksjon, ikke bare en “hello world”.
#[starknet::contract]
mod Teller {
use starknet::ContractAddress;
use starknet::get_caller_address;
#[storage]
struct Storage {
verdi: u128,
eier: ContractAddress,
pause: bool,
}
#[constructor]
fn constructor(ref self: ContractState, eier: ContractAddress) {
self.eier.write(eier);
self.pause.write(false);
}
#[starknet::interface]
trait ITeller {
fn oekn(ref self: TContractState);
fn sett_pause(ref self: TContractState, status: bool);
fn les_verdi(self: @TContractState) -> u128;
}
#[abi(embed_v0)]
impl TellerImpl of ITeller {
fn oekn(ref self: ContractState) {
assert(!self.pause.read(), 'kontrakt er pauset');
let ny_verdi = self.verdi.read() + 1;
self.verdi.write(ny_verdi);
}
fn sett_pause(ref self: ContractState, status: bool) {
let innringer = get_caller_address();
assert(innringer == self.eier.read(), 'kun eier kan pause');
self.pause.write(status);
}
fn les_verdi(self: @ContractState) -> u128 {
self.verdi.read()
}
}
}
Merk access control-mønsteret i sett_pause. Dette er nøyaktig samme type logikk du finner i Solidity-kontrakter med OpenZeppelin sin Ownable, men i Cairo skriver du sjekken selv med get_caller_address(), fordi standardbibliotekene er yngre og mindre standardiserte enn i Ethereum-økosystemet. Det er fristende å hoppe over slike sjekker i en “rask prototype”. Gjør det aldri, selv i en demo-kontrakt du tror ingen andre ser.
Steg 6: Native kontoabstraksjon, hvordan Starknet-kontoer faktisk fungerer
Den viktigste arkitektoniske forskjellen fra Ethereum ligger her, og den påvirker direkte hvordan du bør tenke sikkerhet. På Ethereum er en vanlig brukerkonto (EOA) en enkel nøkkelpar-konstruksjon utenfor kontraktslaget. På Starknet er hver konto, inkludert din egen lommebok, en smart-kontrakt. Det betyr at valideringslogikken for en transaksjon, altså hvordan nettverket avgjør om en signatur er gyldig, er programmerbar kode du eller lommebokleverandøren din har skrevet.
I desember 2025 rullet Starknet ut versjon 0.14.1, som ifølge den offisielle versjonsloggen innførte en separasjon mellom validate og execute i kontoabstraksjonsmodellen. Praktisk betyr dette at nettverket nå kan avvise en transaksjon tidligere i valideringsfasen uten å kjøre hele utførelsen, noe som gjør det vanskeligere å bruke mempool-spam eller validerings-triks som angrepsvektor mot sekvenseren. For deg som utvikler betyr det at en kontrakt med egendefinert multisig- eller sosial gjenopprettingslogikk kan skille tydeligere mellom “er denne signaturen gyldig” og “skal denne handlingen faktisk utføres”, noe som gjør det enklere å bygge sikre gjenopprettingsmekanismer uten ekstra mellomlag.
Sosial gjenoppretting er et godt eksempel på hvorfor dette er mer enn en teoretisk fordel. På en vanlig Ethereum-EOA er det ingen innebygd måte å gjenopprette tilgang hvis du mister nøkkelen, med mindre lommeboken din allerede er en smart-kontraktskonto bygget med en standard som ERC-4337. På Starknet er gjenopprettingslogikk en naturlig del av kontokontrakten fra start, så et prosjekt kan designe for at tre av fem forhåndsgodkjente adresser kan godkjenne et nøkkelbytte, uten å måtte migrere til en helt annen kontotype senere.
Konsekvensen for sikkerheten din: du kan ikke anta at “transaksjonen kom fra en gyldig signatur” betyr det samme som på Ethereum. Du må eksplisitt teste kontoens valideringslogikk, ikke bare forretningslogikken i kontrakten din.
Dette åpner også for funksjoner mange Ethereum-utviklere må hente fra eksterne standarder, som ERC-4337 på andre kjeder, men som er innebygd fra protokollnivå på Starknet. Sesjonsnøkler, der en app får lov til å signere et begrenset sett handlinger i en avgrenset periode uten at brukeren må godkjenne hver transaksjon manuelt, er et naturlig eksempel. Fordi valideringslogikken er kode du selv kontrollerer i kontokontrakten, kan du bygge inn slike begrensninger direkte, uten en separat relayer-arkitektur. Det samme gjelder paymaster-funksjonalitet, der en tredjepart kan sponse gasskostnaden for en bruker, noe vi kommer tilbake til i avsnittet om avanserte tips.
Steg 7-8: Kompiler og test kontrakten med Starknet Foundry
Kompiler kontrakten med Scarb:
scarb build
# Output: target/dev/mitt_prosjekt_Teller.contract_class.json
Skriv deretter en test med snforge som faktisk prøver å bryte access control-sjekken, ikke bare en test som bekrefter at “happy path” virker:
#[test]
fn test_kun_eier_kan_pause() {
let eier: ContractAddress = 123.try_into().unwrap();
let angriper: ContractAddress = 456.try_into().unwrap();
let contract = declare("Teller").unwrap().contract_class();
let (adresse, _) = contract.deploy(@array![eier.into()]).unwrap();
let dispatcher = ITellerDispatcher { contract_address: adresse };
start_cheat_caller_address(adresse, angriper);
let resultat = dispatcher.sett_pause(true);
// Forventer panic/avbrudd fordi angriper ikke er eier
}
Kjør testsettet:
snforge test
# Forventet output:
# Collected 2 test(s) from mitt_prosjekt package
# Running 2 test(s) from src/
# [PASS] mitt_prosjekt::tests::test_oekn (gas: ~1200)
# [PASS] mitt_prosjekt::tests::test_kun_eier_kan_pause (gas: ~900)
# Tests: 2 passed, 0 failed, 0 ignored
Legg merke til at snforge rapporterer gassestimat per test. Bruk dette aktivt: hvis en funksjon plutselig bruker dobbelt så mye gass etter en endring, er det ofte et tegn på en util-loop eller unødvendig storage-lesing du har introdusert, ikke bare “normal variasjon”.
Merk også cheat-funksjonen start_cheat_caller_address i testen over. Dette er en funksjon snforge gir deg nettopp for å simulere at en annen adresse enn standard-testkontoen kaller funksjonen, uten å måtte sette opp en ekte andre lommebok bare for testing. Starknet Foundry har flere slike cheat-funksjoner, blant annet for å manipulere blokktidsstempel og blokknummer, noe som er nyttig når du tester tidslåser som den vi bygger i multisig-eksemplet senere i artikkelen. Skriv alltid minst én test som later som den er en angriper, ikke bare tester som bekrefter normal bruk.
Steg 9-10: Deploy til Sepolia-testnett og verifiser med sncast
Først deklarerer du kontraktsklassen på kjeden, deretter deployer du en instans av den. Dette er to separate transaksjoner på Starknet, i motsetning til Ethereum hvor deploy er én transaksjon. Grunnen til at Starknet gjør det på denne måten er at mange kontrakter i praksis deler samme kode, som standard token-implementasjoner eller fabrikk-mønstre, og da er det sløsing med gass å betale for å laste opp identisk bytekode på nytt for hver eneste instans.
# Deklarer kontraktsklassen
sncast --profile sepolia declare \
--contract-name Teller
# Output gir deg en class_hash, f.eks:
# class_hash: 0x02a8...e91f
# Deploy en instans med konstruktørargument (din eier-adresse)
sncast --profile sepolia deploy \
--class-hash 0x02a8...e91f \
--constructor-calldata 0xDIN_EIER_ADRESSE
# Output gir deg contract_address, f.eks:
# contract_address: 0x05c3...1b22
Verifiser at kontrakten faktisk ligger der du tror ved å lese av en view-funksjon direkte fra terminalen, uten å gå via lommeboken:
sncast --profile sepolia call \
--contract-address 0x05c3...1b22 \
--function les_verdi
# Output: [0x0] (verdi = 0, som forventet rett etter deploy)
Sjekk til slutt adressen i en blokkutforsker for Starknet Sepolia, og bekreft at class_hash matcher det du fikk fra declare-kommandoen. Dette tar 30 sekunder og fanger opp feil deploy-script langt oftere enn du tror.
Et detaljspørsmål som ofte dukker opp her er hvilket token du skal betale gass med. Starknet støtter betaling i både ETH og det native STRK-tokenet, og sncast lar deg velge dette eksplisitt med et fee-token-flagg i deploy-kommandoen. Hvis du tester med lite midler, er det verdt å sjekke saldoen i begge tokenene før du sender en transaksjon, siden en feilmelding om “insufficient funds” ofte egentlig betyr at du har nok ETH men null STRK, eller omvendt. Sett også en realistisk max fee, ikke den aller laveste sncast foreslår, siden en for lav verdi kan gjøre at sekvenseren lar transaksjonen stå ubehandlet i stedet for å avvise den tydelig.
Steg 11: Sikre kontrakten mot vanlige Cairo-sårbarheter
Cairo fjerner noen klassiske Solidity-feilklasser helt. Heltallsoverflow er for eksempel standard beskyttet i Cairo sine typer, i motsetning til gamle Solidity-versjoner uten SafeMath, siden en overflow i en u128 eller u256 i Cairo gir en panic i stedet for å stille wrappe rundt til null. Men Cairo introduserer egne fallgruver du må kjenne til, delvis fordi språket og standardbiblioteket er yngre og mindre gjennomtestet i produksjon enn Solidity-økosystemet.
Den første er feil bruk av felt252 som tallerstatning. Dette er Cairos native feltelement, men det er ikke et vanlig heltall, det “wrapper” rundt et primtall som er mye større enn 2^128. Hvis du bruker felt252 til beløp uten å validere grenser selv, kan en bruker konstruere verdier som gir uventet oppførsel i sammenligninger. Bruk u128 eller u256 for beløp og tellere, ikke rå felt252, med mindre du faktisk trenger feltaritmetikk.
Den andre er reentrancy via eksterne kall i storage-oppdateringer. Selv om Cairos utførelsesmodell er annerledes enn EVM, kan et eksternt kall til en annen kontrakt fortsatt gi kontroll til kode du ikke eier før din egen storage er oppdatert. Mønsteret er identisk med Ethereum: oppdater storage før du gjør eksterne kall (checks-effects-interactions), ikke etter.
// FEIL: ekstern kall før storage-oppdatering
fn trekk_ut(ref self: ContractState, belop: u128) {
let ekstern = IAnnenKontraktDispatcher { contract_address: self.mal.read() };
ekstern.varsle(belop); // kan kalle tilbake inn
self.saldo.write(self.saldo.read() - belop);
}
// RIKTIG: storage oppdateres først
fn trekk_ut_sikker(ref self: ContractState, belop: u128) {
let ny_saldo = self.saldo.read() - belop;
self.saldo.write(ny_saldo);
let ekstern = IAnnenKontraktDispatcher { contract_address: self.mal.read() };
ekstern.varsle(belop);
}
Den tredje fallgruven er å stole blindt på kontoabstraksjon for autorisasjon. Fordi hver konto er en kontrakt, er det fristende å tenke at “kallet kommer fra en kontrakt, så det er trygt validert”. Det er feil. Valider alltid eksplisitt hvem som kaller en sensitiv funksjon i din egen kontrakt, slik vi gjorde med eier-sjekken i tellekontrakten over, uavhengig av hva lommebokkontrakten til den som kaller allerede har validert.
En fjerde fallgruve som er lettere å overse: feilhåndtering ved typekonvertering. Når du konverterer mellom felt252 og mindre typer som u128 med try_into(), returnerer Cairo en Option som kan være None hvis verdien er for stor. Bruker du unwrap() blindt på denne konverteringen uten å håndtere feilen, krasjer hele transaksjonen på en måte som kan være vanskelig å feilsøke for brukeren din, i stedet for å gi en tydelig feilmelding. Håndter konverteringsfeil eksplisitt med match der det er mulig, spesielt på input som kommer direkte fra en bruker.
Steg 12: Multisig, tidslås og sjekkliste før mainnet
Før du flytter noe verdifullt til mainnet, bør administrative funksjoner som oppgraderinger og pause-knapper ligge bak mer enn én signatur. Fordi Starknet-kontoer uansett er kontrakter med programmerbar valideringslogikk, kan du bygge en enkel N-av-M-multisig som eier-adressen i stedet for en enkelt lommebok.
fn sett_pause(ref self: ContractState, status: bool) {
let innringer = get_caller_address();
assert(innringer == self.multisig_konto.read(), 'kun multisig kan pause');
self.pause.write(status);
}
fn forsla_oppgradering(ref self: ContractState, ny_class_hash: felt252) {
let innringer = get_caller_address();
assert(innringer == self.multisig_konto.read(), 'kun multisig kan foreslaa');
let utloep = get_block_timestamp() + 172800; // 48 timers tidslås
self.ventende_oppgradering.write((ny_class_hash, utloep));
}
Sjekklisten før mainnet bør minst inneholde: kjør hele testsuiten med snforge og se at gassforbruket er stabilt mellom kjøringer, kjør en ekstern eller intern revisjon av koden, bekreft at admin-funksjoner krever multisig og tidslås, bekreft at du har testet kontrakten mot feil input og ikke bare mot gyldige input, og dobbeltsjekk at class_hash du deployer på mainnet er bygget fra nøyaktig samme kildekode som ble testet, ikke en lokal variant med “en liten fiks” du glemte å teste på nytt.
Mange prosjekter velger også å sette opp et bug bounty-program før eller samtidig med mainnet-lansering, slik at eksterne sikkerhetsforskere har et insentiv til å rapportere feil til deg i stedet for å utnytte dem. Dette er ikke en erstatning for en revisjon, men et supplement som fanger opp feil revisorer kan ha oversett, spesielt i kode som endres etter at revisjonen er levert. Hvis du gjør endringer i kontrakten etter revisjonen, uansett hvor små, bør den endrede delen revideres på nytt før mainnet-deploy.
STARK mot SNARK: hvorfor bevissystemet påvirker sikkerheten din
Navnet Starknet kommer direkte fra bevissystemet: STARK, forkortelse for “Scalable Transparent Argument of Knowledge”. Det “transparente” er det viktige ordet her. STARK-bevis er basert på hash-funksjoner og krever ingen trusted setup-seremoni, altså ingen hemmelig matematisk “oppstart” som noen må generere og deretter garantert destruere. Mange SNARK-konstruksjoner krever nettopp en slik seremoni, og hvis den noen gang kompromitteres, kan hele systemets sikkerhetsgaranti rakne.
| Egenskap | STARK (Starknet) | Typisk SNARK-konstruksjon |
|---|---|---|
| Trusted setup | Ikke nødvendig | Ofte nødvendig, avhenger av konkret konstruksjon |
| Kryptografisk antakelse | Hash-basert (kollisjonsresistens) | Ofte elliptisk kurve-basert |
| Bevisstørrelse | Generelt større | Generelt mindre i mange konstruksjoner |
| Forhold til kvanteresistens | Starknets blogg peker på hash-baserte bevis som et praktisk spor mot kvanteresistens | Avhenger av underliggende kurve, mange er ikke kvanteresistente |
Dette er ikke bare teori. Starknets egen blogg beskriver hvordan v0.14.2, som gikk live i mars 2026, innførte native in-protokoll bevisverifisering, en forutsetning StarkWare selv peker på som nødvendig infrastruktur for krypterte STRK20-saldoer og private strkBTC-DeFi-funksjoner. Med andre ord: valget av bevissystem er ikke bare en teknisk detalj for protokollteamet, det åpner konkrete personvernfunksjoner du som utvikler kan bygge videre på.
Den praktiske konsekvensen for deg som skriver kontrakter i dag er mindre dramatisk enn den kan høres ut: du trenger ikke forstå bevissystemet på et matematisk nivå for å deploye en trygg kontrakt. Men du bør vite at bevisgenereringen skjer utenfor kjeden, hos en prover, før beviset sendes til Ethereum for verifisering. Hvis kontrakten din gjør noe uvanlig tungt, som store looper over store datastrukturer, kan det påvirke hvor lang tid det tar før transaksjonen din faktisk er bekreftet med et gyldig bevis, ikke bare hvor mye gass den koster.
Vanlige fallgruver ved Starknet-utvikling
- Å behandle felt252 som et vanlig heltall. Det wrapper rundt et stort primtall. Bruk u128/u256 til beløp, ikke rå felt252, med mindre du faktisk trenger feltaritmetikk. Denne forvekslingen er spesielt lett å gjøre for utviklere som kommer rett fra Solidity, hvor uint256 er standardvalget for nesten alt.
- Å glemme at kontoen din selv må deployes først. Nye brukere som ikke har sendt en eneste transaksjon før, mangler en deployet kontokontrakt, og den første transaksjonen deres må derfor betale for både kontodeploy og selve handlingen. Hvis appen din bygger en onboarding-flyt, bør du vise brukeren at dette steget tar litt lengre tid og koster litt mer enn senere transaksjoner.
- Å stole på caller-adresse uten å validere videre. Fordi alle kontoer er kontrakter, er det fristende å tro «kallet er allerede validert». Valider alltid eksplisitt i din egen kontrakt, uavhengig av hvor «pålitelig» avsenderkontrakten virker.
- Å blande sammen class_hash og contract_address. class_hash identifiserer koden, contract_address identifiserer en konkret deployert instans. Å deklarere feil versjon og deploye mot feil hash er en vanlig feilkilde i CI-pipeliner, spesielt når flere utviklere deployer til samme testnett samtidig.
- Å hardkode testnett-nøkler i skript som committes. Selv testnett-nøkler bør ligge i miljøvariabler eller en lokal sncast-profil, ikke i et skript som ender opp i et offentlig Git-repo. Vanen med å være slepphendt på testnett er ofte det som forårsaker den virkelig kostbare feilen den dagen du jobber med mainnet-nøkler.
- Å anta at gassforbruk er statisk mellom kjøringer. Fordi deler av kostnaden avhenger av datapubliseringskostnad på Ethereum L1, kan samme kontraktskall koste ulikt fra uke til uke. Bygg derfor inn en gassmargin i grensesnittet ditt i stedet for å vise brukeren et fast, hardkodet gebyr.
Feilsøking: 8 vanlige problemer og løsninger
De fleste feilene du møter i starten faller i tre kategorier: kontoen din er ikke i den tilstanden verktøyet forventer, verktøyversjonene matcher ikke hverandre, eller du blander sammen de to transaksjonstypene declare og deploy. Tabellen under dekker de åtte problemene vi ser oftest hos utviklere som er nye på Starknet.
| Problem | Sannsynlig årsak | Løsning |
|---|---|---|
| “Account not deployed” ved første transaksjon | Lommebokkontoen din er aldri deployet på kjeden | Send en liten transaksjon for å trigge kontodeploy, eller kjør eksplisitt account deploy med sncast |
| scarb build feiler med versjonskonflikt | Scarb.toml peker på en Cairo-versjon utenfor kompatibilitetsvinduet for mainnet | Sjekk kjedeinfo-siden for gyldig versjonsspekter og juster edition/versjon i Scarb.toml |
| snforge test hopper over tester stille | Testfunksjonen mangler #[test]-attributtet eller feil modulnavn | Kjør med –exact for å se nøyaktig hvilke tester som faktisk kjøres |
| declare feiler med “class already declared” | Samme kode er allerede deklarert på kjeden fra før | Hopp over declare og gå rett til deploy med eksisterende class_hash |
| deploy feiler med “insufficient funds” | Kontoen mangler STRK eller ETH til gass på valgt nettverk | Fyll opp via testnett-kran for Sepolia, eller bekreft saldo på mainnet før forsøk |
| call-funksjon returnerer uventet verdi | Feil kontraktsadresse eller feil funksjonssignatur i ABI | Sammenlign ABI fra target/dev-mappen mot kallet, og dobbeltsjekk adressen i blokkutforskeren |
| Transaksjon sitter fast i “pending” | Sekvenseren har ikke inkludert transaksjonen, ofte pga. for lav max fee | Øk max fee-parameteren i sncast-kallet og send på nytt |
| Multisig-funksjon avviser gyldig signatur | Valideringslogikken skiller ikke riktig mellom validate og execute | Test valideringsfunksjonen isolert med snforge før den kobles til execute-logikken |
| “Transaction reverted” uten tydelig årsak | En assert-sjekk lenger ned i kallkjeden feiler uten beskrivende feiltekst | Legg kortfattede, unike feiltekster på alle assert-setninger slik at feilsøking i loggen blir mulig |
Hvis du står fast på et problem som ikke er i listen, er det neste steget å kjøre kommandoen med økt loggnivå (verbose-flagget på de fleste sncast- og snforge-kommandoer) og lese den rå feilmeldingen fra noden, ikke bare sammendraget verktøyet viser i terminalen. Mange Cairo-feil som ser kryptiske ut ved første blikk, peker faktisk rett på linjenummeret når du ser den fulle stacktracen.
Avanserte tips og komplett prosjektstruktur
Når grunnmuren står, er det fire ting som skiller en hobbyprosjekt-kontrakt fra en som tåler produksjon. Først, batch flere operasjoner i ett multicall der det går, siden hver transaksjon betaler en fast overhead i tillegg til den variable kostnaden, og færre transaksjoner betyr lavere total gasskostnad for brukeren. Deretter, se på paymaster-mønstre hvis du vil la brukere betale gass i et annet token enn STRK eller ETH, siden kontoabstraksjon gjør dette langt enklere å implementere nativt enn på Ethereum. For tredje, hold storage-strukturen flat der du kan. Nestede strukturer i Cairo-storage koster mer å lese og skrive enn enkle felt, og det merkes raskt i gassestimatene fra snforge.
Det fjerde punktet er overvåking etter lansering. En kontrakt som er trygg ved deploy kan fortsatt bli utsatt for uventet bruk måneder senere, spesielt hvis den samhandler med andre protokoller som selv endrer seg. Sett opp en enkel indekserer eller abonner på kontraktens events fra en blokkutforsker-API, slik at du får varsel hvis en adresse plutselig kaller admin-funksjoner, eller hvis en tellervariabel beveger seg langt utenfor normalt mønster. Dette er den samme logikken som ligger bak sanntidsovervåking av DeFi-protokoller generelt, bare tilpasset din egen kontrakt i mindre skala.
En komplett, fungerende prosjektstruktur du kan bruke som utgangspunkt ser slik ut:
mitt_prosjekt/
├── Scarb.toml # avhengigheter og target-konfig
├── src/
│ ├── lib.cairo # eksporterer modulene
│ ├── teller.cairo # kontraktslogikk med access control
│ └── interfaces.cairo # ITeller-traiten
├── tests/
│ ├── test_teller.cairo # happy-path tester
│ └── test_sikkerhet.cairo # angreps-/edge case-tester
└── scripts/
└── deploy_sepolia.sh # sncast declare + deploy i ett skript
Legg deploy-logikken i et eget skript i stedet for å kjøre kommandoene manuelt hver gang. Det tvinger deg til å dokumentere nøyaktig hvilke konstruktørargumenter og hvilken profil som ble brukt, noe som er gull verdt den dagen du må reprodusere en mainnet-deploy seks måneder senere.
Verktøylandskapet rundt Starknet er fortsatt i rask bevegelse, og det er lett å installere feil versjon av Scarb eller Starknet Foundry hvis du følger en gammel artikkel (inkludert eldre versjoner av denne). Bruk alltid snfoundryup for å oppdatere Starknet Foundry til siste anbefalte versjon, og sjekk den offisielle dokumentasjonen for Starknet Foundry hvis en kommando i denne guiden ikke lenger matcher syntaksen i din installerte versjon. CLI-flagg endrer seg oftere enn selve Cairo-språket.
Til slutt: bygg gjerne et andre testprosjekt der du bevisst introduserer en av fallgruvene fra listen over, for eksempel en reentrancy-sårbarhet, og skriv en test som beviser at angrepet fungerer før du fikser det. Denne øvelsen, å bevise at et angrep virker før du patcher det, lærer deg mer om Cairo-sikkerhet enn å bare lese om mønstrene.
Ofte stilte spørsmål om Starknet-smartkontrakter
Må jeg lære Cairo fra scratch, eller kan jeg bruke Solidity-kunnskapen min?
Du må lære Cairo-syntaks, men mange av sikkerhetsmønstrene, som checks-effects-interactions og access control, overføres direkte fra Solidity-erfaring. Syntaksen ligner mer på Rust enn Solidity, med eksplisitte typer, pattern matching og et strengt eierskapssystem for data, så utviklere med Rust-bakgrunn kommer seg ofte raskere i gang enn rene Solidity-utviklere.
Hvor lang tid tar det å deploye en kontrakt til Sepolia-testnettet?
Selve declare- og deploy-transaksjonene bekreftes normalt innen noen minutter på testnett. Det som tar tid er å sette opp verktøyene første gang og fylle lommeboken med testnett-midler fra en kran.
Er Starknet billigere enn Arbitrum eller Base for en typisk kontrakt?
Det varierer med transaksjonstype og datamengde som skrives til Ethereum. Starknets egen 2025-oppsummering rapporterer gjennomsnittsgebyr under 0,001 dollar store deler av året, mens uavhengige sammenligninger viser høyere tall for enkelte transaksjonstyper. Test alltid gasskostnaden for din spesifikke kontrakt før du sammenligner kjeder.
Hva skjer med kontrakten min hvis Starknet oppgraderer protokollen, som fra v0.14.2 til v0.15?
Protokolloppgraderinger er designet for å være bakoverkompatible med eksisterende kontrakter i de fleste tilfeller, men du bør alltid lese versjonsnotatene på Starknets dokumentasjonsside før en stor oppgradering, spesielt hvis kontrakten din bruker avanserte kontoabstraksjonsfunksjoner.
Trenger jeg en revisjon selv for en liten kontrakt?
Hvis kontrakten håndterer noe av økonomisk verdi, ja. Cairo er yngre enn Solidity og har færre etablerte revisjonsfirmaer og mindre standardiserte biblioteker, noe som gjør egen testing med snforge, inkludert angrepsscenarioer, enda viktigere før lansering. En liten kontrakt uten økonomisk verdi, som en ren demo eller et internt verktøy, kan ofte klare seg med grundig egentesting og en manuell kodegjennomgang fra en kollega i stedet for en full ekstern revisjon.
Kan jeg bruke samme lommebok-seed-frase på Starknet som på Ethereum?
Argent X og Braavos støtter egne kontomodeller tilpasset Starknets kontoabstraksjon, og nøkkelderiveringen skiller seg fra en standard Ethereum-lommebok. Følg veiledningen i den spesifikke lommeboken din i stedet for å anta samme oppsett som på Ethereum.
Hvorfor er det to transaksjoner (declare og deploy) i stedet for én?
Starknet skiller kontraktskode (class_hash) fra konkrete instanser (contract_address) slik at flere kontrakter kan dele samme deklarerte kode uten å betale full deploy-kostnad for koden på nytt hver gang. Det sparer gass for alle som deployer en ny instans av en allerede kjent kontraktstype.
Kan jeg oppgradere en Starknet-kontrakt etter at den er deployet?
Ja, hvis du har bygget inn en oppgraderingsmekanisme som bytter class_hash kontrakten peker på, slik vi skisserte i multisig-eksempelet med tidslås. Uten en slik mekanisme innebygd fra start er en deployet kontraktsinstans permanent låst til den opprinnelige koden, akkurat som på Ethereum uten et proxy-mønster.




