Μια συναλλαγή Solana είναι ένα container που περιέχει μία ή περισσότερες οδηγίες. Κάθε οδηγία είναι μια λειτουργία—μεταφορά tokens, δημιουργία λογαριασμού, κλήση προγράμματος. Το δίκτυο εκτελεί όλες τις οδηγίες σε μια συναλλαγή διαδοχικά και ατομικά: είτε κάθε οδηγία επιτυγχάνει, είτε ολόκληρη η συναλλαγή αποτυγχάνει και επαναφέρεται.
Αυτό σημαίνει ότι μπορείτε να συσκευάσετε πολλαπλές μεταφορές σε μία μόνο συναλλαγή. Αντί να στείλετε τρεις ξεχωριστές συναλλαγές για να πληρώσετε τρεις παραλήπτες, στέλνετε μία συναλλαγή με τρεις οδηγίες μεταφοράς. Αυτό είναι ταχύτερο (μία επιβεβαίωση αντί για τρεις) και φθηνότερο (μία βασική χρέωση αντί για τρεις). Ακολουθεί ένα ενδεικτικό παράδειγμα του πώς οι πληρωμές (που αναφέρονται ως "drops" σε αυτή την εικόνα) ομαδοποιούνται σε μία μόνο συναλλαγή και πολλαπλές συναλλαγές αποστέλλονται για να διαχειριστούν τη μεγαλύτερη ομάδα.
Διάγραμμα ομαδικών πληρωμών
Πηγή: QuickNode - How to Send Bulk Transactions on Solana
Για περισσότερες πληροφορίες σχετικά με τις συναλλαγές και τις οδηγίες, δείτε τους οδηγούς Συναλλαγές και Οδηγίες.
Η παρακάτω περιγραφή δείχνει πώς να φορτώσετε πολλαπλές οδηγίες μεταφοράς σε μία μόνο συναλλαγή για ομαδικές πληρωμές.
Ομαδοποίηση οδηγιών σε μία μόνο συναλλαγή
Μια συναλλαγή Solana μπορεί να περιέχει πολλαπλές μεταφορές σε διαφορετικούς παραλήπτες. Υπογράφετε μία φορά, πληρώνετε μία χρέωση συναλλαγής και όλες οι μεταφορές διευθετούνται μαζί. Αν οποιαδήποτε μεταφορά αποτύχει, ολόκληρη η συναλλαγή απορρίπτεται.
Δείτε το Πώς λειτουργούν οι πληρωμές στο Solana για βασικές έννοιες πληρωμών.
Η ομαδοποίηση πολλαπλών μεταφορών απαιτεί τη δημιουργία κάθε οδηγίας ξεχωριστά και στη συνέχεια τον συνδυασμό τους σε μία μόνο συναλλαγή.
Τα παρακάτω βήματα δείχνουν τη βασική ροή. Δείτε το Demo για πλήρη εκτελέσιμο κώδικα.
Παραγωγή λογαριασμών token
Πρώτα, παράγετε τις διευθύνσεις Associated Token Account (ATA) για τον αποστολέα και κάθε παραλήπτη. Τα ATA είναι ντετερμινιστικές διευθύνσεις που βασίζονται στο πορτοφόλι και το mint.
const [senderAta] = await findAssociatedTokenPda({mint: mint.address,owner: sender.address,tokenProgram: TOKEN_2022_PROGRAM_ADDRESS});const [recipient1Ata] = await findAssociatedTokenPda({mint: mint.address,owner: recipient1.address,tokenProgram: TOKEN_2022_PROGRAM_ADDRESS});const [recipient2Ata] = await findAssociatedTokenPda({mint: mint.address,owner: recipient2.address,tokenProgram: TOKEN_2022_PROGRAM_ADDRESS});
Δημιουργία οδηγιών μεταφοράς
Δημιουργήστε μια ξεχωριστή οδηγία μεταφοράς για κάθε παραλήπτη. Κάθε οδηγία καθορίζει:
- τη διεύθυνση του λογαριασμού token προέλευσης
- τη διεύθυνση του λογαριασμού token προορισμού
- την εξουσιοδότηση (διεύθυνση κατόχου του λογαριασμού token προέλευσης)
- το ποσό σε βασικές μονάδες (προσαρμοσμένο για τα δεκαδικά του mint)
const [senderAta] = await findAssociatedTokenPda({mint: mint.address,owner: sender.address,tokenProgram: TOKEN_2022_PROGRAM_ADDRESS});const [recipient1Ata] = await findAssociatedTokenPda({mint: mint.address,owner: recipient1.address,tokenProgram: TOKEN_2022_PROGRAM_ADDRESS});const [recipient2Ata] = await findAssociatedTokenPda({mint: mint.address,owner: recipient2.address,tokenProgram: TOKEN_2022_PROGRAM_ADDRESS});const transfer1Instruction = getTransferInstruction({source: senderAta,destination: recipient1Ata,authority: sender.address,amount: 250_000n});const transfer2Instruction = getTransferInstruction({source: senderAta,destination: recipient2Ata,authority: sender.address,amount: 250_000n});
Αποστολή ως μεμονωμένη συναλλαγή
Προσθέστε όλες τις οδηγίες μεταφοράς σε μία συναλλαγή. Αυτό εκτελεί όλες τις μεταφορές ατομικά, είτε όλες οι μεταφορές επιτυγχάνουν είτε ολόκληρη η συναλλαγή αποτυγχάνει.
Επαλήθευση υπολοίπων
Μετά τη μαζική μεταφορά, επαληθεύστε τα υπόλοιπα token για όλα τα μέρη
χρησιμοποιώντας το splToken βοηθητικό εργαλείο.
const [senderAta] = await findAssociatedTokenPda({mint: mint.address,owner: sender.address,tokenProgram: TOKEN_2022_PROGRAM_ADDRESS});const [recipient1Ata] = await findAssociatedTokenPda({mint: mint.address,owner: recipient1.address,tokenProgram: TOKEN_2022_PROGRAM_ADDRESS});const [recipient2Ata] = await findAssociatedTokenPda({mint: mint.address,owner: recipient2.address,tokenProgram: TOKEN_2022_PROGRAM_ADDRESS});const transfer1Instruction = getTransferInstruction({source: senderAta,destination: recipient1Ata,authority: sender.address,amount: 250_000n});const transfer2Instruction = getTransferInstruction({source: senderAta,destination: recipient2Ata,authority: sender.address,amount: 250_000n});const signature = await client.transaction.prepareAndSend({authority: sender,instructions: [transfer1Instruction, transfer2Instruction],version: 0});const splToken = client.splToken({mint: mint.address,tokenProgram: "auto"});const senderBalance = await splToken.fetchBalance(sender.address);const recipient1Balance = await splToken.fetchBalance(recipient1.address);const recipient2Balance = await splToken.fetchBalance(recipient2.address);
Επίδειξη
// Generate keypairs for sender and two recipientsconst sender = (await generateKeypair()).signer;const recipient1 = (await generateKeypair()).signer;const recipient2 = (await generateKeypair()).signer;console.log("Sender Address:", sender.address);console.log("Recipient 1 Address:", recipient1.address);console.log("Recipient 2 Address:", recipient2.address);// Demo Setup: Create client, mint account, token accounts, and fund with initial tokensconst { client, mint } = await demoSetup(sender, recipient1, recipient2);console.log("\nMint Address:", mint.address);// Derive the Associated Token Accounts addresses (ATAs) for sender and recipientsconst [senderAta] = await findAssociatedTokenPda({mint: mint.address,owner: sender.address,tokenProgram: TOKEN_2022_PROGRAM_ADDRESS});const [recipient1Ata] = await findAssociatedTokenPda({mint: mint.address,owner: recipient1.address,tokenProgram: TOKEN_2022_PROGRAM_ADDRESS});const [recipient2Ata] = await findAssociatedTokenPda({mint: mint.address,owner: recipient2.address,tokenProgram: TOKEN_2022_PROGRAM_ADDRESS});console.log("Sender Token Account:", senderAta.toString());console.log("Recipient 1 Token Account:", recipient1Ata.toString());console.log("Recipient 2 Token Account:", recipient2Ata.toString());// =============================================================================// Batch Token Payment Demo// =============================================================================// Create instructions to transfer tokens from sender to both recipients// Transferring 250,000 base units = 0.25 tokens (with 6 decimals) to eachconst transfer1Instruction = getTransferInstruction({source: senderAta,destination: recipient1Ata,authority: sender.address,amount: 250_000n // 0.25 tokens});const transfer2Instruction = getTransferInstruction({source: senderAta,destination: recipient2Ata,authority: sender.address,amount: 250_000n // 0.25 tokens});// Prepare and send both transfers in a single transaction using @solana/clientconst signature = await client.transaction.prepareAndSend({authority: sender,instructions: [transfer1Instruction, transfer2Instruction],version: 0});console.log("\n=== Batch Token Payment Complete ===");console.log("Transaction Signature:", signature.toString());// Fetch final token account balances using @solana/client SPL token helperconst splToken = client.splToken({mint: mint.address,tokenProgram: "auto"});const senderBalance = await splToken.fetchBalance(sender.address);const recipient1Balance = await splToken.fetchBalance(recipient1.address);const recipient2Balance = await splToken.fetchBalance(recipient2.address);console.log("\nSender Token Account Balance:", senderBalance);console.log("Recipient 1 Token Account Balance:", recipient1Balance);console.log("Recipient 2 Token Account Balance:", recipient2Balance);// =============================================================================// Demo Setup Helper Function// =============================================================================
Κλιμάκωση με σχεδιασμό συναλλαγών
Μια μεμονωμένη συναλλαγή έχει όρια μεγέθους—περίπου 1232 bytes. Για μεγάλες μαζικές λειτουργίες (μισθοδοσία για εκατοντάδες υπαλλήλους, μαζικά airdrops), θα υπερβείτε αυτό το όριο και θα χρειαστεί να χωρίσετε την εργασία σε πολλαπλές συναλλαγές.
Αν και μπορείτε να δημιουργήσετε τη δική σας λογική κατανομής συναλλαγών, το
πακέτο
@solana/instruction-plans
(μέρος του Solana Kit) το χειρίζεται σε δύο επίπεδα:
Τα σχέδια οδηγιών ορίζουν τις λειτουργίες σας και τους περιορισμούς σειράς τους:
- Διαδοχικές — οδηγίες που πρέπει να εκτελεστούν με σειρά
- Παράλληλες — οδηγίες που μπορούν να εκτελεστούν με οποιαδήποτε σειρά
- Μη διαιρετές — οδηγίες που πρέπει να παραμείνουν μαζί στην ίδια συναλλαγή
Τα σχέδια συναλλαγών δημιουργούνται από τα σχέδια οδηγιών. Ο σχεδιαστής πακετάρει έξυπνα τις οδηγίες σε συναλλαγές βέλτιστου μεγέθους, σεβόμενος τους περιορισμούς σειράς σας. Το τελικό σχέδιο συναλλαγής μπορεί στη συνέχεια να:
- Εκτελεστεί — υπογραφεί και σταλεί στο δίκτυο, με παράλληλες συναλλαγές να αποστέλλονται ταυτόχρονα
- Προσομοιωθεί — δοκιμαστική εκτέλεση στο δίκτυο για επαλήθευση πριν την αποστολή
- Σειριοποιηθεί — μεταγλωττιστεί σε base64 για εξωτερικές υπηρεσίες υπογραφής ή ροές εργασίας πολλαπλών μερών
Αυτή η προσέγγιση δύο επιπέδων σας επιτρέπει να σκέφτεστε με όρους λειτουργιών ("μεταφορά στην Alice, στη συνέχεια μεταφορά στον Bob") ενώ η βιβλιοθήκη χειρίζεται τη μηχανική του μεγέθους συναλλαγής, του πακεταρίσματος και της παράλληλης εκτέλεσης.
Is this page helpful?