Tworzenie lokalnie i testowanie na devnecie to świetny sposób, by zacząć pracę z płatnościami w Solanie. Jednak gdy jesteś gotowy na wdrożenie na Mainnet, musisz być świadomy specyfiki mainnetu. Devnet wybacza błędy. Mainnet – nie. Ten przewodnik omawia kluczowe różnice, które pozwolą zapewnić użytkownikom płynne doświadczenie.
| Devnet | Mainnet |
|---|---|
| Darmowe SOL z faucetów | Zdobądź prawdziwe SOL na opłaty |
| Niska konkurencja o miejsce w bloku | Opłaty priorytetowe mają znaczenie |
| Transakcje przechodzą łatwo | Konfiguracja transakcji jest kluczowa |
| Publiczny RPC wystarcza | Wymagany produkcyjny RPC |
| Klucze i minty z devnetu | Inne klucze i minty tokenów — zaktualizuj konfigurację |
Infrastruktura RPC
Publiczne endpointy
(api.mainnet-beta.solana.com) mają limity zapytań i brak SLA. Są odpowiednie
do developmentu, ale zawiodą w produkcyjnych płatnościach — to jak próba
uruchomienia procesora płatności przez współdzielone API bez gwarancji
dostępności.
Nigdy nie używaj publicznego RPC w produkcji
Korzystaj z prywatnego dostawcy RPC dla niezawodnego i niskolatencyjnego dostępu.
Wybierając dostawcę RPC, zwróć uwagę na:
- Niezawodność: SLA z gwarancją dostępności (99,9%+)
- Opóźnienia: Bliskość geograficzna do użytkowników
- Funkcje: Funkcje szybkiego zatwierdzania transakcji, indeksowanie, API opłat priorytetowych
Pełną listę dostawców RPC znajdziesz w przewodniku RPC Infrastructure Providers.
Redundantna konfiguracja RPC
Jak każdy dostawca usług sieciowych, dostawcy RPC mogą mieć przestoje lub okresy pogorszonej wydajności. Aby Twoja aplikacja była odporna, skonfiguruj ją do korzystania z wielu dostawców RPC.
Solana Kit to biblioteka umożliwiająca dostosowanie transportu RPC, co pozwala zbudować własnego redundantnego klienta RPC. Oto przykład, jak można jej użyć do stworzenia redundantnego klienta RPC:
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);}
Jeśli nie chcesz budować własnych narzędzi do routingu, możesz skorzystać z usług firm trzecich, takich jak Iron Forge, aby obsłużyć routing za Ciebie.
Lądowanie transakcji
Na Devnecie transakcje są realizowane dość łatwo. Na Mainnecie konkurujesz o miejsce w bloku. Aby zwiększyć szanse na włączenie transakcji do bloku, powinieneś upewnić się, że transakcja została poprawnie złożona. Oznacza to:
- dołączenie świeżego blockhasha przed wysłaniem transakcji
- dodanie instrukcji opłaty priorytetowej z konkurencyjną opłatą priorytetową
- dodanie instrukcji limitu jednostek obliczeniowych z limitem opartym na szacowanej liczbie jednostek obliczeniowych wymaganych dla transakcji
Dodatkowo warto rozważyć inne narzędzia, takie jak Jito Bundles, aby zwiększyć szanse na włączenie transakcji do bloku. Przyjrzyjmy się tym narzędziom bliżej.
Konfiguracja wysyłania transakcji
Wysyłając transakcje na Mainnecie, skonfiguruj te parametry, aby uzyskać optymalny wskaźnik lądowania:
Zarządzanie blockhashem:
- Pobierz z
confirmedcommitment - Zapisz
lastValidBlockHeightzwrócony przezgetLatestBlockhash— to informuje, kiedy Twoja transakcja wygaśnie - Blockhashe wygasają po ok. 150 blokach (ok. 60–90 sekund)
Opcje wysyłania:
maxRetries: 0— Wyłącz automatyczne ponawianie RPC. Obsłuż ponowienia samodzielnie, aby móc odświeżyć blockhash w razie potrzeby.skipPreflight: true— Pomijaj symulację przed wysłaniem. Użyj tego, jeśli transakcja została już zweryfikowana i zależy Ci na najniższym opóźnieniu. Pozostaw tofalsepodczas developmentu, aby wcześnie wychwycić błędy.
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
Używaj opłat priorytetowych
Każda transakcja w sieci Solana wymaga opłaty transakcyjnej, płatnej w SOL. Opłaty transakcyjne dzielą się na dwie części: opłatę bazową i opłatę priorytetową. Opłata bazowa rekompensuje walidatorom przetwarzanie transakcji. Opłata priorytetowa to opcjonalna opłata, która zwiększa szansę, że obecny lider przetworzy Twoją transakcję. Można to porównać do ekspresowej wysyłki: płacisz więcej za szybszą i bardziej niezawodną realizację.
Jak działają opłaty:
Total fee = Base fee (5,000 lamports per signature) + Priority feePriority fee = Compute units x Price per unit (micro-lamports per compute unit)
Koszty w praktyce:
- Prosty transfer USDC: ~0,001-0,005 USD w normalnych warunkach
- W czasie przeciążenia: ~0,01-0,05 USD
- Szczytowe przeciążenie: Może wzrosnąć jeszcze bardziej
Przykładowa implementacja:
Pakiet
@solana-program/compute-budget
udostępnia funkcję pomocniczą, która pozwala łatwo zaktualizować lub dodać
instrukcję ceny jednostki obliczeniowej (w mikro-lamportach) do transakcji.
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));
Jak uzyskać szacunkowe opłaty: Większość dostawców RPC oferuje API opłat priorytetowych:
Pełną mechanikę opłat znajdziesz w Opłaty transakcyjne oraz w naszym przewodniku: Jak dodać opłaty priorytetowe do transakcji.
Optymalizuj jednostki obliczeniowe
Obliczenia na Solanie to w praktyce miara ilości pracy wykonywanej przez program. Istnieje limit ilości obliczeń, które można wykorzystać w jednej transakcji (obecnie 1,4 miliona jednostek obliczeniowych) oraz limit na ilość obliczeń na konto na blok (obecnie 100 milionów jednostek obliczeniowych).
Podczas wysyłania transakcji musisz oszacować ilość jednostek obliczeniowych, które zostaną użyte, i odpowiednio ustawić limit jednostek obliczeniowych – jest to w praktyce prośba o zarezerwowanie określonej części całkowitej pojemności dla Twojej transakcji. W praktyce oznacza to, że prawidłowe oszacowanie wymaganych jednostek obliczeniowych jest kluczowe, aby Twoja transakcja została uwzględniona w bloku (i ważne dla zarządzania opłatami priorytetowymi).
Solana JSON RPC API posiada metodę
simulatetransaction, która może być
używana do szacowania jednostek obliczeniowych wymaganych przez transakcję, co
obejmuje szacunkową liczbę jednostek obliczeniowych, które zostaną użyte.
@solana/kit dostarcza funkcje pomocnicze,
które szacują limity zasobów transakcji i ustawiają je w wiadomości w jednym
kroku (używając metody simulatetransaction pod spodem). W przypadku transakcji
w wersji 1 te funkcje pomocnicze szacują również limit rozmiaru danych
załadowanych kont.
import {estimateResourceLimitsFactory,estimateAndSetResourceLimitsFactory} from "@solana/kit";const estimateResourceLimits = estimateResourceLimitsFactory({ rpc });const estimateAndSetResourceLimits = estimateAndSetResourceLimitsFactory(estimateResourceLimits);const txWithResourceLimits = await estimateAndSetResourceLimits(tx);
Jeśli budujesz i wysyłasz transakcje za pomocą klienta z wtyczką kit,
zazwyczaj nie potrzebujesz tego kroku — klient automatycznie dodaje instrukcje
budżetu obliczeniowego podczas wysyłania (.sendTransaction()). Powyższy
ręczny przepływ jest przeznaczony dla przypadków, gdy transakcje składane są
bezpośrednio za pomocą @solana/kit.
W środowisku produkcyjnym, jeśli wielokrotnie powtarzasz ten sam typ transakcji, powinieneś rozważyć buforowanie szacunku obliczeniowego dla danego typu transakcji, aby uniknąć narzutu związanego z każdorazowym szacowaniem jednostek obliczeniowych.
Pakiety Jito
Pakiety Jito to narzędzie do zarządzania atomowym wykonaniem wielu transakcji. Osiąga się to poprzez wysyłanie wielu transakcji do sieci Jito wraz z naplwą. Napiwki mogą być wykorzystywane do zachęcania sieci Jito do uwzględnienia Twoich transakcji w bloku.
Zasoby:
Strategie Ponownych Prób
Transakcje mogą się nie powieść z wielu powodów. W przeciwieństwie do tradycyjnych API płatności, które natychmiast zwracają wynik sukcesu/niepowodzenia, transakcje blockchain wymagają śledzenia potwierdzenia.
Kluczowe pojęcia:
- Wygaśnięcie blockhasha: Transakcje są ważne przez ~150 bloków (~60–90 sekund)
- Idempotentność: Ta sama podpisana transakcja zawsze generuje ten sam podpis — ponowne wysłanie jest bezpieczne
- Wykładniczy backoff: Unikaj przeciążania sieci przez szybkie ponowne próby
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;}
sendAndConfirmTransactionFactory z @solana/kit automatycznie obsługuje
polling potwierdzenia i śledzenie wysokości bloku. Zgłasza
SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED gdy blockhash transakcji wygasa,
sygnalizując konieczność przebudowania transakcji z nowym blockhash.
Dodatkowe zasoby
- Przewodnik: Potwierdzanie i wygasanie transakcji
- Helius: Jak przeprowadzać transakcje na Solanie
- QuickNode: Strategie optymalizacji transakcji Solana
Poziomy potwierdzenia
Solana oferuje trzy poziomy potwierdzenia. W terminologii tradycyjnych finansów:
| Poziom | Definicja Solana | Odpowiednik tradycyjny | Przypadek użycia |
|---|---|---|---|
processed | W bloku, bez głosowania | Autoryzacja oczekująca | Aktualizacje UI w czasie rzeczywistym |
confirmed | Głosowanie superwikszości | Środki rozliczone | Większość płatności |
finalized | Zakorzeniony, nieodwracalny | Środki rozrachowane | Wysokie kwoty, zgodność |
Kiedy używać każdego z nich:
- Aktualizacje UI: Pokazuj
processeddla natychmiastowej informacji zwrotnej ("Płatność przesłana") - Uznanie konta użytkownika: Czekaj na
confirmed(bezpieczne dla większości transakcji) - Wysyłka towarów fizycznych: Czekaj na
finalized - Duże wypłaty: Czekaj na
finalized - Zgodność/audyt: Zawsze rejestruj status
finalized
Więcej informacji na temat sprawdzania statusu transakcji znajdziesz w Interakcja z Solaną.
Obsługa błędów
Solana Kit udostępnia typowane błędy za pomocą isSolanaError(). Używaj
konkretnych kodów błędów zamiast dopasowywania ciągów znaków:
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 };}
Typowe kody błędów:
| Kod błędu | Przyczyna | Rozwiązanie |
|---|---|---|
BLOCK_HEIGHT_EXCEEDED | Blockhash wygasł | Przebuduj z nowym blockhash |
BLOCKHASH_NOT_FOUND | Blockhash nie znaleziony | Przebuduj z nowym blockhash |
INSUFFICIENT_FUNDS_FOR_FEE | Za mało SOL | Doładuj płatnika opłat lub użyj abstrakcji opłat |
INSUFFICIENT_FUNDS | Za mało tokenów | Użytkownik potrzebuje większego salda |
ACCOUNT_NOT_FOUND | Brak token account | Utwórz ATA w transakcji |
Transakcje bez opłat gazowych
Użytkownicy oczekują możliwości płacenia w stablecoinach, a nie zdobywania SOL na pokrycie opłat sieciowych. Transakcje bez opłat gazowych rozwiązują ten problem — podobnie jak użytkownicy Venmo nie zastanawiają się nad opłatami ACH. Siehe Abstrakcja opłat aby zapoznać się z pełną implementacją.
Bezpieczeństwo
Zarządzanie kluczami
- Nigdy nie ujawniaj kluczy prywatnych w kodzie frontendowym. Używaj podpisywania po stronie backendu, portfeli sprzętowych, portfeli wielopodpisowych lub usług zarządzania kluczami.
- Rozdzielaj portfele hot i cold. Portfel hot do operacji bieżących, cold do przechowywania środków.
- Twórz kopie zapasowe wszystkich kluczy produkcyjnych. Przechowuj zaszyfrowane kopie zapasowe w wielu bezpiecznych lokalizacjach. Utrata klucza oznacza trwałą utratę dostępu.
- Używaj różnych kluczy dla devnet i mainnet. Klucze devnet nie powinny być tymi samymi kluczami co mainnet. Używaj konfiguracji opartej na środowisku, aby zapewnić ładowanie właściwych kluczy dla każdej sieci.
Infrastruktura podpisywania
Do produkcyjnego podpisywania po stronie backendu używaj Keychain — ujednoliconej biblioteki do podpisywania, która abstrahuje wiele backendów zarządzania kluczami przez jeden interfejs: Memory, Vault, Privy, Turnkey, AWS KMS, Fireblocks, GCP KMS, CDP, Para, Dfns, Crossmint, Openfort i Utila. Dzięki temu możesz lokalnie tworzyć aplikacje z kluczami w pamięci, a następnie przełączyć się na produkcyjne backendy bez zmiany kodu aplikacji.
Nie wiesz, który backend wybrać? Zobacz Wybór backendu. Keychain jest dostępny zarówno dla Rust, jak i TypeScript.
Bezpieczeństwo RPC
Traktuj endpointy RPC jak klucze API—nie ujawniaj ich w kodzie frontendowym, gdzie mogą zostać wydobyte i nadużyte. Użyj proxy backendowego lub zmiennych środowiskowych, które nie są pakowane do kodu klienta.
- QuickNode: Najlepsze praktyki bezpieczeństwa endpointów
- Helius: Chroń swoje klucze API Solana: Najlepsze praktyki bezpieczeństwa
Monitorowanie
Śledź te metryki w środowisku produkcyjnym:
| Metryka | Dlaczego |
|---|---|
| Wskaźnik sukcesu transakcji | Wczesne wykrywanie problemów |
| Opóźnienie potwierdzenia | Monitorowanie zdrowia sieci |
| Wydatki na opłatę priorytetową | Zarządzanie kosztami |
| Wskaźnik błędów RPC | Zdrowie dostawcy |
Skonfiguruj alerty dla:
- Transferów powyżej progu z treasury
- Gwałtownych wzrostów wskaźnika nieudanych transakcji
- Nietypowych wzorców odbiorców
- Wzrostów wskaźnika błędów RPC
W celu monitorowania transakcji w czasie rzeczywistym na dużą skalę zobacz nasz przewodnik po indeksowaniu.
Weryfikuj adresy
Każdy token i program ma dokładnie jeden poprawny adres na mainnecie. Sfałszowane tokeny imitujące USDC lub inne stablecoiny są powszechne—będą miały tę samą nazwę i symbol, ale inny adres mint. Twoja aplikacja powinna zakodować na stałe lub umieścić na liście dozwolonych adresy mint (w zależności od wymagań), nigdy nie akceptuj ich dynamicznie z niezaufanych źródeł.
Konfiguracja oparta na środowisku: Devnet i Mainnet często używają całkowicie różnych mintów tokenów. Skonfiguruj swoją aplikację tak, aby ładowała właściwe adresy dla każdego środowiska—nie koduj na sztywno adresów mainnet i nie zapomnij o ich zamianie podczas testowania, a co gorsza, nie wysyłaj adresów devnet do produkcji.
Niektóre popularne minty stablecoinów to:
| Token | Emitent | Adres Mint |
|---|---|---|
| USDC | Circle | EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v |
| USDT | Tether | Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB |
| PYUSD | PayPal | 2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo |
| USDG | Paxos | 2u1tszSeqZ3qBWF3uNGPFc8TzMk2tdiwknnRMWGWjGWH |
Adresy programów również mają znaczenie. Wysyłanie instrukcji do niewłaściwego programu zakończy się niepowodzeniem—lub co gorsza, spowoduje nieodwracalną utratę środków. Adresy Token Program to:
| Program | Adres |
|---|---|
| Token Program | TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA |
| Token-2022 Program | TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb |
Umieszczenie właściwych adresów na liście dozwolonych chroni przed sfałszowanymi tokenami, ale nie zabezpiecza przed wysłaniem środków na niewłaściwy rodzaj konta. Adres odbiorcy może być portfelem, token account, mennicą lub programem, a każdy wymaga odrębnej obsługi. Natywne SOL wysłane na cokolwiek innego niż portfel wymyka się spod kontroli nadawcy — bezpowrotnie utracone w przypadku mennicy lub programu, możliwe do odzyskania jedynie przez właściciela konta w przypadku token account — bez żadnej nieudanej transakcji, która ostrzegłaby użytkownika.
Zweryfikuj odbiorców przed wysłaniem
Sklasyfikuj każdy adres odbiorcy przed podpisaniem przelewu. Zobacz Weryfikacja adresu, aby zapoznać się z pełnym drzewem decyzyjnym i kodem referencyjnym rozróżniającym portfele, token accounts, mennice i programy.
Lista kontrolna przed uruchomieniem
- Pozyskano SOL w sieci mainnet na opłaty i rent
- Skonfigurowano produkcyjny RPC (nie publiczny endpoint)
- Skonfigurowano zapasowy endpoint RPC
- Zaimplementowano opłaty priorytetowe z dynamicznym ustalaniem cen
- Logika ponawiania obsługuje wygaśnięcie blockhasha
- Poziom potwierdzenia odpowiedni dla przypadku użycia
- Wszystkie typowe błędy obsługiwane w sposób prawidłowy
- Skonfigurowano Gasless (jeśli dotyczy)
- Zweryfikowano adresy tokenów w sieci mainnet (nie mints devnet)
- Walidacja adresu odbiorcy przed wysłaniem (portfel vs token account vs mint vs program)
- Wszystkie klucze bezpiecznie zarchiwizowane
- Przegląd zarządzania kluczami (brak kluczy we frontendzie)
- Aktywny monitoring transakcji i alerty
- Przeprowadzono testy obciążeniowe przy oczekiwanym wolumenie
Wdrażanie programów
Jeśli wdrażasz niestandardowy program Solana jako część swojej infrastruktury płatności, istnieją dodatkowe kwestie do rozważenia.
Przed wdrożeniem
- Wersja Solana CLI: Upewnij się, że używasz najnowszej wersji Solana CLI.
- keypair programu: Twój program będzie miał inny adres w sieci mainnet niż
w devnet (chyba że ponownie używasz tego samego keypair). Zaktualizuj
wszystkie odwołania w konfiguracji swojej aplikacji. Przechowuj keypair
programu w bezpiecznym miejscu (pamiętaj, że uruchomienie
cargo cleanprawdopodobnie usunie Twój keypair programu). - Inicjalizacja kont: Jeśli Twój program wymaga kont administratora, PDA lub innych kont stanu, upewnij się, że zostały one utworzone w sieci mainnet, zanim użytkownicy zaczną korzystać z Twojej aplikacji. To samo dotyczy wszelkich associated token accounts (ATA), których wymaga Twój program.
Proces wdrożenia
- Konta buforowe: Duże programy wdrażane są za pośrednictwem kont
buforowych. Polecenie
solana program deployobsługuje to automatycznie, jednak należy pamiętać, że wdrożenie nie jest atomowe — w razie przerwania może być konieczne odzyskanie lub zamknięcie kont buforowych. Zobacz Wdrażanie programów. - Uprawnienia do aktualizacji: Zdecyduj, czy Twój program powinien być aktualizowalny po uruchomieniu. Aby zapewnić niezmienność, cofnij uprawnienia do aktualizacji po wdrożeniu. Dla większej elastyczności odpowiednio zabezpiecz klucz uprawnień do aktualizacji.
- Czynsz: Upewnij się, że Twój portfel wdrożeniowy ma wystarczająco dużo SOL, aby pokryć minimalne wymagania zwolnienia z czynszu dla wszystkich program accounts.
- Weryfikacja: Zweryfikuj swój program, aby upewnić się, że wdrożony w sieci Solana program wykonywalny odpowiada kodowi źródłowemu w Twoim repozytorium
Pełne wskazówki dotyczące wdrażania programów znajdziesz w Wdrażanie programów.
Is this page helpful?