Halaman ini diterjemahkan secara otomatis oleh AI. Versi bahasa Inggris adalah acuan resmi.Lihat versi bahasa Inggris →
PDA (program-derived addresses) dan CPI (cross-program invocation) adalah dua primitif yang membuat Raydium mungkin. PDA memungkinkan program untuk “memiliki” alamat deterministik tanpa kunci privat — itulah cara kerja pool authorities dan vaults. CPI memungkinkan satu program memanggil program lain — itulah cara Raydium menukar token melalui program SPL Token dan bagaimana integrator menggabungkan Raydium ke dalam alur mereka sendiri. Keduanya layak dipahami sebelum membaca kode sumber Raydium.
PDA: alamat tanpa kunci
Program-Derived Address adalah kunci publik yang:- Tidak berada di kurva ed25519 (tidak ada kunci privat untuk itu).
- Diturunkan secara deterministik dari ID program dan serangkaian seeds.
- Dapat ditandatangani hanya oleh program penurunan, melalui
invoke_signed.
Penurunan
PDA dihitung dengan melakukan hash pada ID program dengan seeds, kemudian menemukan byte “bump” yang memaksa hasil keluar dari kurva. Bump pertama (biasanya dimulai dari 255 dan menurun) yang menghasilkan alamat off-curve menang; ini adalah canonical bump.u64 sebagai byte little-endian. Konvensi Raydium adalah awalan yang dapat dibaca manusia diikuti oleh pengenal unik.
Pola PDA Raydium
PDA umum dalam program Raydium:
Pengguna dan integrator dapat menghitung ini tanpa mengambil apa pun — mengingat input publik (pool ID, farm ID, user key), PDA bersifat deterministik.
Canonical bump
Meskipun secara prinsip dapat ada beberapa bump yang menghasilkan alamat off-curve, program Raydium selalu menggunakan canonical bump (ditemukan dengan menurun dari 255). Ini disimpan dalam data akun PDA sehingga transaksi berikutnya dapat meneruskannya dan melewati loop derivasi yang (mahal):PoolState menyimpan bump: [u8; 1] sebagai gantinya, jadi periksa struct program spesifik daripada mengasumsikan satu bentuk.)
Pada transaksi berikutnya, bump dibaca dari state pool daripada dihitung ulang.
CPI: memanggil program lain
Cross-Program Invocation memungkinkan program untuk memanggil instruksi program lain secara inline dalam satu transaksi. Raydium menggunakan CPI secara ekstensif:- Instruksi swap memanggil program SPL Token untuk memindahkan token.
- CLMM memanggil Metaplex untuk mencetak position NFT.
- Pembuatan pool memanggil System Program untuk mengalokasikan akun.
- Farm v6 memanggil SPL Token untuk mentransfer reward.
integration-guides/cpi-integration.
invoke vs invoke_signed
Runtime Solana menawarkan dua primitif CPI:invoke: panggil program lain; program yang dipanggil mewarisi penandatangan transaksi luar.invoke_signed: panggil program lain atas nama PDA; runtime memverifikasi seeds PDA dan mengotorisasi tanda tangan.
invoke_signed adalah keajaiban yang memungkinkan program untuk memegang otoritas atas akun tanpa mengelola kunci privat.
Contoh: Raydium mentransfer dari pool vault
Pool vault adalah Token Account yang otoritasnya adalah PDA dari program pool. Untuk mentransfer token keluar selama swap, program pool harus menandatangani sebagai PDA itu:invoke_signed dipanggil oleh program CPMM, memverifikasi bahwa vault_and_lp_mint_auth_seed + bump diturunkan ke alamat pool_authority ketika di-hash dengan ID program CPMM, dan mengizinkan tanda tangan otoritas pada transfer token. Tidak ada kunci privat yang terlibat.
Contoh: integrator memanggil Raydium CPMM
Program integrator (misalnya, escrow) dapat memanggilswap_base_input Raydium melalui CPI:
integration-guides/cpi-integration untuk contoh escrow lengkap.
Batas kedalaman CPI
Solana membatasi kedalaman CPI pada 4 level. Instruksi tingkat atas transaksi dihitung sebagai kedalaman 0; setiap invokasi CPI menambah kedalaman. Implikasi praktis: swap Raydium sendiri sudah menggunakan 1-2 level CPI (Raydium → SPL Token). Integrator yang memanggil Raydium menggunakan 2. Jika integrator itu dipanggil oleh integrator lain, itu 3. Level ke-4 adalah batasnya. Sebagian besar komposisi tetap di bawah ini dengan mudah, tetapi nesting dalam (aggregator → router → Raydium → hook) dapat mencapainya. Desain datar daripada dalam.Akun sisa
Ketika instruksi Raydium membutuhkan jumlah akun yang variabel (misalnya, CLMM swap melintasi jumlah tick array yang tidak diketahui), akun tambahan dilewatkan sebagai remaining accounts — ditambahkan ke daftar akun tetap, diinterpretasikan berdasarkan posisi.SwapV2 CPMM menggunakan remaining accounts untuk akun tambahan yang diperlukan program transfer-hook. Klien mengambil akun yang diperlukan dan menambahkannya:
Jebakan PDA
Seeds salah → alamat salah
Bug di mana seeds berada dalam urutan yang salah, encoding yang salah, atau menyertakan/mengecualikan byte tambahan secara diam-diam menghasilkan PDA yang berbeda. Transaksi gagal secara ambigu (program mencoba membaca akun yang tidak ada). Selalu unit-test derivasi seed terhadap nilai golden yang diketahui.Tidak menyimpan bump
Jika Anda menurunkan bump pada setiap transaksi, Anda membayar compute untuk loop derivasi. Simpan canonical bump dalam data PDA dan bacanya dari sana.Membingungkan canonical vs non-canonical bump
Non-canonical bumps (jika ada yang menemukan satu yang menghasilkan off-curve) diizinkan olehinvoke_signed tetapi ditolak oleh program Raydium melalui assert_eq!(bump, canonical_bump). Jika seseorang mencoba mengklaim PDA dengan bump non-canonical, tx gagal.
Melewatkan PDA sebagai penandatangan ketika Anda bukan program pemilik
Hanya program yang ID-nya ada dalam derivasi PDA yang dapatinvoke_signed dengan seeds-nya. Jika Anda mencoba, runtime menolak.
Jebakan CPI
Lupa meneruskan remaining_accounts
Jika instruksi luar Anda melewatkan akun transfer-hook dalam remaining_accounts tetapi CPI ke Raydium tidak meneruskannya, Raydium gagal karena tidak dapat menemukan akun hook. Selalu sertakan with_remaining_accounts dalam CPI yang membutuhkannya.
Ketidakcocokan flag writable
Akun yang instruksi luar tandai writable juga harus writable dalam panggilan CPI jika program yang dipanggil bermaksud menulisnya. Ketidakcocokan → penolakan runtime.Tidak memperhitungkan rent
CPI ke program yang membuat akun (misalnya, pembuatan ATA) memerlukan payer memiliki cukup SOL untuk rent. Pemeriksaan rent yang gagal muncul sebagai error yang tidak jelas.Contoh kerja: menghitung PDA CPMM Raydium
getPoolInfoFromRpc({ poolId }) — ia menurunkan PDA terkait tanpa round-trip.
Penunjuk
solana-fundamentals/account-model— bagaimana PDA cocok dalam model akun.solana-fundamentals/programs-and-anchor— pembantu Anchor untuk mendeklarasikan PDA.integration-guides/cpi-integration— membangun integrasi yang CPI ke dalam Raydium.sdk-api/rust-cpi— tipe Rust CPI Raydium.
- Dokumen PDA Solana.
- Dokumen CPI Solana.
- Dokumen PDA Anchor dan Dokumen CPI Anchor — Anchor tidak memiliki halaman gabungan.

