Membangun secara lokal dan menguji di devnet adalah cara yang bagus untuk memulai dengan pembayaran Solana. Namun, ketika Anda siap untuk deploy ke Mainnet, Anda perlu memahami nuansa mainnet. Devnet memaafkan kesalahan. Mainnet tidak. Panduan ini mencakup perbedaan yang penting untuk memastikan pengguna Anda memiliki pengalaman yang lancar.
| Devnet | Mainnet |
|---|---|
| SOL gratis dari faucet | Dapatkan SOL asli untuk biaya |
| Kompetisi rendah untuk ruang blok | Biaya prioritas penting |
| Transaksi berhasil dengan mudah | Konfigurasi transaksi sangat penting |
| RPC publik sudah cukup | RPC produksi diperlukan |
| Keypair dan mint devnet | Kunci dan token mint berbeda—perbarui konfigurasi Anda |
Infrastruktur RPC
Endpoint publik
(api.mainnet-beta.solana.com) dibatasi rate dengan tanpa SLA. Mereka baik
untuk pengembangan tetapi akan gagal dalam alur pembayaran produksi—seperti
mencoba menjalankan prosesor pembayaran melalui API bersama tanpa jaminan
uptime.
Jangan pernah gunakan RPC publik untuk produksi
Gunakan penyedia RPC privat untuk akses yang andal dan latensi rendah.
Saat memilih penyedia RPC, perhatikan:
- Keandalan: SLA dengan jaminan uptime (99,9%+)
- Latensi: Kedekatan geografis dengan pengguna Anda
- Fitur: Fitur transaction landing, indexing, API biaya prioritas
Untuk daftar lengkap penyedia RPC, lihat panduan Penyedia Infrastruktur RPC.
Konfigurasi RPC redundan
Seperti penyedia layanan jaringan lainnya, penyedia RPC dapat mengalami downtime atau periode performa yang menurun. Untuk memastikan aplikasi Anda tangguh, Anda harus mengonfigurasi aplikasi Anda untuk menggunakan beberapa penyedia RPC.
Solana Kit menyediakan library untuk menyesuaikan transport RPC yang memungkinkan Anda membangun klien RPC redundan Anda sendiri. Berikut adalah contoh bagaimana Anda dapat menggunakannya untuk membangun klien RPC redundan:
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);}
Jika Anda lebih memilih untuk tidak membangun alat routing Anda sendiri, Anda dapat memanfaatkan layanan pihak ketiga seperti Iron Forge untuk menangani routing untuk Anda.
Transaction landing
Di Devnet, transaksi berhasil dengan cukup mudah. Di Mainnet, Anda bersaing untuk ruang blok. Untuk meningkatkan peluang transaksi Anda dimasukkan ke dalam blok, Anda harus memastikan telah merakit transaksi Anda dengan benar. Ini berarti:
- menyertakan blockhash yang segar sebelum mengirim transaksi
- menyertakan instruksi priority fee dalam transaksi dengan priority fee yang kompetitif
- menyertakan instruksi compute unit limit dalam transaksi dengan compute unit limit berdasarkan estimasi compute unit yang diperlukan untuk transaksi
Selain itu, Anda harus mempertimbangkan alat lain seperti Jito Bundles untuk meningkatkan peluang transaksi Anda dimasukkan ke dalam blok. Mari kita jelajahi alat-alat ini lebih detail.
Konfigurasi pengiriman transaksi
Saat mengirim transaksi di Mainnet, konfigurasikan parameter berikut untuk tingkat landing yang optimal:
Manajemen blockhash:
- Ambil dengan komitmen
confirmed - Simpan
lastValidBlockHeightyang dikembalikan olehgetLatestBlockhash—ini memberi tahu Anda kapan transaksi Anda kedaluwarsa - Blockhash kedaluwarsa setelah ~150 blok (~60-90 detik)
Opsi pengiriman:
maxRetries: 0— Nonaktifkan retry RPC otomatis. Tangani retry sendiri sehingga Anda dapat memperbarui blockhash saat diperlukan.skipPreflight: true— Lewati simulasi sebelum mengirim. Gunakan ini ketika Anda sudah memvalidasi transaksi dan menginginkan latensi terendah. Tetap gunakanfalseselama pengembangan untuk menangkap error lebih awal.
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
Gunakan biaya prioritas
Setiap transaksi Solana memerlukan biaya transaksi, yang dibayar dalam SOL. Biaya transaksi dibagi menjadi dua bagian: biaya dasar dan biaya prioritas. Biaya dasar mengompensasi validator untuk memproses transaksi. Biaya prioritas adalah biaya opsional, untuk meningkatkan peluang agar leader saat ini akan memproses transaksi Anda. Anggap saja seperti pengiriman ekspres: Anda membayar lebih untuk pengiriman yang lebih cepat dan lebih andal.
Cara kerja biaya:
Total fee = Base fee (5,000 lamports per signature) + Priority feePriority fee = Compute units x Price per unit (micro-lamports per compute unit)
Biaya di dunia nyata:
- Transfer USDC sederhana: ~$0.001-0.005 selama kondisi normal
- Selama kemacetan: ~$0.01-0.05
- Kemacetan puncak: Dapat melonjak lebih tinggi
Contoh implementasi:
Paket
@solana-program/compute-budget
menyediakan fungsi helper untuk dengan mudah memperbarui atau menambahkan
instruksi harga unit komputasi (dalam micro-lamport) ke transaksi.
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));
Mendapatkan estimasi biaya: Sebagian besar penyedia RPC menawarkan API biaya prioritas:
Untuk mekanisme biaya lengkap, lihat biaya transaksi dan panduan kami: cara menambahkan biaya prioritas ke transaksi.
Optimalkan unit komputasi
Komputasi di Solana secara efektif adalah ukuran jumlah pekerjaan yang dilakukan program. Ada batasan jumlah komputasi yang dapat digunakan dalam transaksi (saat ini 1,4 juta unit komputasi), dan batasan jumlah komputasi yang dapat digunakan per akun per blok (saat ini 100 juta unit komputasi).
Ketika Anda mengirimkan transaksi, Anda perlu memperkirakan jumlah komputasi yang akan digunakan, dan menetapkan batas unit komputasi yang sesuai - ini secara efektif adalah permintaan untuk berapa banyak dari total kapasitas yang harus dicadangkan untuk transaksi Anda. Dalam praktiknya, ini berarti memperkirakan unit komputasi yang diperlukan untuk transaksi Anda dengan benar sangat penting agar transaksi Anda dimasukkan dalam blok (dan penting untuk mengelola biaya prioritas Anda).
Solana JSON RPC API memiliki metode
simulatetransaction yang dapat digunakan
untuk memperkirakan unit komputasi yang diperlukan oleh suatu transaksi, yang
mencakup perkiraan unit komputasi yang akan digunakan.
@solana/kit menyediakan fungsi pembantu
yang memperkirakan batas sumber daya transaksi dan menetapkannya pada pesan
dalam satu langkah (menggunakan metode simulatetransaction di balik layar).
Untuk transaksi versi 1, pembantu ini juga memperkirakan batas ukuran data akun
yang dimuat.
import {estimateResourceLimitsFactory,estimateAndSetResourceLimitsFactory} from "@solana/kit";const estimateResourceLimits = estimateResourceLimitsFactory({ rpc });const estimateAndSetResourceLimits = estimateAndSetResourceLimitsFactory(estimateResourceLimits);const txWithResourceLimits = await estimateAndSetResourceLimits(tx);
Jika Anda membangun dan mengirim transaksi dengan klien plugin kit, biasanya
Anda tidak perlu langkah ini — klien secara otomatis menambahkan instruksi
anggaran komputasi saat mengirim (.sendTransaction()). Alur manual di atas
digunakan saat Anda menyusun transaksi secara langsung dengan @solana/kit.
Dalam produksi, jika Anda mengulangi jenis transaksi yang sama berkali-kali, pertimbangkan untuk menyimpan cache perkiraan komputasi untuk jenis transaksi tersebut guna menghindari overhead estimasi unit komputasi setiap kali.
Jito Bundles
Jito bundles adalah alat untuk mengelola eksekusi atomik dari beberapa transaksi. Hal ini dicapai dengan mengirimkan beberapa transaksi ke jaringan Jito beserta tip. Tip dapat digunakan untuk mendorong jaringan Jito agar menyertakan transaksi Anda dalam sebuah blok.
Sumber Daya:
Strategi Percobaan Ulang
Transaksi dapat gagal karena berbagai alasan. Tidak seperti API pembayaran tradisional yang langsung mengembalikan status berhasil/gagal, transaksi blockchain memerlukan pelacakan konfirmasi.
Konsep utama:
- Kedaluwarsa blockhash: Transaksi berlaku selama ~150 blok (~60-90 detik)
- Idempotency: Transaksi yang ditandatangani sama selalu menghasilkan tanda tangan yang sama — pengiriman ulang aman dilakukan
- Exponential backoff: Hindari membebani jaringan dengan percobaan ulang yang terlalu cepat
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 dari @solana/kit menangani polling
konfirmasi dan pelacakan tinggi blok secara otomatis. Fungsi ini akan melempar
SOLANA_ERROR__BLOCK_HEIGHT_EXCEEDED ketika blockhash transaksi kedaluwarsa,
memberi sinyal bahwa Anda perlu membangun ulang transaksi dengan blockhash baru.
Sumber Daya Tambahan
- Panduan: Konfirmasi & Kedaluwarsa Transaksi
- Helius: Cara Melakukan Transaksi di Solana
- QuickNode: Strategi untuk Mengoptimalkan Transaksi Solana
Memahami Tingkat Konfirmasi
Solana menawarkan tiga tingkat konfirmasi. Dalam istilah keuangan tradisional:
| Level | Definisi Solana | Padanan Tradisional | Kasus Penggunaan |
|---|---|---|---|
processed | Dalam blok, belum divoting | Otorisasi tertunda | Pembaruan UI real-time |
confirmed | Supermayoritas telah voting | Dana telah dikliringkan | Sebagian besar pembayaran |
finalized | Sudah di-root, tidak dapat dibatalkan | Dana telah diselesaikan | Nilai tinggi, kepatuhan |
Kapan menggunakan masing-masing:
- Pembaruan UI: Tampilkan
processeduntuk umpan balik segera ("Pembayaran telah dikirim") - Kredit akun pengguna: Tunggu
confirmed(aman untuk sebagian besar transaksi) - Kirim barang fisik: Tunggu
finalized - Penarikan dalam jumlah besar: Tunggu
finalized - Kepatuhan/audit: Selalu catat status
finalized
Untuk informasi lebih lanjut tentang memeriksa status transaksi, lihat Berinteraksi dengan Solana.
Penanganan Kesalahan
Solana Kit menyediakan error berupa tipe melalui isSolanaError(). Gunakan kode
error spesifik alih-alih pencocokan string:
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 };}
Kode Error Umum:
| Kode Error | Penyebab | Pemulihan |
|---|---|---|
BLOCK_HEIGHT_EXCEEDED | Blockhash kedaluwarsa | Bangun ulang dengan blockhash baru |
BLOCKHASH_NOT_FOUND | Blockhash tidak ditemukan | Bangun ulang dengan blockhash baru |
INSUFFICIENT_FUNDS_FOR_FEE | SOL tidak mencukupi | Isi saldo fee payer atau gunakan abstraksi biaya |
INSUFFICIENT_FUNDS | Token tidak mencukupi | Pengguna memerlukan saldo lebih banyak |
ACCOUNT_NOT_FOUND | token account tidak ada | Buat ATA dalam transaksi |
Transaksi Tanpa Gas
Pengguna mengharapkan pembayaran menggunakan stablecoin, bukan harus memperoleh SOL untuk biaya jaringan. Transaksi tanpa gas mengatasi masalah ini—mirip dengan bagaimana pengguna Venmo tidak perlu memikirkan biaya ACH. Lihat Abstraksi Biaya untuk implementasi lengkapnya.
Keamanan
Manajemen Kunci
- Jangan pernah mengekspos kunci privat dalam kode frontend. Gunakan penandatanganan backend, dompet perangkat keras, dompet multitanda tangan, atau layanan manajemen kunci.
- Pisahkan dompet panas dan dompet dingin. Dompet panas untuk operasional, dompet dingin untuk perbendaharaan.
- Buat cadangan semua kunci produksi. Simpan cadangan terenkripsi di beberapa lokasi yang aman. Kehilangan kunci berarti kehilangan akses secara permanen.
- Gunakan kunci yang berbeda untuk devnet dan mainnet. Kunci devnet Anda seharusnya tidak sama dengan kunci mainnet Anda. Gunakan konfigurasi berbasis lingkungan untuk memastikan kunci yang tepat dimuat di setiap jaringan.
Infrastruktur Penandatanganan
Untuk penandatanganan backend produksi, gunakan Keychain—sebuah pustaka penandatanganan terpadu yang mengabstraksi berbagai backend manajemen kunci melalui satu antarmuka: Memory, Vault, Privy, Turnkey, AWS KMS, Fireblocks, GCP KMS, CDP, Para, Dfns, Crossmint, Openfort, dan Utila. Ini memungkinkan Anda mengembangkan secara lokal menggunakan kunci in-memory, lalu beralih ke backend kelas produksi tanpa mengubah kode aplikasi.
Tidak yakin backend mana yang cocok? Lihat Memilih backend. Keychain tersedia untuk Rust dan TypeScript.
Keamanan RPC
Perlakukan endpoint RPC seperti API key—jangan ekspos di kode frontend dimana mereka dapat diekstrak dan disalahgunakan. Gunakan proxy backend atau variabel lingkungan yang tidak dibundel ke dalam kode klien.
- QuickNode: Praktik Terbaik Keamanan Endpoint
- Helius: Lindungi API Key Solana Anda: Praktik Terbaik Keamanan
Pemantauan
Lacak metrik-metrik berikut di produksi:
| Metrik | Alasan |
|---|---|
| Tingkat keberhasilan transaksi | Deteksi masalah lebih awal |
| Latensi konfirmasi | Pantau kesehatan jaringan |
| Pengeluaran priority fee | Manajemen biaya |
| Tingkat error RPC | Kesehatan penyedia layanan |
Siapkan peringatan untuk:
- Transfer di atas ambang batas dari treasury
- Lonjakan tingkat transaksi gagal
- Pola penerima yang tidak biasa
- Peningkatan tingkat error RPC
Untuk pemantauan transaksi real-time dalam skala besar, lihat Panduan Indexing kami.
Verifikasi Alamat
Setiap token dan program memiliki tepat satu alamat yang benar di mainnet. Token palsu yang meniru USDC atau stablecoin lainnya sangat umum—mereka akan memiliki nama dan simbol yang sama tetapi mint yang berbeda. Aplikasi Anda harus hardcode atau allowlist alamat mint (berdasarkan kebutuhan Anda), jangan pernah menerimanya secara dinamis dari sumber yang tidak terpercaya.
Konfigurasi berbasis lingkungan: Devnet dan Mainnet sering menggunakan token mint yang sepenuhnya berbeda. Siapkan konfigurasi aplikasi Anda untuk memuat alamat yang tepat per lingkungan—jangan hardcode alamat mainnet dan lupa menggantinya saat pengujian, atau lebih buruk lagi, mengirimkan alamat devnet ke produksi.
Beberapa stablecoin mint yang umum adalah:
| Token | Penerbit | Alamat Mint |
|---|---|---|
| USDC | Circle | EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v |
| USDT | Tether | Es9vMFrzaCERmJfrF4H2FYD4KCoNkY11McCe8BenwNYB |
| PYUSD | PayPal | 2b1kV6DkPAnxd5ixfnxCpjxmKwqjjaYmCZfHsFu24GXo |
| USDG | Paxos | 2u1tszSeqZ3qBWF3uNGPFc8TzMk2tdiwknnRMWGWjGWH |
Alamat program juga penting. Mengirim instruksi ke program yang salah akan gagal—atau lebih buruk, mengakibatkan kehilangan dana yang tidak dapat dipulihkan. Alamat Token Program adalah:
| Program | Alamat |
|---|---|
| Token Program | TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA |
| Token-2022 Program | TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb |
Memasukkan alamat yang tepat ke allowlist melindungi dari token palsu, tetapi tidak melindungi dari pengiriman ke jenis akun yang salah. Alamat penerima dapat berupa dompet, token account, mint, atau program, dan masing-masing memerlukan penanganan yang berbeda. SOL asli yang dikirim ke selain dompet akan lepas dari kendali pengirim — hilang sepenuhnya jika dikirim ke mint atau program, dapat dipulihkan hanya oleh pemilik akun jika dikirim ke token account — tanpa ada transaksi gagal yang memperingatkan pengguna.
Validasi penerima sebelum mengirim
Klasifikasikan setiap alamat penerima sebelum menandatangani transfer. Lihat Verifikasi Alamat untuk pohon keputusan lengkap dan kode referensi yang membedakan dompet, token account, mint, dan program.
Daftar Periksa Pra-Peluncuran
- SOL Mainnet diperoleh untuk biaya dan rent
- RPC produksi dikonfigurasi (bukan endpoint publik)
- Endpoint RPC cadangan dikonfigurasi
- Biaya prioritas diterapkan dengan penetapan harga dinamis
- Logika percobaan ulang menangani kedaluwarsa blockhash
- Tingkat konfirmasi sesuai dengan kasus penggunaan
- Semua kesalahan umum ditangani dengan baik
- Gasless dikonfigurasi (jika berlaku)
- Alamat token Mainnet diverifikasi (bukan mint devnet)
- Validasi alamat penerima sebelum mengirim (dompet vs token account vs mint vs program)
- Semua kunci dicadangkan dengan aman
- Manajemen kunci ditinjau (tidak ada kunci di frontend)
- Pemantauan dan peringatan transaksi aktif
- Diuji beban pada volume yang diharapkan
Men-deploy Program
Jika Anda men-deploy program Solana kustom sebagai bagian dari infrastruktur pembayaran Anda, ada pertimbangan tambahan yang perlu diperhatikan.
Pra-deployment
- Versi Solana CLI: Pastikan Anda menggunakan versi terbaru dari Solana CLI.
- Program keypair: Program Anda akan memiliki alamat yang berbeda di mainnet
dibandingkan devnet (kecuali Anda menggunakan keypair yang sama). Perbarui
semua referensi dalam konfigurasi aplikasi Anda. Simpan program keypair Anda
di lokasi yang aman (perlu diperhatikan bahwa menjalankan
cargo cleankemungkinan akan menghapus program keypair Anda). - Inisialisasi akun: Jika program Anda memerlukan akun admin, PDA, atau akun state lainnya, pastikan akun-akun tersebut sudah dibuat di mainnet sebelum pengguna berinteraksi dengan aplikasi Anda. Begitu pula untuk Associated Token Accounts (ATAs) yang dibutuhkan program Anda.
Proses Deployment
- Buffer accounts: Program berukuran besar dideploy melalui buffer accounts.
Perintah
solana program deploymenangani ini secara otomatis, namun perlu dipahami bahwa deployment tidak bersifat atomik—jika terganggu, Anda mungkin perlu memulihkan atau menutup buffer accounts. Lihat Deploying Programs. - Upgrade authority: Tentukan apakah program Anda harus dapat diperbarui setelah diluncurkan. Untuk ketidakberubahan, cabut upgrade authority setelah deployment. Untuk fleksibilitas, amankan kunci upgrade authority dengan tepat.
- Rent: Pastikan dompet deployment Anda memiliki cukup SOL untuk menutupi minimum rent-exempt bagi semua program account.
- Verifikasi: Verifikasi program Anda untuk memastikan bahwa program yang dapat dieksekusi yang Anda deploy ke jaringan Solana sesuai dengan kode sumber di repositori Anda
Untuk panduan lengkap deployment program, lihat Deploying Programs.
Is this page helpful?