Verifikasi alamat

Mengirim token ke alamat yang salah dapat mengakibatkan kehilangan dana secara permanen. Verifikasi alamat memastikan Anda hanya mengirim token ke alamat yang dapat menerima dan mengaksesnya dengan benar.

Lihat Cara Kerja Pembayaran di Solana untuk konsep pembayaran inti.

Memahami alamat Solana

Akun Solana memiliki dua jenis alamat, on-curve dan off-curve.

Alamat on-curve

Alamat standar adalah kunci publik dari keypair Ed25519. Alamat ini:

  • Memiliki kunci privat yang sesuai yang dapat menandatangani transaksi
  • Digunakan sebagai alamat wallet

Alamat off-curve (PDA)

Program Derived Address diturunkan secara deterministik dari ID program dan seed. Alamat ini:

  • Tidak memiliki kunci privat yang sesuai
  • Hanya dapat ditandatangani oleh program tempat alamat tersebut diturunkan

Jenis akun dalam pembayaran

Gunakan alamat untuk mengambil akun dari jaringan, periksa pemilik program dan jenis akunnya untuk menentukan cara menangani alamat tersebut.

Mengetahui apakah suatu alamat on-curve atau off-curve tidak memberi tahu Anda jenis akun apa itu, program apa yang memilikinya, atau apakah akun ada di alamat tersebut. Anda harus mengambil akun dari jaringan untuk menentukan detail ini.

Akun System Program (wallet)

Akun yang dimiliki oleh System Program adalah wallet standar. Untuk mengirim token SPL ke wallet, Anda menurunkan dan menggunakan associated token account (ATA)-nya.

Setelah menurunkan alamat ATA, periksa apakah token account ada di on-chain. Jika ATA tidak ada, Anda dapat menyertakan instruksi untuk membuat token account penerima dalam transaksi yang sama dengan transfer. Namun, ini memerlukan pembayaran rent untuk token account baru. Karena penerima memiliki ATA, SOL yang dibayarkan untuk rent tidak dapat dikembalikan oleh pengirim.

Tanpa perlindungan, mensubsidi pembuatan ATA dapat dieksploitasi. Pengguna jahat dapat meminta transfer, membuat ATA mereka dengan biaya Anda, menutup ATA untuk mengklaim kembali SOL rent, dan mengulanginya.

Token account

Token account dimiliki oleh Token Program atau Token-2022 Program dan menyimpan saldo token. Jika alamat yang Anda terima dimiliki oleh token program, Anda harus memverifikasi bahwa akun tersebut adalah token account (bukan mint account) dan sesuai dengan mint account token yang diharapkan sebelum mengirim.

Token Program secara otomatis memvalidasi bahwa kedua token account dalam transfer menyimpan token dari mint yang sama. Jika validasi gagal, transaksi ditolak dan tidak ada dana yang hilang.

Mint account

Mint account melacak pasokan token dan metadata dari token tertentu. Mint account juga dimiliki oleh Token Program tetapi bukan penerima yang valid untuk transfer token. Mencoba mengirim token ke alamat mint akan menghasilkan transaksi yang gagal, tetapi tidak ada dana yang hilang.

Akun lainnya

Akun yang dimiliki oleh program lain memerlukan keputusan kebijakan. Beberapa akun (misalnya dompet multisig) mungkin merupakan pemilik token account yang valid, sementara yang lain harus ditolak.

Alur verifikasi

Diagram berikut menunjukkan pohon keputusan referensi untuk memvalidasi alamat:

Address Verification Flow

Ambil akun

Gunakan alamat untuk mengambil detail akun dari jaringan.

Akun tidak ada

Jika tidak ada akun di alamat ini, periksa apakah alamat tersebut on-curve atau off-curve:

  • Off-curve (PDA): Tolak alamat secara konservatif untuk menghindari pengiriman ke ATA yang mungkin tidak dapat diakses. Tanpa akun yang ada, Anda tidak dapat menentukan dari alamat saja program mana yang menurunkan PDA ini atau apakah alamat tersebut untuk ATA. Menurunkan ATA untuk alamat ini untuk mengirim token dapat mengakibatkan dana terkunci dalam token account yang tidak dapat diakses.

  • On-curve: Ini adalah alamat wallet yang valid (public key) yang belum didanai. Turunkan ATA, periksa apakah ada, dan kirim token ke sana. Anda harus membuat keputusan kebijakan apakah akan mendanai pembuatan ATA jika belum ada.

Akun ada

Jika akun ada, periksa program mana yang memilikinya:

  • System Program: Ini adalah wallet standar. Turunkan ATA, periksa apakah ada, dan kirim token ke sana. Anda harus membuat keputusan kebijakan apakah akan mendanai pembuatan ATA jika belum ada.

  • Token Program / Token-2022: Verifikasi bahwa akun tersebut adalah token account (bukan mint account) dan bahwa akun tersebut menyimpan token (mint) yang ingin Anda kirim. Jika valid, kirim token langsung ke alamat ini. Jika itu adalah mint account atau token account untuk mint yang berbeda, tolak alamatnya.

  • Program Lain: Ini memerlukan keputusan kebijakan. Beberapa program seperti multisig wallet mungkin merupakan pemilik token account yang dapat diterima. Jika kebijakan Anda mengizinkannya, turunkan ATA dan kirim. Jika tidak, tolak alamatnya.

Demo

Contoh berikut hanya menunjukkan logika validasi alamat. Ini adalah kode referensi untuk tujuan ilustrasi.

Demo ini tidak menunjukkan cara menurunkan ATA atau membangun transaksi untuk mengirim token. Lihat dokumentasi token account dan transfer token untuk contoh kode.

Demo di bawah ini menggunakan tiga kemungkinan hasil:

HasilArtiTindakan
IS_WALLETAlamat wallet yang validTurunkan dan kirim ke associated token account
IS_TOKEN_ACCOUNTToken account yang validKirim token langsung ke alamat ini
REJECTAlamat tidak validJangan kirim
Demo
/**
* Validates an input address and classifies it as a wallet, token account, or invalid.
*
* @param inputAddress - The address to validate
* @param rpc - Optional RPC client (defaults to mainnet)
* @returns Classification result:
* - IS_WALLET: Valid wallet address
* - IS_TOKEN_ACCOUNT: Valid token account
* - REJECT: Invalid address for transfers
*/
export async function validateAddress(
inputAddress: Address,
rpc: Rpc<GetAccountInfoApi> = defaultRpc
): Promise<ValidationResult> {
const account = await fetchJsonParsedAccount(rpc, inputAddress);
// Log the account data for demo
console.log("\nAccount:", account);
// Account doesn't exist on-chain
if (!account.exists) {
// Off-curve = PDA that doesn't exist as an account
// Reject conservatively to avoid sending to an address that may be inaccessible.
if (isOffCurveAddress(inputAddress)) {
return { type: "REJECT", reason: "PDA doesn't exist as an account" };
}
// On-curve = valid keypair address, treat as unfunded wallet
return { type: "IS_WALLET" };
}
// Account exists, check program owner
const owner = account.programAddress;
// System Program = wallet
if (owner === SYSTEM_PROGRAM) {
return { type: "IS_WALLET" };
}
// Token Program or Token-2022, check if token account
if (owner === TOKEN_PROGRAM || owner === TOKEN_2022_PROGRAM) {
const accountType = (
account.data as { parsedAccountMeta?: { type?: string } }
).parsedAccountMeta?.type;
if (accountType === "account") {
return { type: "IS_TOKEN_ACCOUNT" };
}
// Reject if not a token account (mint account)
return {
type: "REJECT",
reason: "Not a token account"
};
}
// Unknown program owner
return { type: "REJECT", reason: "Unknown program owner" };
}
// =============================================================================
// Examples
// =============================================================================
Console
Click to execute the code.

Is this page helpful?

Daftar Isi

Edit Halaman

Dikelola oleh

© 2026 Yayasan Solana.
Semua hak dilindungi.
Terhubung