Das Senden von Token an die falsche Adresse kann zu einem dauerhaften Verlust von Geldern führen. Die Adressverifizierung stellt sicher, dass Sie Token nur an Adressen senden, die diese ordnungsgemäß empfangen und darauf zugreifen können.
Siehe Wie Zahlungen auf Solana funktionieren für grundlegende Zahlungskonzepte.
Solana-Adressen verstehen
Solana-Konten haben zwei Arten von Adressen: on-curve und off-curve.
On-Curve-Adressen
Standardadressen sind die öffentlichen Schlüssel von Ed25519-Schlüsselpaaren. Diese Adressen:
- Haben einen entsprechenden privaten Schlüssel, der Transaktionen signieren kann
- Werden als Wallet-Adressen verwendet
Off-Curve-Adressen (PDAs)
Program Derived Addresses werden deterministisch aus einer Programm-ID und Seeds abgeleitet. Diese Adressen:
- Haben keinen entsprechenden privaten Schlüssel
- Können nur vom Programm signiert werden, von dem die Adresse abgeleitet wurde
Kontentypen bei Zahlungen
Verwenden Sie die Adresse, um ein Konten aus dem Netzwerk abzurufen, prüfen Sie dessen Programmeigentümer und Kontotyp, um zu bestimmen, wie die Adresse zu handhaben ist.
Zu wissen, ob eine Adresse on-curve oder off-curve ist, sagt Ihnen nicht, welcher Kontotyp es ist, welches Programm es besitzt oder ob ein Konten unter dieser Adresse existiert. Sie müssen das Konten aus dem Netzwerk abrufen, um diese Details zu ermitteln.
System Program-Konten (Wallets)
Konten, die dem System Program gehören, sind Standard-Wallets. Um SPL-Token an ein Wallet zu senden, leiten Sie dessen Associated Token Account (ATA) ab und verwenden es.
Nachdem Sie die ATA-Adresse abgeleitet haben, prüfen Sie, ob das token account on-chain existiert. Wenn das ATA nicht existiert, können Sie eine Anweisung zum Erstellen des token account des Empfängers in derselben Transaktion wie die Übertragung einschließen. Dies erfordert jedoch die Zahlung von rent für das neue token account. Da der Empfänger das ATA besitzt, kann das für die rent gezahlte SOL nicht vom Absender zurückgefordert werden.
Ohne Schutzmaßnahmen kann die Subventionierung der ATA-Erstellung ausgenutzt werden. Ein böswilliger Benutzer könnte eine Überweisung anfordern, sein ATA auf Ihre Kosten erstellen lassen, das ATA schließen, um die Miete in SOL zurückzuerhalten, und dies wiederholen.
Token-Konten
Token-Konten gehören dem Token Program oder Token-2022 Program und halten Token-Guthaben. Wenn die Adresse, die Sie erhalten, einem Token-Programm gehört, sollten Sie überprüfen, dass das Konto ein Token-Konto ist (kein Mint-Konto) und mit dem erwarteten Token-Mint-Konto übereinstimmt, bevor Sie senden.
Die Token Programs validieren automatisch, dass beide Token-Konten in einer Überweisung Token derselben Mint halten. Wenn die Validierung fehlschlägt, wird die Transaktion abgelehnt und es gehen keine Mittel verloren.
Mint-Konten
Mint-Konten verfolgen das Token-Angebot und die Metadaten eines bestimmten Tokens. Mint-Konten gehören ebenfalls Token Programs, sind aber keine gültigen Empfänger für Token-Überweisungen. Der Versuch, Token an eine Mint-Adresse zu senden, führt zu einer fehlgeschlagenen Transaktion, aber es gehen keine Mittel verloren.
Andere Konten
Konten, die anderen Programmen gehören, erfordern eine Grundsatzentscheidung. Einige Konten (z. B. Multisig-Wallets) können gültige Token-Konto-Eigentümer sein, während andere abgelehnt werden sollten.
Verifizierungsablauf
Das folgende Diagramm zeigt einen Referenz-Entscheidungsbaum zur Validierung einer Adresse:
Konto abrufen
Verwenden Sie die Adresse, um die Kontodetails aus dem Netzwerk abzurufen.
Konto existiert nicht
Wenn unter dieser Adresse kein Konto existiert, prüfen Sie, ob die Adresse on-curve oder off-curve ist:
-
Off-curve (PDA): Lehnen Sie die Adresse vorsichtshalber ab, um das Senden an ein ATA zu vermeiden, das möglicherweise nicht zugänglich ist. Ohne ein bestehendes Konto können Sie allein anhand der Adresse nicht feststellen, welches Programm diese PDA abgeleitet hat oder ob die Adresse für ein ATA bestimmt ist. Das Ableiten eines ATA für diese Adresse zum Senden von Token könnte dazu führen, dass Guthaben in einem nicht zugänglichen Token-Konto gesperrt werden.
-
On-curve: Dies ist eine gültige Wallet-Adresse (öffentlicher Schlüssel), die noch nicht finanziert wurde. Leiten Sie das ATA ab, prüfen Sie, ob es existiert, und senden Sie Token dorthin. Sie müssen eine Grundsatzentscheidung treffen, ob Sie die Erstellung des ATA finanzieren, falls es nicht existiert.
Konto existiert
Wenn ein Konto existiert, prüfen Sie, welches Programm es besitzt:
-
System Program: Dies ist eine Standard-Wallet. Leiten Sie das ATA ab, prüfen Sie, ob es existiert, und senden Sie Token dorthin. Sie müssen eine Grundsatzentscheidung treffen, ob Sie die Erstellung des ATA finanzieren, falls es nicht existiert.
-
Token Program / Token-2022: Überprüfen Sie, dass das Konto ein Token-Konto ist (kein Mint-Konto) und dass es den Token (Mint) hält, den Sie senden möchten. Wenn gültig, senden Sie Token direkt an diese Adresse. Wenn es ein Mint-Konto oder ein Token-Konto für einen anderen Mint ist, lehnen Sie die Adresse ab.
-
Other Program: Dies erfordert eine Grundsatzentscheidung. Einige Programme wie Multisig-Wallets können akzeptable Besitzer von Token-Konten sein. Wenn Ihre Richtlinie dies zulässt, leiten Sie das ATA ab und senden Sie. Andernfalls lehnen Sie die Adresse ab.
Demo
Das folgende Beispiel zeigt nur die Adressvalidierungslogik. Dies ist Referenzcode zu Illustrationszwecken.
Die Demo zeigt nicht, wie man ein ATA ableitet oder eine Transaktion zum Senden von Token erstellt. Siehe die Dokumentation zu Token-Konten und Token-Übertragungen für Beispielcode.
Die folgende Demo verwendet drei mögliche Ergebnisse:
| Ergebnis | Bedeutung | Aktion |
|---|---|---|
IS_WALLET | Gültige Wallet-Adresse | Associated token account ableiten und dorthin senden |
IS_TOKEN_ACCOUNT | Gültiges Token-Konto | Token direkt an diese Adresse senden |
REJECT | Ungültige Adresse | Nicht senden |
/*** 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?