Weryfikacja adresu

Wysłanie tokenów na nieprawidłowy adres może skutkować trwałą utratą środków. Weryfikacja adresu zapewnia, że wysyłasz tokeny tylko na adresy, które mogą je poprawnie odebrać i uzyskać do nich dostęp.

Zobacz Jak działają płatności w Solana, aby poznać podstawowe pojęcia dotyczące płatności.

Zrozumienie adresów Solana

Konta Solana mają dwa typy adresów: on-curve i off-curve.

Adresy on-curve

Standardowe adresy to klucze publiczne z par kluczy Ed25519. Te adresy:

  • Mają odpowiadający im klucz prywatny, który może podpisywać transakcje
  • Służą jako adresy portfeli

Adresy off-curve (PDA)

Program Derived Addresses (adresy pochodne programu) są deterministycznie wyprowadzane z ID programu i seedów. Te adresy:

  • Nie mają odpowiadającego im klucza prywatnego
  • Mogą być podpisywane tylko przez program, z którego zostały wyprowadzone

Typy kont w płatnościach

Użyj adresu, aby pobrać konto z sieci, sprawdź właściciela programu i typ konta, aby określić, jak obsłużyć dany adres.

Wiedza o tym, czy adres jest on-curve czy off-curve, nie mówi, jaki to typ konta, jaki program jest jego właścicielem ani czy konto istnieje pod tym adresem. Musisz pobrać konto z sieci, aby poznać te szczegóły.

Konta System Program (portfele)

Konta należące do System Program to standardowe portfele. Aby wysłać tokeny SPL do portfela, należy wyznaczyć i użyć jego associated token account (ATA).

Po wyznaczeniu adresu ATA sprawdź, czy token account istnieje on-chain. Jeśli ATA nie istnieje, możesz dodać instrukcję utworzenia token account odbiorcy w tej samej transakcji co transfer. Wymaga to jednak opłacenia rent za nowe token account. Ponieważ odbiorca jest właścicielem ATA, SOL zapłacone za rent nie może zostać odzyskane przez nadawcę.

Bez odpowiednich zabezpieczeń subsydiowanie tworzenia ATA może zostać wykorzystane w nieuczciwy sposób. Złośliwy użytkownik może zlecić transfer, utworzyć swoje ATA na Twój koszt, zamknąć ATA, aby odzyskać rent SOL, i powtarzać ten proces.

Konta tokenów

Konta tokenów są własnością Token Program lub Token-2022 Program i przechowują salda tokenów. Jeśli otrzymany adres należy do programu tokenów, należy zweryfikować, czy konto jest kontem tokena (a nie mint account) i czy odpowiada oczekiwanemu mint account tokena przed wysłaniem.

Token Programs automatycznie sprawdzają, czy oba konta tokenów w transferze przechowują tokeny tego samego mint. Jeśli weryfikacja się nie powiedzie, transakcja zostaje odrzucona i żadne środki nie zostają utracone.

Konta mint

Konta mint śledzą podaż tokena i metadane konkretnego tokena. Konta mint są również własnością Token Programs, ale nie są prawidłowymi odbiorcami transferów tokenów. Próba wysłania tokenów na adres mint kończy się nieudaną transakcją, ale środki nie zostają utracone.

Inne konta

Konta należące do innych programów wymagają decyzji politycznej. Niektóre konta (np. portfele multisig) mogą być prawidłowymi właścicielami kont tokenów, podczas gdy inne powinny zostać odrzucone.

Przebieg weryfikacji

Poniższy diagram przedstawia przykładowe drzewo decyzyjne do weryfikacji adresu:

Address Verification Flow

Pobierz konto

Użyj adresu, aby pobrać szczegóły konta z sieci.

Konto nie istnieje

Jeśli pod tym adresem nie istnieje konto, sprawdź, czy adres jest on-curve czy off-curve:

  • Poza krzywą (PDA): Ostrożnie odrzuć ten adres, aby uniknąć wysyłania do ATA, który może być niedostępny. Bez istniejącego konta nie da się określić na podstawie samego adresu, który program wygenerował ten PDA ani czy adres jest ATA. Utworzenie ATA dla tego adresu i wysłanie tokenów może spowodować zablokowanie środków na niedostępnym token account.

  • Na krzywej: To poprawny adres portfela (klucz publiczny), który nie został jeszcze zasilony. Wygeneruj ATA, sprawdź, czy istnieje, i wyślij na niego tokeny. Musisz podjąć decyzję, czy finansować utworzenie ATA, jeśli jeszcze nie istnieje.

Konto istnieje

Jeśli konto istnieje, sprawdź, który program jest jego właścicielem:

  • System Program: To standardowy portfel. Wygeneruj ATA, sprawdź, czy istnieje, i wyślij na niego tokeny. Musisz podjąć decyzję, czy finansować utworzenie ATA, jeśli jeszcze nie istnieje.

  • Token Program / Token-2022: Zweryfikuj, czy konto jest token account (a nie mint account) i czy posiada token (mint), który chcesz wysłać. Jeśli tak, wyślij tokeny bezpośrednio na ten adres. Jeśli to mint account lub token account dla innego mint, odrzuć adres.

  • Inny program: Wymaga decyzji politycznej. Niektóre programy, jak portfele multisig, mogą być akceptowalnymi właścicielami token account. Jeśli polityka na to pozwala, wygeneruj ATA i wyślij. W przeciwnym razie odrzuć adres.

Demo

Poniższy przykład pokazuje wyłącznie logikę walidacji adresu. To kod referencyjny służący do celów ilustracyjnych.

Demo nie pokazuje, jak wyprowadzić ATA ani jak zbudować transakcję do wysyłania tokenów. Zobacz dokumentację dotyczącą token account oraz przesyłania tokenów, aby znaleźć przykładowy kod.

Poniższa demonstracja wykorzystuje trzy możliwe wyniki:

WynikZnaczenieDziałanie
IS_WALLETPrawidłowy adres portfelaWyprowadź i wyślij na associated token account
IS_TOKEN_ACCOUNTPrawidłowy token accountWyślij tokeny bezpośrednio na ten adres
REJECTNieprawidłowy adresNie wysyłaj
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?

Spis treści

Edytuj stronę

Zarządzane przez

© 2026 Solana Foundation.
Wszelkie prawa zastrzeżone.
Bądź na bieżąco