Τα Token Programs του Solana υποστηρίζουν εξουσιοδότηση—παραχώρηση άδειας σε άλλο λογαριασμό να μεταφέρει tokens από το token account σας μέχρι ένα καθορισμένο όριο. Αυτό επιτρέπει περιπτώσεις χρήσης όπως αυτοματοποιημένες πληρωμές, υπηρεσίες εγγύησης και επεξεργασία πληρωμών από τρίτους χωρίς να παραδώσετε την κατοχή των κεφαλαίων σας.
Πώς λειτουργεί η εξουσιοδότηση
Όταν εγκρίνετε έναν εξουσιοδοτημένο, εξουσιοδοτείτε έναν συγκεκριμένο λογαριασμό να μεταφέρει tokens εκ μέρους σας:
- Ο κάτοχος διατηρεί την κατοχή: Εξακολουθείτε να κατέχετε τα tokens και μπορείτε να τα μεταφέρετε ή να ανακαλέσετε την εξουσιοδότηση ανά πάσα στιγμή
- Περιορισμένη δαπάνη: Ο εξουσιοδοτημένος μπορεί να μεταφέρει μόνο μέχρι το εγκεκριμένο ποσό
- Ένας εξουσιοδοτημένος ανά λογαριασμό: Κάθε token account μπορεί να έχει μόνο έναν ενεργό εξουσιοδοτημένο
- Η νέα έγκριση αντικαθιστά την παλιά: Η έγκριση νέου εξουσιοδοτημένου ανακαλεί αυτόματα τον προηγούμενο
Η εξουσιοδότηση δεν μεταβιβάζει την κατοχή. Ο εξουσιοδοτημένος μπορεί να δαπανήσει tokens μέχρι το όριο, αλλά δεν μπορεί να αποκτήσει πρόσβαση ή να αδειάσει τον λογαριασμό πέρα από το εγκεκριμένο ποσό. Ο κάτοχος μπορεί να ανακαλέσει ανά πάσα στιγμή.
Επιχειρηματικές περιπτώσεις χρήσης
| Περίπτωση χρήσης | Πώς βοηθά η εξουσιοδότηση |
|---|---|
| Επεξεργαστές πληρωμών | Ο έμπορος παραχωρεί άδεια στον επεξεργαστή να διευθετεί συναλλαγές |
| Αυτοματοποιημένη μισθοδοσία | Το ταμείο εγκρίνει την υπηρεσία μισθοδοσίας να καταβάλει μισθούς |
| Υπηρεσίες εγγύησης | Ο αγοραστής εξουσιοδοτεί τον πράκτορα εγγύησης για υπό όρους απελευθέρωση |
| Πλατφόρμες συναλλαγών | Ο χρήστης εγκρίνει το ανταλλακτήριο να εκτελεί συναλλαγές εκ μέρους του |
| Έκδοση καρτών | Ο χρήστης εγκρίνει τον εκδότη κάρτας να χρεώνει αγορές στο token account του |
Έγκριση εξουσιοδοτημένου
Παραχωρήστε σε έναν άλλο λογαριασμό άδεια να ξοδέψει tokens από τον λογαριασμό σας:
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});
Παράμετροι:
source: Ο λογαριασμός token που παραχωρεί την άδειαdelegate: Ο λογαριασμός που θα έχει άδεια δαπάνηςowner: Τρέχων κάτοχος του λογαριασμού token (πρέπει να υπογράψει τη συναλλαγή)amount: Μέγιστος αριθμός tokens που μπορεί να μεταφέρει ο εκπρόσωποςdecimals: Δεκαδικά ψηφία του token για επικύρωση (αποτρέπει σφάλματα δεκαδικών)
Επίδειξη
// 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// =============================================================================
Ανάκληση εκπροσώπου
Αφαιρέστε όλες τις άδειες δαπάνης από τον τρέχοντα εκπρόσωπο:
import { getRevokeInstruction } from "@solana-program/token";const revokeInstruction = getRevokeInstruction({source: tokenAccountAddress, // Your token accountowner: ownerKeypair // You (must sign)});
Η ανάκληση αφαιρεί όλες τις άδειες εκπροσώπου—δεν υπάρχει μερική ανάκληση. Αν χρειάζεται να μειώσετε το όριο, εγκρίνετε τον ίδιο εκπρόσωπο με χαμηλότερο ποσό.
Επίδειξη
// 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// =============================================================================
Μεταφορά ως εκπρόσωπος
Όταν ενεργείτε ως εκπρόσωπος, χρησιμοποιήστε μια τυπική μεταφορά αλλά υπογράψτε με το keypair του εκπροσώπου αντί του κατόχου:
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});
Η μεταφορά θα επιτύχει αν:
- Ο λογαριασμός προέλευσης έχει επαρκές υπόλοιπο
- Ο εκπρόσωπος υπογράφει τη συναλλαγή
Κάθε μεταφορά μειώνει το υπόλοιπο επιτρεπόμενο ποσό. Όταν το επιτρεπόμενο ποσό φτάσει στο μηδέν, ο εκπρόσωπος δεν μπορεί πλέον να μεταφέρει tokens.
Επίδειξη
// 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// =============================================================================
Έλεγχος κατάστασης εξουσιοδότησης
Ερωτήστε έναν λογαριασμό token για να δείτε τον τρέχοντα εκπρόσωπό του και το υπόλοιπο όριο:
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// =============================================================================
Ζητήματα ασφαλείας
Για κατόχους λογαριασμών:
- Εγκρίνετε μόνο αξιόπιστους εκπροσώπους
- Ορίστε το ελάχιστο απαραίτητο όριο δαπανών
- Ανακαλέστε τις εξουσιοδοτήσεις όταν δεν χρειάζονται πλέον
- Παρακολουθείτε τους λογαριασμούς σας για μη αναμενόμενες μεταφορές
Για παρόχους υπηρεσιών (εκπροσώπους):
- Επικοινωνήστε με σαφήνεια το ζητούμενο όριο δαπανών στους χρήστες
- Εφαρμόστε κατάλληλη διαχείριση κλειδιών για τον λογαριασμό εκπροσώπου σας
- Παρακολουθείτε την κατανάλωση του ορίου για να ζητήσετε επανέγκριση πριν εξαντληθούν τα όρια
Εξουσιοδότηση έναντι επιμέλειας
| Πτυχή | Εξουσιοδότηση | Πλήρης επιμέλεια |
|---|---|---|
| Ιδιοκτησία token | Ο χρήστης διατηρεί | Ο χρήστης μεταφέρει στον επιμελητή |
| Έλεγχος δαπανών | Περιορισμένος στο εγκεκριμένο ποσό | Πλήρης πρόσβαση στα μεταφερόμενα κεφάλαια |
| Ανάκληση | Άμεση, από τον κάτοχο | Απαιτεί συνεργασία επιμελητή |
| Έκθεση σε κίνδυνο | Περιορισμένη στο εγκεκριμένο ποσό | Ολόκληρο το υπόλοιπο |
| Απαιτούμενη εμπιστοσύνη | Περιορισμένη | Υψηλή |
Η εξουσιοδότηση παρέχει μια ενδιάμεση λύση—επιτρέποντας αυτοματοποιημένες πληρωμές ενώ περιορίζει την έκθεση σε κίνδυνο στο εγκεκριμένο ποσό.
Σχετικοί πόροι
| Πόρος | Περιγραφή |
|---|---|
| Έγκριση εκπροσώπου | Πώς να χορηγήσετε σε άλλον λογαριασμό άδεια να δαπανήσει από τον λογαριασμό token σας. |
| Ανάκληση εκπροσώπου | Πώς να αφαιρέσετε έναν υπάρχοντα εκπρόσωπο και να ανακαλέσετε τα δικαιώματα δαπάνης του. |
| Μεταφορά token | Πώς να μεταφέρετε tokens μεταξύ λογαριασμών token. |
Is this page helpful?