Solanas Token-Programme unterstützen Delegation – die Gewährung einer Berechtigung an ein anderes Konto, Token von Ihrem Token-Konto bis zu einem festgelegten Limit zu übertragen. Dies ermöglicht Anwendungsfälle wie automatisierte Zahlungen, Treuhanddienste und Zahlungsabwicklung durch Dritte, ohne die Verwahrung Ihrer Mittel aufzugeben.
Wie Delegation funktioniert
Wenn Sie einen Delegierten genehmigen, autorisieren Sie ein bestimmtes Konto, Token in Ihrem Namen zu übertragen:
- Eigentümer behält Verwahrung: Sie besitzen weiterhin die Token und können diese jederzeit übertragen oder widerrufen
- Begrenzte Ausgaben: Der Delegierte kann nur bis zum genehmigten Betrag übertragen
- Ein Delegierter pro Konto: Jedes Token-Konto kann nur einen aktiven Delegierten haben
- Neue Genehmigung ersetzt alte: Die Genehmigung eines neuen Delegierten widerruft automatisch den vorherigen
Delegation ist nicht-verwahrend. Der Delegierte kann Token bis zum Limit ausgeben, kann aber nicht auf das Konto zugreifen oder es über den genehmigten Betrag hinaus leeren. Der Eigentümer kann jederzeit widerrufen.
Geschäftliche Anwendungsfälle
| Anwendungsfall | Wie Delegation hilft |
|---|---|
| Zahlungsabwickler | Händler gewährt Abwickler Berechtigung zur Abwicklung von Transaktionen |
| Automatisierte Gehaltsabrechnung | Treasury genehmigt Gehaltsabrechnungsdienst zur Auszahlung von Gehältern |
| Treuhanddienste | Käufer delegiert an Treuhänder für bedingte Freigabe |
| Handelsplattformen | Benutzer genehmigt Börse zur Ausführung von Trades in seinem Namen |
| Kartenausgabe | Benutzer genehmigt Kartenaussteller zur Belastung von Einkäufen auf seinem Token-Konto |
Genehmigung eines Delegierten
Einem anderen Konten die Berechtigung erteilen, Token von Ihrem Konten auszugeben:
import { getApproveCheckedInstruction } from "@solana-program/token";// Approve delegate to spend up to 1,000 USDC (6 decimals)const approveInstruction = getApproveCheckedInstruction({source: tokenAccountAddress, // Your token accountmint: usdcMintAddress, // USDC mintdelegate: delegateAddress, // Account receiving permissionowner: ownerKeypair, // You (must sign)amount: 1_000_000_000n, // 1,000 USDC in base unitsdecimals: 6});
Parameter:
source: Das Token-Konten, das die Berechtigung erteiltdelegate: Das Konten, das die Ausgabeberechtigung erhältowner: Aktueller Eigentümer des Token-Kontens (muss die Transaktion signieren)amount: Maximale Anzahl an Token, die der Delegierte übertragen kanndecimals: Token-Dezimalstellen zur Validierung (verhindert Dezimalfehler)
Demo
// Generate keypairs for sender and delegateconst sender = (await generateKeypair()).signer;const delegate = (await generateKeypair()).signer;console.log("Sender Address:", sender.address);console.log("Delegate Address:", delegate.address);// Demo Setup: Create client, mint account, token account, and fund with initial tokensconst { client, mint, senderAta } = await demoSetup(sender);console.log("\nMint Address:", mint.address);console.log("Sender ATA:", senderAta);// =============================================================================// Approve Delegate// =============================================================================// Create instruction to approve delegateconst approveInstruction = getApproveCheckedInstruction({source: senderAta,mint: mint.address,delegate: delegate.address,owner: sender,amount: 1_000_000n, // 1.0 tokens with 6 decimalsdecimals: 6});// Send approve transactionconst signature = await client.transaction.prepareAndSend({authority: sender,instructions: [approveInstruction]});console.log("\n=== Approve Delegate ===");console.log("Transaction Signature:", signature);// Fetch token account data to show delegate is setconst tokenData = await fetchToken(client.runtime.rpc, senderAta);console.log("\nSender Token Account Data:", tokenData.data);// =============================================================================// Demo Setup Helper Function// =============================================================================
Delegierten widerrufen
Alle Ausgabeberechtigungen vom aktuellen Delegierten entfernen:
import { getRevokeInstruction } from "@solana-program/token";const revokeInstruction = getRevokeInstruction({source: tokenAccountAddress, // Your token accountowner: ownerKeypair // You (must sign)});
Revoke entfernt alle Delegiertenberechtigungen – es gibt keinen teilweisen Widerruf. Wenn Sie das Limit reduzieren möchten, genehmigen Sie denselben Delegierten mit einem niedrigeren Betrag.
Demo
// Generate keypairs for sender and delegateconst sender = (await generateKeypair()).signer;const delegate = (await generateKeypair()).signer;console.log("Sender Address:", sender.address);console.log("Delegate Address:", delegate.address);// Demo Setup: Create client, mint account, token account, and fund with initial tokensconst { client, mint, senderAta } = await demoSetup(sender);console.log("\nMint Address:", mint.address);console.log("Sender ATA:", senderAta);// =============================================================================// Transaction 1: Approve Delegate// =============================================================================// Create instruction to approve delegateconst approveInstruction = getApproveCheckedInstruction({source: senderAta,mint: mint.address,delegate: delegate.address,owner: sender,amount: 1_000_000n, // 1.0 tokens with 6 decimalsdecimals: 6});// Send approve transactionconst approveSignature = await client.transaction.prepareAndSend({authority: sender,instructions: [approveInstruction]});console.log("\n=== Transaction 1: Approve Delegate ===");console.log("Transaction Signature:", approveSignature);// Fetch token account data to show delegate is setconst tokenDataAfterApprove = await fetchToken(client.runtime.rpc, senderAta);console.log("\nSender Token Account Data:", tokenDataAfterApprove.data);// =============================================================================// Transaction 2: Revoke Delegate// =============================================================================// Create instruction to revoke delegateconst revokeInstruction = getRevokeInstruction({source: senderAta,owner: sender});// Send revoke transactionconst revokeSignature = await client.transaction.prepareAndSend({authority: sender,instructions: [revokeInstruction]});console.log("\n=== Transaction 2: Revoke Delegate ===");console.log("Transaction Signature:", revokeSignature);// Fetch token account data to show delegate is revokedconst tokenDataAfterRevoke = await fetchToken(client.runtime.rpc, senderAta);console.log("\nSender Token Account Data:", tokenDataAfterRevoke.data);// =============================================================================// Demo Setup Helper Function// =============================================================================
Übertragung als Delegierter
Wenn Sie als Delegierter agieren, verwenden Sie eine Standard-Übertragung, signieren jedoch mit dem Delegierten-Keypair anstelle des Eigentümers:
import { getTransferCheckedInstruction } from "@solana-program/token";const transferInstruction = getTransferCheckedInstruction({source: ownerTokenAccount, // The account you have permission to spend frommint: usdcMintAddress,destination: recipientTokenAccount,authority: delegateKeypair, // You (the delegate) sign, not the owneramount: 100_000_000n, // 100 USDCdecimals: 6});
Die Übertragung ist erfolgreich, wenn:
- Das Quellkonto über ausreichendes Guthaben verfügt
- Der Delegierte die Transaktion signiert
Jede Übertragung reduziert die verbleibende Zulage. Wenn die Zulage null erreicht, kann der Delegierte keine Token mehr übertragen.
Demo
// Generate keypairs for sender, delegate, and recipientconst sender = (await generateKeypair()).signer;const delegate = (await generateKeypair()).signer;const recipient = (await generateKeypair()).signer;console.log("Sender Address:", sender.address);console.log("Delegate Address:", delegate.address);console.log("Recipient Address:", recipient.address);// Demo Setup: Create client, mint account, token accounts, and fund with initial tokensconst { client, mint, senderAta, recipientAta } = await demoSetup(sender,delegate,recipient);console.log("\nMint Address:", mint.address);console.log("Sender ATA:", senderAta);console.log("Recipient ATA:", recipientAta);// =============================================================================// Transaction 1: Approve Delegate// =============================================================================// Create instruction to approve delegateconst approveInstruction = getApproveCheckedInstruction({source: senderAta,mint: mint.address,delegate: delegate.address,owner: sender,amount: 1_000_000n, // 1.0 tokens with 6 decimalsdecimals: 6});// Send approve transactionconst approveSignature = await client.transaction.prepareAndSend({authority: sender,instructions: [approveInstruction]});console.log("\n=== Transaction 1: Approve Delegate ===");console.log("Delegate Address:", delegate.address);console.log("Transaction Signature:", approveSignature);// =============================================================================// Fetch Token Account Data to Demonstrate Delegate is Set// =============================================================================const tokenAccountData = await fetchToken(client.runtime.rpc, senderAta);console.log("\nSender Token Account Data:", tokenAccountData.data);// =============================================================================// Transaction 2: Transfer Using Delegate// =============================================================================// Create instruction to transfer tokens using delegate// Note: delegate is the authority here, not the ownerconst transferInstruction = getTransferCheckedInstruction({source: senderAta,mint: mint.address,destination: recipientAta,authority: delegate, // Delegate signs this transactionamount: 500_000n, // 0.5 tokens with 6 decimalsdecimals: 6});// Send transfer transaction// Delegate pays for the transaction and authorizes the transfer (sender not needed)const transferSignature = await client.transaction.prepareAndSend({authority: delegate, // Delegate pays fee and signsinstructions: [transferInstruction]});// =============================================================================// Fetch Final Token Account Balances// =============================================================================const finalSenderToken = await fetchToken(client.runtime.rpc, senderAta);const finalRecipientToken = await fetchToken(client.runtime.rpc, recipientAta);console.log("\n=== Transaction 2: Transfer Using Delegate ===");console.log("Transaction Signature:", transferSignature);console.log("\nSender Token Account Data:", finalSenderToken.data);console.log("\nRecipient Token Account Data:", finalRecipientToken.data);// =============================================================================// Demo Setup Helper Function// =============================================================================
Überprüfung des Delegierungsstatus
Ein Token-Konten abfragen, um den aktuellen Delegierten und die verbleibende Zulage zu sehen:
import { fetchToken } from "@solana-program/token";const tokenAccount = await fetchToken(rpc, tokenAccountAddress);if (tokenAccount.data.delegate) {console.log("Delegate:", tokenAccount.data.delegate);console.log("Remaining allowance:", tokenAccount.data.delegatedAmount);} else {console.log("No delegate set");}
Demo
// Demo Setup: Create client, mint, two token accounts (one with delegate, one without)const { client, ataWithDelegate, ataWithoutDelegate } = await demoSetup();// =============================================================================// Fetch Token Accounts// =============================================================================// Fetch token account with delegateconst tokenWithDelegate = await fetchToken(client.runtime.rpc, ataWithDelegate);console.log("Token Account with Delegate:", tokenWithDelegate);// Fetch token account without delegateconst tokenWithoutDelegate = await fetchToken(client.runtime.rpc,ataWithoutDelegate);console.log("\nToken Account without Delegate:", tokenWithoutDelegate);// =============================================================================// Demo Setup Helper Function// =============================================================================
Sicherheitsüberlegungen
Für Konten-Inhaber:
- Genehmigen Sie nur vertrauenswürdige Delegierte
- Legen Sie das minimal notwendige Ausgabenlimit fest
- Widerrufen Sie Delegierungen, wenn sie nicht mehr benötigt werden
- Überwachen Sie Ihre Konten auf unerwartete Überweisungen
Für Dienstleister (Delegierte):
- Kommunizieren Sie das angeforderte Ausgabenlimit klar an die Nutzer
- Implementieren Sie eine ordnungsgemäße Schlüsselverwaltung für Ihr Delegiertenkonto
- Verfolgen Sie den Verbrauch der Genehmigung, um eine erneute Genehmigung anzufordern, bevor die Limits erschöpft sind
Delegierung vs. Verwahrung
| Aspekt | Delegierung | Vollständige Verwahrung |
|---|---|---|
| Token-Eigentum | Nutzer behält | Nutzer überträgt an Verwahrer |
| Ausgabenkontrolle | Begrenzt auf genehmigten Betrag | Vollständiger Zugriff auf übertragene Mittel |
| Widerruf | Sofort, durch Eigentümer | Erfordert Kooperation des Verwahrers |
| Risikoexposition | Begrenzt auf genehmigten Betrag | Gesamtes Guthaben |
| Erforderliches Vertrauen | Begrenzt | Hoch |
Delegierung bietet einen Mittelweg – sie ermöglicht automatisierte Zahlungen und begrenzt gleichzeitig die Risikoexposition auf den genehmigten Betrag.
Verwandte Ressourcen
| Ressource | Beschreibung |
|---|---|
| Approve Delegate | Wie Sie einem anderen Konten die Berechtigung erteilen, von Ihrem Token-Konten auszugeben. |
| Revoke Delegate | Wie Sie einen bestehenden Delegierten entfernen und seine Ausgabeberechtigungen widerrufen. |
| Transfer Token | Wie Sie Token zwischen Token-Konten übertragen. |
Is this page helpful?