Yanlış adrese token göndermek, fonların kalıcı olarak kaybedilmesine neden olabilir. Adres doğrulama, yalnızca tokenları düzgün bir şekilde alabilecek ve erişebilecek adreslere göndermenizi sağlar.
Temel ödeme kavramları için Solana'da Ödemeler Nasıl Çalışır bölümüne bakın.
Solana adreslerini anlama
Solana hesaplarının iki tür adresi vardır: eğri üzerinde ve eğri dışında.
Eğri üzerinde adresler
Standart adresler, Ed25519 anahtar çiftlerinden gelen genel anahtarlardır. Bu adresler:
- İşlemleri imzalayabilen karşılık gelen bir özel anahtara sahiptir
- Cüzdan adresi olarak kullanılır
Eğri dışında adresler (PDA'lar)
Program Derived Addresses, bir program kimliğinden ve seed'lerden 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
Ödemelerde hesap türleri
Ağdan bir hesap almak için adresi kullanın, program sahibini ve hesap türünü kontrol ederek adresin nasıl işleneceğini belirleyin.
Bir adresin eğri üzerinde mi yoksa eğri dışında mı olduğunu bilmek, size ne tür bir hesap olduğunu, 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 almanız gerekir.
System Program hesapları (cüzdanlar)
System Program'a ait hesaplar standart cüzdanlardır. Bir cüzdana SPL token göndermek için, onun Associated Token Account (ATA) adresini türetip kullanırsınız.
ATA adresini türettikten sonra, token hesabının zincir üzerinde var olup olmadığını kontrol edin. ATA mevcut değilse, transfer ile aynı işlemde alıcının token hesabını oluşturmak için bir talimat ekleyebilirsiniz. Ancak bu, yeni token hesabı için rent ödemeyi gerektirir. Alıcı ATA'nın sahibi olduğundan, rent için ödenen SOL gönderen tarafından geri alınamaz.
Güvenlik önlemleri olmadan, ATA oluşturma maliyetini karşılamak istismar edilebilir. Kötü niyetli bir kullanıcı transfer talep edebilir, ATA'sını sizin masrafınızla oluşturabilir, rent SOL'unu geri almak için ATA'yı kapatabilir ve bunu tekrarlayabilir.
Token hesapları
Token hesapları Token Program veya Token-2022 Program tarafından sahiplenilir ve token bakiyelerini tutar. Aldığınız adres bir token programına aitse, göndermeden önce hesabın bir token hesabı olduğunu (mint hesabı değil) ve beklenen token mint hesabıyla eşleştiğini doğrulamalısınız.
Token Programları, bir transferdeki her iki token hesabının da aynı mint'in tokenlarını tuttuğunu otomatik olarak doğrular. Doğrulama başarısız olursa, işlem reddedilir ve hiçbir fon kaybedilmez.
Mint hesapları
Mint hesapları belirli bir tokenın arzını ve meta verilerini takip eder. Mint hesapları da Token Programları tarafından sahiplenilir ancak token transferleri için geçerli alıcılar değildir. Bir mint adresine token gönderme girişimi başarısız bir işlemle sonuçlanır, ancak hiçbir fon kaybedilmez.
Diğer hesaplar
Diğer programlara ait hesaplar bir politika kararı gerektirir. Bazı hesaplar (örneğin çoklu imza cüzdanları) geçerli token hesabı sahipleri olabilirken, diğerleri reddedilmelidir.
Doğrulama akışı
Aşağıdaki diyagram, bir adresi doğrulamak için referans karar ağacını gösterir:
Hesabı getir
Ağdan hesap ayrıntılarını getirmek için adresi kullanın.
Hesap mevcut değil
Bu adreste hiçbir hesap yoksa, adresin eğri üzerinde mi yoksa eğri dışında mı olduğunu kontrol edin:
-
Eğri dışı (PDA): Erişilemeyen bir ATA'ya gönderim yapmaktan kaçınmak için adresi ihtiyatlı bir şekilde reddedin. Mevcut bir hesap olmadan, yalnızca adresten bu PDA'yı hangi programın türettiğini veya adresin bir ATA için olup olmadığını belirleyemezsiniz. Bu adres için bir ATA türeterek token göndermek, fonların erişilemeyen bir token hesabında kilitlenmesine neden olabilir.
-
Eğri üzerinde: Bu, henüz fonlanmamış geçerli bir cüzdan adresidir (genel anahtar). ATA'yı türetin, var olup olmadığını kontrol edin ve ona token gönderin. ATA mevcut değilse, oluşturulmasını fonlayıp fonlamayacağınıza dair bir politika kararı vermelisiniz.
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, var olup olmadığını kontrol edin ve ona token gönderin. ATA mevcut değilse, oluşturulmasını fonlayıp fonlamayacağınıza dair bir politika kararı vermelisiniz.
-
Token Program / Token-2022: Hesabın bir token hesabı olduğunu (mint hesabı olmadığını) ve göndermeyi planladığınız token'ı (mint) tuttuğunu doğrulayın. Geçerliyse, token'ları doğrudan bu adrese gönderin. Eğer bir mint hesabıysa veya farklı bir mint için token hesabıysa, adresi reddedin.
-
Diğer program: Bu bir politika kararı gerektirir. Çoklu imza cüzdanları gibi bazı programlar, token hesaplarının kabul edilebilir sahipleri olabilir. Politikanız izin veriyorsa, ATA'yı türetin ve gönderin. Aksi takdirde, adresi reddedin.
Demo
Aşağıdaki örnek yalnızca adres doğrulama mantığını göstermektedir. Bu, açıklama amaçlı referans kodudur.
Demo, bir ATA'nın nasıl türetileceğini veya token göndermek için bir işlemin nasıl oluşturulacağını göstermemektedir. Örnek kod için token hesabı ve token transferi belgelerine bakın.
Aşağıdaki demo üç olası sonuç kullanır:
| Sonuç | Anlamı | Eylem |
|---|---|---|
IS_WALLET | Geçerli cüzdan adresi | Associated token account türet ve gönder |
IS_TOKEN_ACCOUNT | Geçerli token hesabı | Token'ları doğrudan bu adrese gönder |
REJECT | Geçersiz adres | Gönderme |
/*** 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 democonsole.log("\nAccount:", account);// Account doesn't exist on-chainif (!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 walletreturn { type: "IS_WALLET" };}// Account exists, check program ownerconst owner = account.programAddress;// System Program = walletif (owner === SYSTEM_PROGRAM) {return { type: "IS_WALLET" };}// Token Program or Token-2022, check if token accountif (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 ownerreturn { type: "REJECT", reason: "Unknown program owner" };}// =============================================================================// Examples// =============================================================================
Is this page helpful?