Adresi doğrula

Yanlış adrese para göndermek kalıcı kayıplara yol açabilir. Adres doğrulama, sizin ve kullanıcılarınızın yalnızca fonları düzgün biçimde alabilecek ve erişebilecek adreslere göndermenizi sağlar. Bir borsa işletiyorsanız bu kontrolleri yapmanız ve göndermeden önce kullanıcınızın adresi doğrulamasını sağlamanız önerilir.

Doğrulama, ne gönderdiğinize bağlıdır:

  • SPL token'ları kısmen kendi kendini korur. Token Program, hesapları beklenen mint ile eşleşmeyen bir transferi reddeder; bu nedenle yanlış yönlendirilmiş bir token transferi fon kaybı olmadan başarısız olur. Bu sayfanın büyük bölümü SPL token gönderimleri ile ilgilidir.
  • Yerel SOL için böyle bir koruma yoktur. System Program transferi herhangi bir hesaba başarıyla gerçekleşir; bu nedenle yanlış bir alıcı SOL'u kalıcı olarak kilitler. Bkz. Yerel SOL Gönderimi.

Temel ödeme kavramları için bkz. Solana'da Ödemeler Nasıl Çalışır.

Solana Adreslerini Anlamak

Solana hesaplarının iki tür adresi vardır: eğri üzerinde (on-curve) ve eğri dışında (off-curve).

Eğri Üzerindeki Adresler (On-Curve)

Standart adresler, Ed25519 keypair'lerinden elde edilen açık anahtarlardır. Bu adresler:

  • İşlemleri imzalayabilen karşılık gelen bir özel anahtara sahiptir
  • Cüzdan adresi olarak kullanılır

Eğri Dışı Adresler (PDA'lar)

Program Derived Address'ler, bir program kimliği ve tohumlardan deterministik olarak türetilir. Bu adresler:

  • Karşılık gelen bir özel anahtara sahip değildir
  • Yalnızca adresin türetildiği program tarafından imzalanabilir

Program kontrollü cüzdanlar, yaygın olarak akıllı cüzdanlar veya akıllı hesaplar olarak adlandırılır ve eğri dışı adreslere sahiptir. Bu kılavuzda tüm içerikte "akıllı cüzdan" terimi kullanılmaktadır.

Ödemelerde Hesap Türleri

Ağdan bir hesap çekmek için adresi kullanın; adresi nasıl işleyeceğinizi belirlemek için program sahibini ve hesap türünü kontrol edin.

Bir adresin eğri üzerinde mi yoksa eğri dışında mı olduğunu bilmek, hesabın türünü, hangi programın sahibi olduğunu veya o adreste bir hesabın var olup olmadığını söylemez. Bu ayrıntıları belirlemek için hesabı ağdan çekmeniz gerekir.

System Program Hesapları (Cüzdanlar)

System Program tarafından sahip olunan hesaplar standart cüzdanlardır. Bir cüzdana SPL token göndermek için, onun Associated Token Account (ATA)'ını türetip kullanmanız gerekir.

ATA adresini türettikten sonra, token account'ın zincir üzerinde var olup olmadığını kontrol edin. ATA mevcut değilse, transfer işlemiyle aynı işlem içinde alıcının token account'ını oluşturmak için bir talimat ekleyebilirsiniz. Ancak bu, yeni token account için rent ödenmesini gerektirir. Alıcı ATA'ya sahip olduğundan, rent için ödenen SOL gönderici tarafından geri alınamaz.

Sistem hesapları eğri dışında bulunabilir. Kullanıcınız eğri dışı bir adrese token göndermek istiyorsa, kullanıcıya fonları bir akıllı cüzdana göndermek isteyip istemediğini doğrulaması için uyarı yapılması önerilir.

Güvenlik önlemleri olmadan, ATA oluşturma maliyetinin karşılanması istismar edilebilir. Kötü niyetli bir kullanıcı transfer talep edebilir, ATA'sını sizin hesabınıza oluşturabilir, rent SOL'unu geri almak için ATA'yı kapatabilir ve bunu tekrarlayabilir.

Token Hesapları

Token account'lar, Token Program veya Token-2022 Program tarafından sahiplenilir ve token bakiyelerini tutar. Aldığınız adres bir token programına aitse, token göndermeden önce hesabın bir token account olduğunu (mint account değil) ve beklenen token mint account ile eşleştiğini doğrulamalısınız.

Token Program'lar, bir transferdeki her iki token account'ın da aynı mint'e ait token tuttuğunu otomatik olarak doğrular. Doğrulama başarısız olursa işlem reddedilir ve hiçbir varlık kaybolmaz.

Mint Hesapları

Mint account'lar, belirli bir tokenın arzını ve meta verilerini takip eder. Mint account'lar da Token Program'lar tarafından sahiplenilir, ancak token transferleri için geçerli alıcılar değildir. Bir mint adresine token göndermeye çalışmak başarısız bir işlemle sonuçlanır, ancak hiçbir varlık kaybolmaz.

Diğer Hesaplar

Diğer programlara ait hesaplar geçerlidir ancak ilgili sahip programın belirlediği yetki kurallarına tabidir. Kullanıcıya fonları bir akıllı cüzdana göndermek isteyip istemediğini doğrulaması için uyarı yapılması önerilir.

Yerel SOL Gönderimi

Yukarıdaki sınıflandırma, SPL tokenlarının nereye gönderebileceğini belirler. Yerel SOL daha kısıtlıdır: tek güvenli alıcı, bir System Program cüzdanı (ya da bir System Program cüzdanına dönüşen, fonlanmamış eğri üzeri bir adres) olmalıdır.

Bir System Program transferi, mintler, token accountlar, programlar ve PDA'lar dahil olmak üzere herhangi bir hesaba lamport ekler. Lamportlar yalnızca hesabın sahibi olan program tarafından çıkarılabilir; bu nedenle SOL'un yanlış bir alıcıya gönderilmesi, fonların kalıcı olarak kaybedilmesine yol açabilir.

Bir SPL token transferinin aksine, alıcı beklenmedik bir adres olduğunda işlem başarısız olmaz.

Yerel SOL gönderilirken yalnızca IS_WALLET sonucu kabul edilebilirdir. IS_TOKEN_ACCOUNT ise kabul edilemez: bir token account, SPL tokenları barındırır ve oraya gönderilen SOL, gönderenin kontrolü dışına çıkar.

Bu, SOL'un kaybolmasının yaygın bir yoludur: bir kullanıcı, token'ın mint adresini (veya bir program adresini) SOL çekme işlemine yapıştırır. Transfer başarıyla tamamlanır ve SOL kurtarılamaz. Bir SOL transferini imzalamadan önce her zaman alıcıyı sınıflandırın.

Doğrulama Akışı

Aşağıdaki diyagram, bir adresi doğrulamak için referans karar ağacını göstermektedir:

Address Verification Flow

Hesabı Getir

Ağdan hesap ayrıntılarını getirmek için adresi kullanın.

Hesap mevcut değil

Bu adreste herhangi bir hesap yoksa, adresin eğri üzerinde mi yoksa eğri dışında mı olduğunu kontrol edin:

  • Eğri dışı (PDA): ATA oluşturmadan veya SPL token göndermeden önce açık alıcı doğrulaması isteyin. Mevcut bir hesap olmadan, yalnızca adresten bu PDA'yı hangi programın türettiğini veya alıcının programının kendi ATA'sına erişip erişemeyeceğini belirleyemezsiniz.

  • Eğri üzerinde: Bu, henüz fonlanmamış geçerli bir cüzdan adresidir (açık anahtar). ATA'yı türetin, mevcut olup olmadığını kontrol edin ve token gönderin. ATA mevcut değilse oluşturulmasını finanse edip etmeyeceğinize dair bir politika kararı vermeniz gerekir.

Hesap mevcut

Bir hesap mevcutsa, hangi programın sahibi olduğunu kontrol edin:

  • System Program: Bu standart bir cüzdandır. ATA'yı türetin, mevcut olup olmadığını kontrol edin ve token gönderin. ATA mevcut değilse oluşturulmasını finanse edip etmeyeceğinize dair bir politika kararı vermeniz gerekir.

  • Token Program / Token-2022: Hesabın bir token account (mint account değil) olduğunu ve göndermek istediğiniz token'ı (mint) tuttuğunu doğrulayın. Geçerliyse token'ları doğrudan bu adrese gönderin. Eğer bu bir mint account veya farklı bir mint için bir token account ise adresi reddedin.

  • Diğer Program: Çoklu imza cüzdanları gibi programlar, token account'larının kabul edilebilir sahipleridir. Kullanıcının akıllı cüzdana göndermek istediğini onaylamasını isteyin.

    Yaygın akıllı cüzdanlardan bazıları:

Demo

Aşağıdaki örnek yalnızca adres doğrulama mantığını göstermektedir. Bu, yalnızca açıklama amacıyla hazırlanmış referans kodudur.

Demo, bir ATA türetmeyi veya token göndermek için bir işlem oluşturmayı göstermemektedir. Örnek kod için token account ve token transfer belgelerine başvurun.

Aşağıdaki demo üç olası sonucu kullanmaktadır:

SonuçAnlamİşlem
IS_WALLETGeçerli cüzdan adresiassociated token account'a türet ve gönder
IS_TOKEN_ACCOUNTGeçerli token accountToken'ları doğrudan bu adrese gönder
USER_VERIFICATIONAdres, alıcı onayı gerektirirSPL token göndermeden veya ATA fonlamadan önce açık inceleme isteyin
REJECTGeçersiz adresGönderme

Ardından her sonucu, varlık bazında kabul edilebilirliğe eşler: canReceiveNativeSol (yalnızca cüzdanlar) ve canReceiveSplToken (cüzdanlar veya token account'lar). Bir USER_VERIFICATION sonucu otomatik olarak kabul edilmez; uygulamanızın SPL token göndermeden önce kullanıcının niyetini onaylamasını sağlaması gerekir. Bir token account, IS_TOKEN_ACCOUNT döndürür; bu nedenle SPL token alabilir ancak yerel SOL alamaz — bu ayrım, SOL'un kilitlenmesini önler.

Demo
/**
* Validates an input address and classifies it as a wallet, token account,
* address requiring recipient verification, 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
* - USER_VERIFICATION: Require explicit review before sending SPL tokens
* - 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 onchain
if (!account.exists) {
// An unfunded PDA may belong to a smart wallet, but the address
// alone cannot prove that its program can access a newly-created ATA.
if (isOffCurveAddress(inputAddress)) {
return {
type: "USER_VERIFICATION",
reason:
"Unfunded PDA: confirm the recipient is using a smart wallet and controls this address"
};
}
// On-curve = valid keypair address, treat as unfunded wallet
return { type: "IS_WALLET" };
}
// Account exists, check program owner
const owner = account.programAddress;
// A System Program account can be a standard wallet or an off-curve smart
// wallet. Require verification before automatically sending to the
// latter.
if (owner === SYSTEM_PROGRAM) {
if (isOffCurveAddress(inputAddress)) {
return {
type: "USER_VERIFICATION",
reason:
"Off-curve System Program account: confirm recipient is using a smart wallet"
};
}
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"
};
}
// An account owned by another program can be a smart wallet.
return {
type: "USER_VERIFICATION",
reason:
"Program-owned account: confirm the recipient is using a smart wallet"
};
}
/**
* Native SOL is only safe to send to a wallet. Any other account locks it.
*/
function canReceiveNativeSol(result: ValidationResult): boolean {
return result.type === "IS_WALLET";
}
/**
* SPL tokens can go to a wallet (via its ATA) or directly to a token account.
*/
function canReceiveSplToken(result: ValidationResult): boolean {
return result.type === "IS_WALLET" || result.type === "IS_TOKEN_ACCOUNT";
}
// =============================================================================
// Examples
// =============================================================================
Console
Click to execute the code.

Is this page helpful?

© 2026 Solana Vakfı. Tüm hakları saklıdır.