Base, Coinbase sin lag-2-kjede bygget på OP Stack, passerte i september 2026 rundt 6,27 milliarder dollar i DeFi-verdi ifølge tall fra DefiLlama gjengitt av CoinGabbar, noe som utgjorde 6,57 prosent av all offentlig kjedet DeFi-verdi den uken. Det gjør Base til en av de tre største kjedene målt i innlåst kapital, rett bak Ethereum og Solana. For norske og nordiske utviklere som allerede jobber med Solidity, er spørsmålet ikke lenger om Base er relevant, men hvordan man deployer og sikrer en kontrakt der uten å gjenta feilene andre lag-2-prosjekter har gjort. Denne guiden tar deg fra tom mappe til verifisert, sikret kontrakt på Base mainnet i tolv konkrete steg.
Du trenger ingen tidligere erfaring med OP Stack for å følge med, men du bør kunne litt Solidity og ha brukt et kommandolinjeverktøy før. Vi bruker Foundry gjennom hele guiden fordi det er raskest å teste og deploye med, og fordi Slither og andre analyseverktøy fungerer godt sammen med det. Målet er ikke bare å få en kontrakt live på kjeden, men å forstå hvorfor hvert steg finnes, slik at du kan tilpasse mønsteret til dine egne prosjekter senere.
Guiden skiller seg fra generelle Solidity-tutorials ved at den går inn på det som faktisk er spesifikt for Base: syv-dagers uttaksvinduet, forskjellen mellom native og brodd USDC, og hvordan en enkelt Coinbase-drevet sekvenser påvirker designvalgene dine. Disse detaljene er lette å overse hvis du bare kopierer et Ethereum-mainnet-oppsett rett inn på en lag-2-kjede.
Hva er Base, og hvorfor bør norske utviklere bry seg nå
Base er en OP Stack-basert lag-2-kjede lansert av Coinbase. Den arver sikkerheten sin fra Ethereum gjennom det som kalles optimistiske rollups: transaksjoner behandles raskt på Base, mens den endelige tilstanden regelmessig postes til Ethereum for endelig avgjørelse. Ifølge en teknisk gjennomgang fra HBM & Company produserer Base nye blokker omtrent hvert andre sekund, og nettverkets Flashblocks-funksjon gir forhåndsbekreftelser på rundt 200 millisekunder. Merk at en forhåndsbekreftelse ikke er det samme som endelig oppgjør mot Ethereum.
Sammenlignet med andre lag-2-kjeder ligger Base litt bak i ren transaksjonshastighet. CryptoSlate viste til L2Beat-tall som satte Base sin gjennomsnittlige TPS til 3,11, mens Arbitrum og Optimism ligger over 7 TPS. Til gjengjeld har Base bygget en enorm brukerbase raskt: BaseScan registrerte 1,88 millioner transaksjoner på en enkelt dag i september 2025, ifølge Forklog. Kombinasjonen av lav gjennomstrømning per sekund, men høy total aktivitet, forteller noe viktig: mesteparten av trafikken på Base er enkle overføringer og swaps, ikke tunge beregninger. Det påvirker hvordan du bør designe kontraktene dine, spesielt rundt gasskostnader knyttet til data som postes til Ethereum. Hvis kontrakten din er avhengig av høy gjennomstrømning for komplekse beregninger, som avansert on-chain matching eller tunge kryptografiske operasjoner, bør du teste ytelsen under realistisk last på testnettet før du legger designbeslutninger som er vanskelige å endre senere.
Den viktigste forskjellen fra å bygge direkte på Ethereum er tillitsmodellen. Base har foreløpig én sekvenser, drevet av Coinbase, som ifølge Zealynx sin sikkerhetsgjennomgang ordner transaksjoner etter innsendingstidspunkt snarere enn gasspris. Sekvenseren kan ikke stjele midler direkte, men den har i praksis makt over rekkefølge og kan sensurere enkelttransaksjoner midlertidig. Base sin egen utviklingsblogg beskriver en plan for 2026 til 2027 der målet er å fjerne sikkerhetsrådets nødbryter og bevege seg mot det OP Stack kaller “Stage 2”-desentralisering. En delt sekvenser er under testing på devnett per midten av 2026, men ikke i produksjon ennå. Dette er relevant for deg som utvikler fordi tillitsantagelsene dine i dag ikke nødvendigvis er de samme om ett eller to år: en kontrakt designet med forutsetning om at “sekvenseren er alltid tilgjengelig og aldri sensurerer” bør uansett bygges robust nok til å tåle at den forutsetningen svikter midlertidig, uavhengig av hvor langt desentraliseringen har kommet når du leser dette. Du bør bygge kontraktene dine som om sekvenseren kan forsinke deg, ikke som om den er nøytral infrastruktur for alltid.
Gasskostnaden på Base består av to deler: selve utførelsen på L2, som er svært billig, og en L1-databit som dekker kostnaden ved å poste komprimerte transaksjonsdata til Ethereum. Zealynx sin tekniske gjennomgang av Base sin gebyrmodell peker på at L1-databiten ofte er den dominerende kostnaden i en typisk transaksjon, ikke selve beregningen. Det betyr at en kontrakt som skriver mye data til lagring, for eksempel lange strenger eller store arrays, kan bli overraskende dyr å bruke selv om den kjører på en lag-2-kjede, rett og slett fordi mer data må postes til L1. Design kontraktene dine med dette i bakhodet: pakk data kompakt, og unngå å lagre mer på kjeden enn det som faktisk trengs for at logikken skal fungere korrekt.
Base sammenlignet med Arbitrum og zkSync Era
Før du bestemmer deg for Base, er det verdt å vite hvordan det faktisk skiller seg fra de to andre store lag-2-alternativene på Ethereum. Alle tre er EVM-kompatible og lar deg bruke samme Solidity-kode, men sikkerhetsmodellen og ventetiden ved uttak varierer betydelig. Dette er ikke en rangering der én kjede vinner på alle punkter, men en oversikt over hvilke avveininger du faktisk gjør ved å velge den ene fremfor den andre.
| Egenskap | Base | Arbitrum | zkSync Era |
|---|---|---|---|
| Rollup-type | Optimistisk (OP Stack) | Optimistisk (Nitro) | Zero-knowledge (zk-rollup) |
| Sikkerhetsmekanisme | Permissionless feilbevis (Cannon) | Interaktive feilbevis | Gyldighetsbevis (kryptografisk) |
| Uttaksventetid til Ethereum | 7 dager (standard bro) | Ca. 7 dager (standard bro) | Ingen utfordringsperiode, raskere finalitet |
| Sekvenser-modell | Én sentral, Coinbase-drevet | Én sentral, Offchain Labs-drevet | Én sentral, Matter Labs-drevet |
| Gjennomsnittlig TPS (L2Beat/CryptoSlate) | 3,11 | Over 7 | Varierer med batch-størrelse |
| Utvikleroppsett | Foundry eller Hardhat, standard EVM-verktøy | Foundry eller Hardhat, standard EVM-verktøy | Krever ofte zkSync-spesifikk kompilator (zksolc) |
Den mest praktiske forskjellen for deg som utvikler er kompatibilitet. Fordi Base og Arbitrum begge er optimistiske rollups med standard EVM-bytekode, kan du som regel deploye nøyaktig samme kompilerte kontrakt på begge uten endringer. zkSync Era krever derimot ofte en egen kompilator tilpasset zk-kretsen, noe som betyr at verktøykjeden din må tilpasses spesifikt for den kjeden. Hvis prosjektet ditt skal kjøre på flere lag-2-kjeder samtidig, er det en reell grunn til at mange team starter med Base eller Arbitrum og vurderer zkSync Era som et eget løp senere, snarere enn som en direkte erstatning.
Velg Base spesifikt hvis brukerne dine allerede har en Coinbase-konto, siden det direkte uttaket uten smartkontraktbro senker terskelen for ikke-tekniske brukere betraktelig. Velg Arbitrum hvis du trenger den bredeste eksisterende DeFi-likviditeten og flest ferdigbygde integrasjoner å bygge videre på. Velg zkSync Era hvis rask, kryptografisk endelig avgjørelse uten en flerdagers ventetid er viktigere for produktet ditt enn bred verktøykompatibilitet. Ingen av valgene er permanente: fordi kontraktkoden i stor grad er gjenbrukbar mellom Base og Arbitrum, er kostnaden ved å støtte begge samtidig lavere enn mange team antar før de har prøvd det.
Forutsetninger: verktøy, versjoner og kontoer du trenger
Før du starter, sett av rundt 60 minutter og sørg for at følgende er på plass. Vi unngår å oppgi eksakte versjonsnumre der de endrer seg ofte, siden det viktigste er at du installerer nyeste stabile utgave rett før du starter, ikke en versjon som allerede er utdatert når du leser dette.
| Verktøy | Versjon | Formål |
|---|---|---|
| Foundry (forge, cast, anvil) | Nyeste stabile, installert via foundryup | Kompilering, testing, deploy |
| Solidity-kompilator | 0.8.x-serien | Skrive og kompilere kontrakten |
| OpenZeppelin Contracts | Nyeste 5.x-utgave | ReentrancyGuard, Ownable, ERC-20-basiskode |
| Slither (Trail of Bits) | Nyeste utgave via pip | Statisk sikkerhetsanalyse |
| Nettleserlommebok (MetaMask/Coinbase Wallet) | Nyeste utgave | Signere transaksjoner, teste bro |
| Node.js | LTS-versjon | Kjøre eventuelle hjelpeskript |
Du trenger også en lommebok med en liten mengde ekte ETH på Ethereum mainnet hvis du skal bygge videre til produksjon, pluss tilgang til en Base-kompatibel RPC-leverandør. Base sin offisielle dokumentasjon lister opp flere måter å bro eiendeler mellom Ethereum og Base, inkludert direkte uttak fra en Coinbase-konto uten å bruke smartkontraktbroen i det hele tatt.
Steg 1: Sett opp lommebok for Base
Åpne lommeboken din og legg til Base Sepolia som testnettverk, og Base mainnet som produksjonsnettverk. De fleste moderne lommebøker legger til Base automatisk siden det er et av de mest brukte lag-2-nettverkene, men sjekk alltid at kjede-ID-en stemmer med det Base sin offisielle dokumentasjon oppgir før du signerer noe. En feil kjede-ID er en klassisk måte phishing-sider lurer utviklere til å signere transaksjoner på feil nettverk.
Opprett en dedikert utviklerlommebok for dette prosjektet, atskilt fra lommeboken din med reelle midler. Privatnøkkelen til denne testlommeboken kommer til å havne i miljøvariabler og skript underveis, og du vil ikke risikere at en feilkonfigurert fil lekker nøkkelen til en konto med reell verdi.
Skriv ned kjede-ID-en for begge nettverkene et sted du enkelt kan sjekke den opp mot: Base mainnet og Base Sepolia bruker ulike ID-er, og de fleste feilsendte transaksjoner i denne fasen skyldes at en lommebok var koblet til feil nettverk uten at brukeren la merke til det før etter signering.
Steg 2: Hent testnett-ETH fra en faucet
Base Sepolia krever testnett-ETH for å betale gass. Du kan hente dette gratis fra en Ethereum Sepolia-faucet og deretter bro det videre til Base Sepolia, eller bruke en faucet som støtter Base Sepolia direkte. Bekreft saldoen din med en enkel kommando før du går videre:
cast balance DIN_ADRESSE --rpc-url https://sepolia.base.org
Du trenger ikke mye. Vanlig deploy og verifisering av en enkel kontrakt koster typisk under 0,01 testnett-ETH, men hent gjerne litt ekstra slik at du kan kjøre flere test-deployer uten å måtte tilbake til en faucet midt i arbeidet.
Steg 3: Installer Foundry og initialiser prosjektet
Foundry er et Rust-basert verktøysett for Solidity-utvikling, satt sammen av forge for kompilering og testing, cast for å snakke med noder, og anvil for en lokal testkjede. Installer det og opprett et nytt prosjekt:
curl -L https://foundry.paradigm.xyz | bash
foundryup
forge init base-vault-tutorial
cd base-vault-tutorial
forge install OpenZeppelin/openzeppelin-contracts
Dette gir deg en standard mappestruktur med src/ for kontrakter, test/ for tester og script/ for deployskript. Slett eksempelfilene som følger med forge init, siden du bygger fra bunnen av i denne guiden.
Steg 4: Skriv en sikker kontrakt med reentrancy-beskyttelse
Vi bygger en enkel innskudds- og uttaksboks, den typen kontrakt som oftest rammes av reentrancy-angrep hvis den skrives feil. Zealynx sin gjennomgang av bro-kontrakter på Base pekte nettopp på manglende nonReentrant-beskyttelse på funksjoner som withdraw(), executeMessage() og deposit() som en kritisk svakhet i deres analyse av en bro-protokoll på nettverket. Vi følger derfor mønsteret sjekk-effekt-interaksjon og legger til OpenZeppelin sin ReentrancyGuard som et ekstra lag:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "openzeppelin-contracts/contracts/security/ReentrancyGuard.sol";
import "openzeppelin-contracts/contracts/access/Ownable.sol";
contract BaseVault is ReentrancyGuard, Ownable {
mapping(address => uint256) public balances;
bool public paused;
event Deposited(address indexed user, uint256 amount);
event Withdrawn(address indexed user, uint256 amount);
modifier whenNotPaused() {
require(!paused, "Vault: satt pa pause");
_;
}
constructor(address initialOwner) Ownable(initialOwner) {}
function deposit() external payable whenNotPaused {
require(msg.value > 0, "Vault: null innskudd");
balances[msg.sender] += msg.value;
emit Deposited(msg.sender, msg.value);
}
function withdraw(uint256 amount) external nonReentrant whenNotPaused {
require(balances[msg.sender] >= amount, "Vault: for lav saldo");
// Effekt foer interaksjon
balances[msg.sender] -= amount;
(bool success, ) = msg.sender.call{value: amount}("");
require(success, "Vault: overforing feilet");
emit Withdrawn(msg.sender, amount);
}
function pause() external onlyOwner {
paused = true;
}
function unpause() external onlyOwner {
paused = false;
}
}
Legg merke til rekkefølgen inne i withdraw(): saldoen trekkes ned før pengene sendes ut. Det er selve poenget med sjekk-effekt-interaksjon, og det gjør at selv om mottakeren skulle prøve å kalle tilbake til kontrakten under overføringen, finner den ingenting igjen å hente ut. ReentrancyGuard-modifikatoren nonReentrant er et andre sikkerhetslag oppå dette, ikke en erstatning for riktig rekkefølge i koden.
Steg 5: Skriv enhets- og fuzz-tester med Forge
Grunnleggende scenarier
Forge sitt innebygde testrammeverk lar deg skrive tester i Solidity og kjøre både faste scenarier og fuzz-tester, der verktøyet selv genererer tilfeldige input for å prøve å bryte antagelsene dine. En fuzz-test for uttaksfunksjonen ser slik ut:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.20;
import "forge-std/Test.sol";
import "../src/BaseVault.sol";
contract BaseVaultTest is Test {
BaseVault vault;
address user = address(0xBEEF);
function setUp() public {
vault = new BaseVault(address(this));
vm.deal(user, 10 ether);
}
function testDepositAndWithdraw() public {
vm.startPrank(user);
vault.deposit{value: 1 ether}();
assertEq(vault.balances(user), 1 ether);
vault.withdraw(1 ether);
assertEq(vault.balances(user), 0);
vm.stopPrank();
}
function testFuzz_CannotWithdrawMoreThanBalance(uint256 amount) public {
vm.assume(amount > 0 && amount <= 5 ether);
vm.startPrank(user);
vault.deposit{value: amount}();
vm.expectRevert("Vault: for lav saldo");
vault.withdraw(amount + 1);
vm.stopPrank();
}
}
Fuzz-testing mot gjeninntredelse
Kjør testene med forge test -vvv. Fuzz-testen over prøver hundrevis av tilfeldige beløp automatisk og bekrefter at kontrakten alltid avviser uttak som overstiger saldoen. Skriv minst én test som simulerer et gjeninntredelsesangrep direkte, ved å lage en angripende kontrakt som kaller tilbake til withdraw() i sin egen mottakerfunksjon. Hvis den testen ikke feiler, har du bevist at beskyttelsen faktisk virker, ikke bare antatt det.
Fuzz-testing er spesielt verdifullt for kontrakter som håndterer penger, fordi den finner kantetilfeller en utvikler sjelden tenker på selv, som å sende inn null, maksverdien for en uint256, eller beløp som akkurat treffer en avrundingsgrense. Mange av de mest kjente DeFi-hackene har vist seg å skyldes nettopp et slikt kantetilfelle som aldri ble testet eksplisitt, ikke en fundamental designfeil i kontraktens hovedlogikk.
Steg 6: Konfigurer nettverk, RPC og miljøvariabler
Legg til Base-nettverkene i foundry.toml og lagre hemmeligheter i en .env-fil som aldri sjekkes inn i versjonskontroll:
[rpc_endpoints]
base_sepolia = "https://sepolia.base.org"
base_mainnet = "https://mainnet.base.org"
[etherscan]
base_sepolia = { key = "${BASESCAN_API_KEY}", url = "https://api-sepolia.basescan.org/api" }
base_mainnet = { key = "${BASESCAN_API_KEY}", url = "https://api.basescan.org/api" }
I .env-filen legger du inn PRIVATE_KEY for testlommeboken din og BASESCAN_API_KEY fra BaseScan sitt utviklerpanel. Legg .env til i .gitignore før du gjør noe annet, ikke etterpå. Det er en av de vanligste feilene nye kontraktsprosjekter gjør, og den er umulig å reparere fullt ut når nøkkelen først er pushet til et offentlig repository.
Steg 7: Deploy til Base Sepolia testnett
Skriv et lite deployskript i script/Deploy.s.sol som instansierer kontrakten med din adresse som eier, og kjør det mot testnettet:
source .env
forge script script/Deploy.s.sol:DeployScript \
--rpc-url base_sepolia \
--broadcast \
--private-key $PRIVATE_KEY
Forge skriver ut kontraktadressen og transaksjonshashen når deploy er fullført. Lagre adressen et sted du husker den, du trenger den i neste steg. Test deretter en runde med innskudd og uttak direkte mot testnettet via cast send, ikke bare gjennom en frontend, slik at du er sikker på at kontraktens logikk fungerer utenfor det lokale testmiljøet også.
Steg 8: Verifiser kontrakten på BaseScan
Verifisering betyr at kildekoden din blir offentlig lesbar og sammenlignbar med den kompilerte bytekoden på kjeden. Uten dette må brukere stole blindt på det du sier kontrakten gjør. Kjør:
forge verify-contract \
KONTRAKTADRESSE \
src/BaseVault.sol:BaseVault \
--chain base-sepolia \
--etherscan-api-key $BASESCAN_API_KEY \
--constructor-args $(cast abi-encode "constructor(address)" DIN_ADRESSE)
Sjekk resultatet på BaseScan sin testnett-utforsker og bekreft at fanen for kildekode viser en grønn hake. Hvis konstruktørargumentene ikke matcher nøyaktig det du brukte ved deploy, feiler verifiseringen, og det er den vanligste årsaken til at nye utviklere sitter fast på dette steget.
Verifisering er også en tillitssignal overfor brukerne dine. En uverifisert kontrakt med reelle midler er et rødt flagg for enhver som vurderer å bruke den, uansett hvor god koden faktisk er internt. Gjør det til en fast rutine å verifisere umiddelbart etter hvert deploy, ikke som noe du gjør "senere" rett før lansering, siden det er lett å glemme når prosjektet vokser og flere kontrakter kommer til.
Steg 9: Kjør statisk sikkerhetsanalyse med Slither
Slither fra Trail of Bits leser gjennom Solidity-koden din uten å kjøre den, og flagger mønstre som er kjent for å føre til sårbarheter, som ubeskyttede eksterne kall, feil bruk av tx.origin eller heltallsoverflyt i eldre kompilatorversjoner. Installer og kjør det mot prosjektet:
pip3 install slither-analyzer
slither src/BaseVault.sol --solc-remaps "openzeppelin-contracts=lib/openzeppelin-contracts"
Slither er ikke et komplett svar. Det fanger opp kjente mønstre, men det forstår ikke forretningslogikken din, og det finner ikke feil i hvordan kontrakten din samhandler med Base sin spesifikke bro- og sekvenser-arkitektur. Bruk det som et første filter før du eventuelt bestiller en manuell revisjon fra et selskap som spesialiserer seg på lag-2-kontrakter, spesielt hvis kontrakten din skal håndtere reelle brukermidler.
Les gjennom hver eneste advarsel Slither gir deg, selv de som virker trivielle. Det er fristende å ignorere lavrisiko-varsler for å komme raskere til deploy, men flere av de mest kjente DeFi-hackene startet som en kombinasjon av flere "mindre" svakheter som hver for seg virket ufarlige. Dokumenter i det minste hvorfor du eventuelt velger å ignorere en advarsel, slik at neste utvikler som leser koden forstår at det var en bevisst vurdering, ikke en forglemmelse.
Steg 10: Deploy til Base mainnet
Når testnettdeployet er verifisert og testene er grønne, bytt RPC-endepunkt fra base_sepolia til base_mainnet og gjenta kommandoen fra steg 7. Bruk en helt separat lommebok for mainnet-deployet, ikke testlommeboken fra tidligere i guiden. Sett gasspris eksplisitt med --gas-price hvis du deployer i en periode med høy aktivitet på Ethereum, siden Base sin datakostnad til L1 kan dominere den totale transaksjonsprisen din, ifølge Zealynx sin tekniske forklaring av gebyrmodellen.
Vent på minst tre bekreftelser før du stoler på at deployet er endelig, og verifiser kontrakten på BaseScan mainnet med samme kommando som i steg 8, bare med --chain base i stedet for base-sepolia.
Steg 11: Bro ETH og USDC mellom Ethereum og Base
Standard uttak fra Base til Ethereum går gjennom en utfordringsperiode på syv dager. Etter at en tilstandsrot er postet til Ethereum, kan enhver observatør med tilgang til Base sin transaksjonshistorikk kjøre OP Stack sitt feilbevisprogram lokalt og utfordre roten hvis den er feil, ifølge HBM & Company sin gjennomgang av mekanismen. Systemet bruker det som kalles Cannon, en MIPS-basert tvisteløser som reduserer en omstridt beregning til et enkelt steg Ethereum kan verifisere direkte. Permissionless feilbevis ble aktivert på Base i mars 2025, noe som betyr at hvem som helst kan delta i å sikre nettverket, ikke bare utvalgte parter.
For kontrakten din betyr dette at enhver funksjon som avhenger av at midler raskt kommer tilbake til Ethereum, må ta høyde for denne uken. Bygg aldri en integrasjon som antar at et uttak fra Base til Ethereum er øyeblikkelig, med mindre du bruker en tredjeparts likviditetsbro som forskutterer midlene mot et gebyr.
| Retning | Metode | Typisk ventetid |
|---|---|---|
| Ethereum til Base (innskudd) | Offisiell bro eller Coinbase-konto | Noen minutter |
| Base til Ethereum (uttak) | Offisiell bro, standard vei | 7 dagers utfordringsperiode |
| Base til Ethereum (uttak) | Tredjeparts likviditetsbro | Minutter, mot et gebyr |
| Base til Coinbase-konto | Direkte uttak uten smartkontraktbro | Varierer med Coinbase sine interne rutiner |
Native USDC på Base er utstedt direkte av Circle, ikke brodd fra Ethereum. Det gamle brodde tokenet USDbC finnes fortsatt i enkelte eldre integrasjoner, men bør ikke behandles som hovedavregningsmiddel i ny kode, ifølge en 2026-oversikt over Base-økosystemet. Sjekk alltid hvilken av de to adressene en integrasjon faktisk peker mot før du stoler på at en USDC-saldo betyr det du tror.
Bro-kontrakter i seg selv er blant de mest verdifulle målene i hele DeFi, nettopp fordi de samler enorme summer på ett sted. Zealynx sin risikoanalyse av Base-broen viste til en målt protokoll-TVL på over 3,1 milliarder dollar i det tilfellet de undersøkte, noe som illustrerer hvorfor selv små feil i tilgangskontroll eller reentrancy-beskyttelse på en bro kan bli enormt kostbare. Hvis kontrakten din selv skal ta imot innskudd fra en bro, ikke bare fra brukere direkte på Base, gjelder de samme reentrancy- og tilgangskontroll-prinsippene fra steg 4 med enda mindre feilmargin, siden beløpene som flyter gjennom en bro typisk er større enn i en enkelt brukerkontrakt.
Hvis prosjektet ditt skal motta meldinger direkte fra broens smartkontrakter, som ved en cross-chain-integrasjon der en handling på Ethereum skal utløse en effekt på Base, må du validere avsenderen nøye. Kontrakten din bør kun stole på meldinger som faktisk kommer fra den offisielle bromeldingskontrakten, aldri fra en vilkårlig adresse som utgir seg for å representere broen. Dette er nøyaktig samme type validering som manglet i flere av de større cross-chain-hackene i norsk og internasjonal presse de siste årene, der en forfalsket melding fikk en mottakerkontrakt til å tro at midler var deponert når de i realiteten aldri hadde forlatt avsenderkjeden.
Steg 12: Sett opp multisig-eierskap, overvåking og det komplette prosjektet
Så snart kontrakten har reelle midler, bør eierskapet (onlyOwner-funksjonene i eksempelet vårt) flyttes fra en enkelt lommebok til en multisig-kontrakt, slik at ingen enkeltperson kan pause eller endre kontrakten alene. Kall transferOwnership() fra den opprinnelige eier-adressen til multisig-adressen din, og bekreft eierskapsendringen på BaseScan før du fjerner tilgangen til den gamle nøkkelen. De fleste team på Base bruker Safe (tidligere Gnosis Safe) til dette, siden det krever et flertall av forhåndsgodkjente signaturer for hver eneste administrativ handling, i stedet for at én enkelt kompromittert nøkkel er nok til å ta kontroll over kontrakten.
Det komplette prosjektet du nå sitter igjen med, har denne strukturen:
base-vault-tutorial/
|-- src/
| `-- BaseVault.sol
|-- test/
| `-- BaseVault.t.sol
|-- script/
| `-- Deploy.s.sol
|-- lib/
| `-- openzeppelin-contracts/
|-- foundry.toml
`-- .env (ikke i git)
For løpende overvåking, sett opp varsler på store innskudd og uttak gjennom en blokk-utforsker sitt API eller en tredjepartstjeneste, og følg med på om det samlede beløpet i kontrakten (address(this).balance) noen gang avviker fra summen av alle registrerte saldoer. Et avvik der er ofte det første tegnet på at noe uventet har skjedd, lenge før det viser seg som et fullt utnyttet hull.
Sjekkliste før du lanserer på mainnet
Med kontrakten skrevet, testet, verifisert og deployet, er det verdt å samle alt du nettopp har gjort i én kort sjekkliste. Bruk den som en siste gjennomgang før du deler kontraktadressen offentlig eller lar reelle brukere sende inn midler.
- Alle enhets- og fuzz-tester kjører grønt, inkludert en eksplisitt test som simulerer et gjeninntredelsesangrep.
- Slither er kjørt og alle relevante advarsler er enten fikset eller dokumentert med en begrunnelse.
- Kontrakten er verifisert på BaseScan, både på testnett og mainnet.
- Eierskap er flyttet fra en enkelt lommebok til en multisig-kontrakt.
- .env-filen med private nøkler er bekreftet ekskludert fra versjonskontroll.
- Du har testet en fullstendig innskudd- og uttakssyklus manuelt på mainnet med et lite beløp før du markedsfører kontrakten bredt.
- Du har en plan for hvordan du varsler brukere dersom noe uventet oppdages etter lansering, inkludert hvordan pause-funksjonen brukes i praksis.
Vanlige sikkerhetsfeller på Base og OP Stack
De fleste hackene mot lag-2-kontrakter skyldes ikke eksotiske angrep, men velkjente feil som ikke ble fanget opp før lansering. L2Beat sin risikovurdering av Base og andre rollups følger nettopp denne typen strukturelle svakheter over tid, ikke bare enkelthendelser. Her er fem feil som går igjen spesifikt i Base- og OP Stack-prosjekter.
| Feil | Konsekvens | Løsning |
|---|---|---|
| Manglende nonReentrant på uttaksfunksjoner | Angriper kan tømme kontrakten via gjentatte kall | Bruk ReentrancyGuard og sjekk-effekt-interaksjon sammen |
| Antar at uttak til Ethereum er øyeblikkelig | Brukerflyt bryter sammen eller låser midler i syv dager | Bygg eksplisitt venting eller bruk en likviditetsbro |
| Blander native USDC og eldre USDbC | Feil saldoberegning eller mislykkede overføringer | Valider kontraktadressen for tokenet eksplisitt i koden |
| Stoler på sekvenseren som nøytral tidsstempel-kilde | Tidsavhengig logikk kan manipuleres av rekkefølge | Bruk blokknummer og gjør tidsvinduer sjenerøse |
| Eierskap på én enkelt EOA-lommebok | Enkeltperson kan pause, oppgradere eller stjele | Flytt eierskap til multisig før mainnet-lansering |
Feilsøking og avanserte tips for produksjon
Feilsøking: løsninger på de vanligste problemene
Selv med et nøye oppsett dukker det opp små hindringer underveis, spesielt første gang du beveger deg fra lokal testing til et faktisk nettverk. Tabellen under dekker de åtte problemene norske utviklere oftest støter på i akkurat denne prosessen, fra tomme lommebøker til feilsøking av verifiseringstrinnet.
| Problem | Sannsynlig årsak | Løsning |
|---|---|---|
| "insufficient funds for gas" ved deploy | For lite testnett-ETH i lommeboken | Hent mer fra en faucet og sjekk saldo med cast balance |
| forge verify-contract feiler med "already verified" | Kontrakten er allerede verifisert fra tidligere forsøk | Sjekk BaseScan direkte, ingen handling nødvendig |
| Konstruktørargumenter matcher ikke ved verifisering | Feil rekkefølge eller type i cast abi-encode | Kopier nøyaktig samme argumenter som ble brukt ved deploy |
| RPC-tidsavbrudd mot base_mainnet | Overbelastet offentlig endepunkt | Bruk en dedikert RPC-leverandør i stedet for det offentlige endepunktet |
| Fuzz-test feiler tilfeldig mellom kjøringer | Antagelse i vm.assume for smal eller for bred | Juster grensene og legg til flere eksplisitte edge-case-tester |
| Transaksjon henger i "pending" lenge | For lav gasspris satt manuelt | Fjern manuell gasspris og la forge estimere selv |
| Slither rapporterer falske positiver på OpenZeppelin-kode | Slither analyserer også biblioteket, ikke bare din kode | Filtrer med --exclude-dependencies i kommandoen |
| Uttak til Ethereum vises ikke etter syv dager | Uttaket krever et eget "finalize"-steg etter ventetiden | Fullfør uttaket manuelt gjennom brogrensesnittet eller et cast-kall |
De to siste radene i tabellen fanger opp det nyeste utviklere oftest glemmer: at et Base-uttak til Ethereum faktisk er en to-stegs prosess, ikke ett. Det første steget initierer uttaket og starter utfordringsperioden, mens det andre steget, ofte kalt "finalize" eller "prove and finalize" i ulike brogrensesnitt, faktisk flytter midlene etter at syv dager har gått. Mange nye brukere sjekker lommeboken sin på dag åtte, ser ingenting, og antar at noe har gått galt, når løsningen bare er å fullføre det andre steget manuelt.
Avanserte tips før du skalerer opp
- Sett en øvre grense per transaksjon i tillegg til den generelle logikken, slik at selv en uoppdaget feil begrenses i skadeomfang.
- Legg til en tidsforsinkelse på eierskapsendringer og oppgraderinger, slik at brukere rekker å reagere før en endring trer i kraft.
- Test kontrakten mot en lokal fork av Base mainnet med anvil, ikke bare mot testnettet, for å fange opp interaksjoner med eksisterende kontrakter på kjeden.
- Følg med på Base sin desentraliseringsveikart, siden overgangen til flere sekvensere og fjerning av nødbryteren kan endre hvilke angrepsvektorer som er relevante for deg over tid.
- Sett opp et bug bounty-program før kontrakten håndterer store summer, slik at velvillige sikkerhetsforskere har et insentiv til å varsle deg først.
- Skriv en enkel hendelsesplan i forkant, med tydelig ansvarsfordeling for hvem som kaller pause() og hvem som kommuniserer med brukerne dersom noe går galt, slik at ingen bruker tid på å finne ut av dette midt i en pågående hendelse.
Ingen av disse tipsene erstatter grundig testing og en ekstern gjennomgang, men de reduserer skadeomfanget betydelig hvis noe likevel skulle gå galt. Kombinasjonen av transaksjonsgrenser, tidsforsinkelse på administrative endringer og en klar hendelsesplan er ofte det som avgjør om en oppdaget svakhet blir en mindre, håndterbar hendelse eller et fullstendig tap av brukermidler.
Til slutt: ingen bro eller kontrakt er risikofri bare fordi den er revidert. BaltEX pekte i sin gjennomgang av Base-broer på at ingen større bro på nettverket hadde hatt et katastrofalt utnyttet hull de siste 18 månedene per september 2026, men understreket samtidig at brukere alltid bør sjekke ferske revisjoner, aktive bug bounty-programmer og innlåst verdi før store overføringer. Det samme rådet gjelder din egen kontrakt: en revisjon er et øyeblikksbilde, ikke en garanti som varer evig.
Ofte stilte spørsmål
Må jeg bruke Foundry, eller kan jeg bruke Hardhat på Base?
Base støtter begge rammeverkene siden det er en fullstendig EVM-kompatibel kjede. Foundry er raskere til testing og fuzzing fordi testene skrives i Solidity og kjøres nativt, men hvis teamet ditt allerede har en etablert Hardhat-oppsett med JavaScript-baserte tester, fungerer det like godt mot Base sine RPC-endepunkter.
Hvorfor tar det syv dager å ta ut midler fra Base til Ethereum?
Det er utfordringsperioden i OP Stack sitt feilbevissystem. Den gir enhver observatør tid til å oppdage og bestride en feilaktig tilstandsrot før uttaket regnes som endelig på Ethereum. Perioden er et sikkerhetsvalg, ikke en teknisk begrensning som kan fjernes uten å svekke sikkerhetsmodellen.
Er Base tryggere eller mindre trygt enn Arbitrum og zkSync Era?
De tre kjedene bruker ulike sikkerhetsmodeller. Base og Arbitrum er begge optimistiske rollups med utfordringsperioder, mens zkSync Era bruker gyldighetsbevis som verifiseres matematisk uten en ventetid på samme måte. Ingen av modellene er automatisk tryggere i alle scenarioer. Vurder heller hvor desentralisert sekvenseren er, og hvor lenge feilbevissystemet har vært i produksjon på hver kjede, før du konkluderer. Base sitt permissionless feilbevissystem har vært i produksjon siden mars 2025, noe som gir det en dokumentert historikk, men fortsatt kortere enn eldre, mer etablerte sikkerhetsmekanismer andre steder i økosystemet.
Kan jeg stole på at native USDC på Base alltid er 1:1 med dollar?
Native USDC på Base er utstedt direkte av Circle på samme måte som på Ethereum, og er ikke avhengig av en bro-mekanisme for å opprettholde verdien sin. Den eldre, brodde varianten USDbC er derimot avhengig av at broens smartkontrakt forblir intakt, og bør derfor behandles med større forsiktighet i ny kode.
Trenger jeg en profesjonell revisjon selv om jeg har kjørt Slither?
Ja, hvis kontrakten skal håndtere reelle brukermidler. Slither og lignende verktøy fanger opp kjente kodemønstre, men de forstår ikke forretningslogikken din eller hvordan kontrakten samhandler med resten av Base-økosystemet. En manuell revisjon fra noen som kjenner OP Stack sine spesifikke egenskaper, dekker hull automatiserte verktøy ikke ser.
Hva skjer med kontrakten min hvis Base sin sekvenser går ned?
Så lenge sekvenseren er nede, kan ingen nye transaksjoner behandles på Base, men allerede bekreftede transaksjoner forblir gyldige siden de er sikret av data postet til Ethereum. OP Stack har mekanismer for at brukere i ytterste konsekvens kan tvinge inn transaksjoner direkte via Ethereum hvis sekvenseren skulle sensurere dem over lengre tid, men dette er en nødløsning, ikke normal drift. For kontrakten din i praksis betyr et sekvenser-avbrudd som regel bare midlertidig utilgjengelighet, ikke tap av midler, forutsatt at kontrakten din ikke er avhengig av at en bestemt transaksjon skjer innenfor et stramt tidsvindu.
Koster det mye å deployere kontrakter på Base sammenlignet med Ethereum mainnet?
Base er betydelig billigere enn å deployere direkte på Ethereum mainnet, siden kun komprimerte data postes til L1 mens selve utførelsen skjer på L2. Den eksakte kostnaden varierer med hvor overbelastet Ethereum er akkurat når du deployer, siden L1-databiten av gebyret ditt følger Ethereum sin egen gassprising.
Kan jeg bruke Vyper i stedet for Solidity på Base?
Ja. Base er fullstendig EVM-kompatibel, så enhver kompilator som produserer standard EVM-bytekode, inkludert Vyper, fungerer like godt som Solidity. Foundry sin native støtte er bygget rundt Solidity, så hvis du velger Vyper, må du sette opp kompileringssteget separat og deretter importere den ferdig kompilerte bytekoden i test- og deployskriptene dine.
Hvordan vet jeg om en tredjeparts likviditetsbro for raske uttak er trygg å bruke?
Se etter hvor lenge broen har operert uten hendelser, hvor stor innlåst verdi den håndterer, og om den er offentlig revidert av et anerkjent sikkerhetsselskap. En bro som forskutterer uttak mot gebyr, tar på seg en reell finansiell risiko fram til det offisielle uttaket fra Base er endelig etter syv dager, så undersøk alltid hvem som faktisk bærer den risikoen før du stoler på et raskt uttak for store beløp.
