Lokaal bouwen en testen op devnet zijn uitstekende manieren om te beginnen met Solana-betalingen. Wanneer je echter klaar bent om naar mainnet te implementeren, moet je je bewust zijn van de nuances van het mainnet. Devnet vergeeft fouten. Mainnet niet. Deze gids behandelt de verschillen die ertoe doen om ervoor te zorgen dat je gebruikers een soepele ervaring hebben.
| Devnet | Mainnet |
|---|---|
| Gratis SOL van faucets | Verkrijg echte SOL voor kosten |
| Lage concurrentie voor blokruimte | Prioriteitskosten zijn belangrijk |
| Transacties landen gemakkelijk | Transactieconfiguratie is cruciaal |
| Publieke RPC is prima | Productie-RPC vereist |
| Devnet-keypairs en mints | Verschillende sleutels en token-mints—werk je configuratie bij |
RPC-infrastructuur
Publieke endpoints
(api.mainnet-beta.solana.com) zijn rate-limited zonder SLA. Ze zijn prima voor
ontwikkeling maar zullen productiebetalingsstromen laten mislukken—alsof je een
betalingsverwerker probeert te draaien via een gedeelde API zonder
uptime-garantie.
Gebruik nooit publieke RPC voor productie
Gebruik een private RPC-provider voor betrouwbare, lage-latency toegang.
Bij het kiezen van een RPC-provider, let op:
- Betrouwbaarheid: SLA's met uptime-garanties (99,9%+)
- Latency: Geografische nabijheid tot je gebruikers
- Functies: Transactielandingsfuncties, indexering, prioriteitskost-API's
Voor een volledige lijst van RPC-providers, zie de RPC Infrastructure Providers-gids.
Redundante RPC-configuratie
Zoals elke netwerkserviceprovider kunnen RPC-providers downtime of periodes van verminderde prestaties ervaren. Om ervoor te zorgen dat je applicatie veerkrachtig is, moet je je applicatie configureren om meerdere RPC-providers te gebruiken.
Solana Kit biedt een bibliotheek voor het aanpassen van RPC-transporten waarmee je je eigen redundante RPC-client kunt bouwen. Hier is een voorbeeld van hoe je het kunt gebruiken om een redundante RPC-client te bouwen:
import { RpcTransport } from "@solana/rpc-spec";import { RpcResponse } from "@solana/rpc-spec-types";import { createHttpTransport } from "@solana/rpc-transport-http";// Create a transport for each RPC serverconst transports = [createHttpTransport({ url: "https://mainnet-beta.my-server-1.com" }),createHttpTransport({ url: "https://mainnet-beta.my-server-2.com" }),createHttpTransport({ url: "https://mainnet-beta.my-server-3.com" })];// Create a wrapper transport that distributes requests to themlet nextTransport = 0;async function roundRobinTransport<TResponse>(...args: Parameters<RpcTransport>): Promise<RpcResponse<TResponse>> {const transport = transports[nextTransport];nextTransport = (nextTransport + 1) % transports.length;return await transport(...args);}
Als je liever geen eigen routingtools bouwt, kun je gebruikmaken van een derde partij service zoals Iron Forge om de routing voor je af te handelen.
Transaction landing
Op Devnet landen transacties vrij gemakkelijk. Op Mainnet concurreer je voor blokruimte. Om de kans te vergroten dat je transactie in een blok wordt opgenomen, moet je ervoor zorgen dat je transactie correct is samengesteld. Dit betekent:
- het opnemen van een verse blockhash voordat je de transactie verstuurt
- het opnemen van een priority fee instructie in de transactie met een competitieve priority fee
- het opnemen van een compute unit limit instructie in de transactie met een compute unit limit gebaseerd op de geschatte compute units die nodig zijn voor de transactie
Daarnaast moet je andere tools zoals Jito Bundles overwegen om de kans te vergroten dat je transactie in een blok wordt opgenomen. Laten we deze tools in meer detail verkennen.
Configuratie voor het versturen van transacties
Bij het versturen van transacties op Mainnet, configureer je deze parameters voor optimale landingspercentages:
Blockhash-beheer:
- Ophalen met
confirmedcommitment - Bewaar de
lastValidBlockHeightdie wordt geretourneerd doorgetLatestBlockhash—dit vertelt je wanneer je transactie verloopt - Blockhashes verlopen na ~150 blokken (~60-90 seconden)
Verzendopties:
maxRetries: 0— Schakel automatische RPC-retries uit. Handel retries zelf af zodat je de blockhash kunt verversen wanneer nodig.skipPreflight: true— Omzeil simulatie voordat je verstuurt. Gebruik dit wanneer je de transactie al hebt gevalideerd en de laagste latentie wilt. Houd het opfalsetijdens ontwikkeling om fouten vroegtijdig op te vangen.
import { createSolanaRpc } from "@solana/kit";const rpc = createSolanaRpc(process.env.RPC_URL!);// 1. Get blockhash with confirmed commitmentconst { value: latestBlockhash } = await rpc.getLatestBlockhash({ commitment: "confirmed" }).send();// 2. Build and sign your transaction with the blockhash// ... (transaction building code)// 3. Send with production settingsconst signature = await rpc.sendTransaction(encodedTransaction, {encoding: "base64",maxRetries: 0n, // Handle retries yourselfskipPreflight: true, // Skip simulation for speed (use false during dev)preflightCommitment: "confirmed"}).send();// 4. Track expiration using lastValidBlockHeightconst { lastValidBlockHeight } = latestBlockhash;// Stop retrying when current block height exceeds lastValidBlockHeight
Gebruik prioriteitskosten
Elke Solana-transactie vereist transactiekosten, betaald in SOL. Transactiekosten zijn opgesplitst in twee delen: de basiskosten en de prioriteitskosten. De basiskosten compenseren validators voor het verwerken van de transactie. De prioriteitskosten zijn optionele kosten om de kans te vergroten dat de huidige leider je transactie verwerkt. Zie het als expresverzending: je betaalt meer voor snellere, betrouwbaardere levering.
Hoe kosten werken:
Total fee = Base fee (5,000 lamports per signature) + Priority feePriority fee = Compute units x Price per unit (micro-lamports per compute unit)
Kosten in de praktijk:
- Eenvoudige USDC-overdracht: ~$0,001-0,005 onder normale omstandigheden
- Tijdens congestie: ~$0,01-0,05
- Piekcongestie: kan hoger uitvallen
Voorbeeldimplementatie:
Het
@solana-program/compute-budget-pakket
biedt een hulpfunctie om eenvoudig de compute unit price (in micro-lamports)
instructie bij te werken of toe te voegen aan een transactie.
import { updateOrAppendSetComputeUnitPriceInstruction } from "@solana-program/compute-budget";const tx = pipe(createTransactionMessage({ version: 0 }),(m) => setTransactionMessageFeePayerSigner(payer, m),(m) => setTransactionMessageLifetimeUsingBlockhash(latestBlockhash, m),(m) => appendTransactionMessageInstructions([myInstructions], m),(m) => updateOrAppendSetComputeUnitPriceInstruction(1000n as MicroLamports, m));
Kostenramingen verkrijgen: De meeste RPC-providers bieden prioriteitskost-API's aan:
Voor de volledige kostenmechanica, zie Transactiekosten en onze handleiding: Hoe prioriteitskosten toevoegen aan een transactie.
Optimaliseer compute units
Compute op Solana is in feite een maat voor de hoeveelheid werk die het programma verricht. Er is een limiet aan de hoeveelheid compute die kan worden gebruikt in een transactie (momenteel 1,4 miljoen compute units), en een limiet aan de hoeveelheid compute die per account per blok kan worden gebruikt (momenteel 100 miljoen compute units).
Wanneer je een transactie indient, moet je de hoeveelheid compute schatten die zal worden gebruikt, en de compute unit-limiet dienovereenkomstig instellen - dit is in feite een verzoek voor hoeveel van de totale capaciteit moet worden gereserveerd voor jouw transactie. In de praktijk betekent dit dat het correct inschatten van de compute units die nodig zijn voor je transactie cruciaal is om je transactie in een blok opgenomen te krijgen (en belangrijk is voor het beheren van je prioriteitskosten).
De Solana JSON RPC API heeft een
simulatetransaction methode die gebruikt
kan worden om de benodigde compute units voor een transactie te schatten,
inclusief een schatting van de te gebruiken compute units.
@solana/kit biedt hulpfuncties die de
resourcelimieten van een transactie schatten en deze in één stap instellen op
het bericht (met behulp van de simulatetransaction methode onder de motorkap).
Voor versie 1 transacties schatten deze hulpfuncties ook de limiet voor de
geladen accountsdatagrootte.
import {estimateResourceLimitsFactory,estimateAndSetResourceLimitsFactory} from "@solana/kit";const estimateResourceLimits = estimateResourceLimitsFactory({ rpc });const estimateAndSetResourceLimits = estimateAndSetResourceLimitsFactory(estimateResourceLimits);const txWithResourceLimits = await estimateAndSetResourceLimits(tx);
Als u transacties bouwt en verzendt met een kit-pluginclient, heeft u deze
stap doorgaans niet nodig — de client voegt compute budget-instructies voor u
toe bij het verzenden (.sendTransaction()). De handmatige aanpak hierboven
is voor wanneer u transacties rechtstreeks samenstelt met @solana/kit.
In productie, als u herhaaldelijk hetzelfde type transactie uitvoert, kunt u overwegen de compute-schatting voor dat transactietype te cachen om de overhead van het steeds opnieuw schatten van compute units te vermijden.
Jito Bundles
Jito-bundles zijn een tool voor het beheren van atomaire uitvoering van meerdere transacties. Dit wordt bereikt door meerdere transacties naar het Jito-netwerk te sturen met een fooi. Fooien kunnen worden gebruikt om het Jito-netwerk te stimuleren uw transacties in een block op te nemen.
Bronnen:
Herprobeerstrategie
Transacties kunnen om vele redenen mislukken. In tegenstelling tot traditionele betaal-API's die direct succes/mislukking teruggeven, vereisen blockchain-transacties het bijhouden van bevestigingen.
Belangrijke concepten:
- Blockhash-vervaldatum: Transacties zijn geldig voor ~150 blocks (~60-90 seconden)
- Idempotentie: Dezelfde ondertekende transactie produceert altijd dezelfde handtekening — opnieuw indienen is veilig
- Exponentiële backoff: Voorkom het overbelasten van het netwerk met snelle herhaalde pogingen
import {createSolanaRpc,createSolanaRpcSubscriptions,sendAndConfirmTransactionFactory,isSolanaError,SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED} from "@solana/kit";const rpc = createSolanaRpc(process.env.RPC_URL!);const rpcSubscriptions = createSolanaRpcSubscriptions(process.env.RPC_WSS_URL!);const sendAndConfirmTransaction = sendAndConfirmTransactionFactory({rpc,rpcSubscriptions});// Send with automatic confirmation tracking and block height monitoringtry {await sendAndConfirmTransaction(signedTransaction, {commitment: "confirmed",// Optional: abort after 75 secondsabortSignal: AbortSignal.timeout(75_000)});} catch (e) {if (isSolanaError(e, SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED)) {// Blockhash expired—rebuild transaction with fresh blockhash and retryrebuildAndRetryTransaction(); // implement your own logic for rebuilding and retrying the transaction}throw e;}
De sendAndConfirmTransactionFactory van @solana/kit verwerkt
bevestigingspeilingen en het bijhouden van blokhoogtes automatisch. Het gooit
SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED wanneer de blockhash van de transactie
verloopt, wat aangeeft dat je de transactie opnieuw moet opbouwen met een nieuwe
blockhash.
Aanvullende bronnen
- Gids: Transactiebevestiging & Vervaldatum
- Helius: Hoe transacties te landen op Solana
- QuickNode: Strategieën om Solana-transacties te optimaliseren
Bevestigingsniveaus begrijpen
Solana biedt drie bevestigingsniveaus. In termen van traditionele financiën:
| Niveau | Solana-definitie | Traditioneel equivalent | Gebruiksgeval |
|---|---|---|---|
processed | In een blok, nog niet gestemd | Autorisatie in behandeling | Real-time UI-updates |
confirmed | Supermeerderheid gestemd | Vrijgegeven gelden | De meeste betalingen |
finalized | Verankerd, onomkeerbaar | Verrekende gelden | Hoge waarde, compliance |
Wanneer elk te gebruiken:
- UI-updates: Toon
processedvoor onmiddellijke feedback ("Betaling ingediend") - Gebruikersaccount crediteren: Wacht op
confirmed(veilig voor de meeste transacties) - Fysieke goederen verzenden: Wacht op
finalized - Grote opnames: Wacht op
finalized - Compliance/audit: Registreer altijd de
finalized-status
Voor meer informatie over het controleren van de transactiestatus, zie Interactie met Solana.
Foutafhandeling
Solana Kit biedt getypeerde fouten via isSolanaError(). Gebruik specifieke
foutcodes in plaats van stringvergelijking:
import {isSolanaError,SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED,SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE,SOLANA_ERROR__TRANSACTION_ERROR__BLOCKHASH_NOT_FOUND,SOLANA_ERROR__INSTRUCTION_ERROR__INSUFFICIENT_FUNDS} from "@solana/kit";function handlePaymentError(error: unknown): {message: string;retryable: boolean;} {// Blockhash expired—rebuild and retryif (isSolanaError(error, SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED) ||isSolanaError(error, SOLANA_ERROR__TRANSACTION_ERROR__BLOCKHASH_NOT_FOUND)) {return { message: "Transaction expired—rebuilding", retryable: true };}// Insufficient SOL for feesif (isSolanaError(error,SOLANA_ERROR__TRANSACTION_ERROR__INSUFFICIENT_FUNDS_FOR_FEE)) {return { message: "Not enough SOL for fees", retryable: false };}// Insufficient token balanceif (isSolanaError(error, SOLANA_ERROR__INSTRUCTION_ERROR__INSUFFICIENT_FUNDS)) {return { message: "Insufficient balance", retryable: false };}// Unknown errorconsole.error("Payment error:", error);return { message: "Payment failed—please retry", retryable: true };}
Veelvoorkomende foutcodes:
| Foutcode | Oorzaak | Herstel |
|---|---|---|
BLOCK_HEIGHT_EXCEEDED | Blockhash verlopen | Opnieuw opbouwen met nieuwe blockhash |
BLOCKHASH_NOT_FOUND | Blockhash niet gevonden | Opnieuw opbouwen met nieuwe blockhash |
INSUFFICIENT_FUNDS_FOR_FEE | Onvoldoende SOL | Betaalrekening aanvullen of gebruik fee-abstractie |
INSUFFICIENT_FUNDS | Onvoldoende tokens | Gebruiker heeft meer saldo nodig |
ACCOUNT_NOT_FOUND | token account ontbreekt | ATA aanmaken in transactie |
Gasloze Transacties
Gebruikers verwachten te betalen in stablecoins, niet om SOL te verwerven voor netwerkkosten. Gasloze transacties lossen dit op—vergelijkbaar met hoe Venmo-gebruikers niet nadenken over ACH-kosten. Zie Kostenabstractie voor een volledige implementatie.
Beveiliging
Sleutelbeheer
- Stel nooit privésleutels bloot in frontend-code. Gebruik backend-ondertekening, hardwarewallets, multisignatuurwallets of sleutelbeheerservices.
- Scheid hot- en coldwallets. Hot wallet voor operaties, cold voor de treasury.
- Maak een back-up van alle productiesleutels. Sla versleutelde back-ups op op meerdere beveiligde locaties. Het verliezen van een sleutel betekent permanent verlies van toegang.
- Gebruik verschillende sleutels voor devnet en mainnet. Uw devnet-sleutels mogen niet uw mainnet-sleutels zijn. Gebruik omgevingsgebaseerde configuratie om ervoor te zorgen dat de juiste sleutels voor elk netwerk worden geladen.
Ondertekeningsinfrastructuur
Voor productie-backend-ondertekening gebruikt u Keychain—een uniforme ondertekeningsbibliotheek die meerdere sleutelbeheer-backends abstraheert via één interface: Memory, Vault, Privy, Turnkey, AWS KMS, Fireblocks, GCP KMS, CDP, Para, Dfns, Crossmint, Openfort en Utila. Hiermee kunt u lokaal ontwikkelen met in-memory sleutels en vervolgens overschakelen naar productiewaardige backends zonder de applicatiecode te wijzigen.
Niet zeker welke backend past? Zie Een backend kiezen. Keychain is beschikbaar voor zowel Rust als TypeScript.
RPC-beveiliging
Behandel RPC-endpoints zoals API-sleutels—stel ze niet bloot in frontend-code waar ze kunnen worden geëxtraheerd en misbruikt. Gebruik een backend-proxy of omgevingsvariabelen die niet in client-code worden gebundeld.
- QuickNode: Best Practices voor Endpoint-beveiliging
- Helius: Bescherm je Solana API-sleutels: Best Practices voor Beveiliging
Monitoring
Volg deze metrics in productie:
| Metric | Waarom |
|---|---|
| Transactiesuccespercentage | Problemen vroegtijdig detecteren |
| Bevestigingslatentie | Netwerkgezondheid monitoren |
| Prioriteitskosten | Kostenbeheer |
| RPC-foutpercentage | Providergezondheid |
Stel waarschuwingen in voor:
- Overboekingen boven drempelwaarde vanuit treasury
- Pieken in mislukte transacties
- Ongebruikelijke ontvangerpatronen
- Stijgingen in RPC-foutpercentage
Voor realtime transactiemonitoring op schaal, zie onze Indexeringsgids.
Verifieer Adressen
Elk token en programma heeft precies één correct adres op mainnet. Vervalste tokens die USDC of andere stablecoins imiteren zijn gebruikelijk—ze hebben dezelfde naam en hetzelfde symbool maar een andere mint. Je applicatie moet de mint-adressen hardcoden of op een allowlist plaatsen (gebaseerd op je vereisten), accepteer ze nooit dynamisch vanuit onbetrouwbare bronnen.
Omgevingsgebaseerde configuratie: Devnet en Mainnet gebruiken vaak volledig verschillende token mints. Stel de configuratie van je applicatie in om de juiste adressen per omgeving te laden—hardcode geen mainnet-adressen en vergeet ze niet te verwisselen tijdens het testen, of erger nog, lever geen devnet-adressen op in productie.
Enkele veelvoorkomende stablecoin mints zijn:
| Token | Uitgever | Mint-adres |
|---|---|---|
| USDC | Circle | EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v |
| USDT | Tether | Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB |
| PYUSD | PayPal | 2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo |
| USDG | Paxos | 2u1tszSeqZ3qBWF3uNGPFc8TzMk2tdiwknnRMWGWjGWH |
Programma-adressen zijn ook belangrijk. Het verzenden van instructies naar het verkeerde programma zal mislukken—of erger nog, resulteren in onherstelbaar verlies van fondsen. De Token Program-adressen zijn:
| Programma | Adres |
|---|---|
| Token Program | TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA |
| Token-2022 Program | TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb |
Het op de allowlist plaatsen van de juiste adressen beschermt tegen vervalste tokens, maar het biedt geen bescherming tegen het versturen naar het verkeerde soort account. Een ontvangersadres kan een wallet, een token account, een mint of een programma zijn, en elk vereist een andere afhandeling. Natieve SOL die naar iets anders dan een wallet wordt gestuurd, verlaat de controle van de verzender — definitief verloren bij een mint of programma, alleen terugvorderbaar door de accounteigenaar bij een token account — zonder een mislukte transactie om de gebruiker te waarschuwen.
Valideer ontvangers vóór het versturen
Classificeer elk ontvangersadres voordat u een overdracht ondertekent. Zie Adres Verifiëren voor de volledige beslisboom en referentiecode die wallets, token accounts, mints en programma's onderscheidt.
Checklist vóór lancering
- Mainnet SOL verkregen voor kosten en rent
- Productie-RPC geconfigureerd (geen publiek eindpunt)
- Reserveer-RPC-eindpunt geconfigureerd
- Prioriteitskosten geïmplementeerd met dynamische prijsstelling
- Retry-logica verwerkt verlopen blockhash
- Bevestigingsniveau passend voor het gebruiksscenario
- Alle veelvoorkomende fouten worden correct afgehandeld
- Gasless geconfigureerd (indien van toepassing)
- Mainnet-tokenadressen geverifieerd (geen devnet mints)
- Validatie van ontvangersadres vóór het versturen (wallet vs token account vs mint vs programma)
- Alle sleutels veilig opgeslagen
- Sleutelbeheer beoordeeld (geen sleutels in frontend)
- Transactiebewaking en -waarschuwingen actief
- Belastingstests uitgevoerd op verwacht volume
Programma's implementeren
Als u een aangepast Solana-programma implementeert als onderdeel van uw betalingsinfrastructuur, zijn er aanvullende overwegingen.
Pre-deployment
- Solana CLI-versie: Zorg ervoor dat je de nieuwste versie van de Solana CLI gebruikt.
- Program keypair: Je programma heeft op mainnet een ander adres dan op
devnet (tenzij je hetzelfde keypair hergebruikt). Werk alle verwijzingen in je
applicatieconfiguratie bij. Bewaar je program keypair op een veilige locatie
(let op: het uitvoeren van
cargo cleanzal waarschijnlijk je program keypair verwijderen). - Accounts initialiseren: Als je programma beheerdersaccounts, PDA's of andere statusaccounts vereist, zorg er dan voor dat deze op mainnet worden aangemaakt voordat gebruikers met je applicatie communiceren. Hetzelfde geldt voor alle Associated Token Accounts (ATA's) die je programma nodig heeft.
Implementatieproces
- Buffer accounts: Grote programma's worden geïmplementeerd via buffer
accounts. Het
solana program deploycommando verwerkt dit automatisch, maar houd er rekening mee dat implementatie niet atomair is — als het wordt onderbroken, moet je mogelijk buffer accounts herstellen of sluiten. Zie Programma's implementeren. - Upgrade-autoriteit: Beslis of je programma na de lancering upgradebaar moet zijn. Voor onveranderlijkheid, trek de upgrade-autoriteit in na implementatie. Voor flexibiliteit, beveilig de upgrade-autoriteitssleutel op de juiste wijze.
- Rent: Zorg ervoor dat je implementatiewallet voldoende SOL heeft om de minimumdrempels voor rent-vrijstelling te dekken voor alle program accounts.
- Verificatie: Verifieer je programma om te controleren dat het uitvoerbare programma dat je naar het netwerk van Solana implementeert overeenkomt met de broncode in je repository
Voor volledige begeleiding bij de implementatie van programma's, zie Programma's implementeren.
Is this page helpful?