Τελευταία Ενημέρωση: 2025-01-09
Τι Θα Δημιουργήσετε
Στον Οδηγό Πλήρους Ροής Συναλλαγών, μάθατε πώς να δημιουργείτε συναλλαγές χωρίς κόστος gas χρησιμοποιώντας το Kora. Υπάρχουν όμως πολλά σενάρια όπου μια μεμονωμένη συναλλαγή δεν επαρκεί ή δεν υπάρχει αρκετός χώρος σε μία συναλλαγή για να συμπεριληφθεί μια οδηγία πληρωμής Kora. Σε αυτόν τον οδηγό, θα δημιουργήσουμε ένα demo που επιδεικνύει πώς να χρησιμοποιήσετε το Kora για να υπογράψετε και να στείλετε μια δέσμη συναλλαγών στον block engine του Jito για ατομική εκτέλεση στο Solana Mainnet. Ο διακομιστής Kora θα πληρώσει το φιλοδώρημα Jito και όλες τις χρεώσεις συναλλαγών.
Το τελικό αποτέλεσμα θα είναι ένα λειτουργικό σύστημα δεσμών Jito:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━KORA JITO BUNDLE DEMO━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━[1/4] Initializing clients→ Kora RPC: http://localhost:8080/→ Solana RPC: https://api.mainnet-beta.solana.com[2/4] Setting up keypairs→ Sender: BYJVBqQ2xV9GECc84FeoPQy2DpgoonZQFQu97MMWTbBc→ Kora signer address: 3Z1Ef7YaxK8oUMoi6exf7wYZjZKWJJsrzJXSt1c3qrDE[3/4] Creating bundle transactions→ Blockhash: 7HZUaMqV...→ Tip account: 96gYZGLn...→ Transaction 1: Kora Memo "Bundle tx #1"→ Transaction 2: Kora Memo "Bundle tx #2"→ Transaction 3: Kora Memo "Bundle tx #3"→ Transaction 4: Kora Memo "Bundle tx #4" + Jito tip✓ 4 transactions created for bundle[4/4] Signing and sending bundle✓ Bundle submitted to Jito block engine→ Bundle UUID: 8f4a3b2c-1d5e-6f7a-8b9c-0d1e2f3a4b5c━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━SUCCESS: Bundle confirmed on Solana━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━Bundle UUID:8f4a3b2c-1d5e-6f7a-8b9c-0d1e2f3a4b5c
Δείτε πώς το δημιουργούμε.
Προαπαιτούμενα
Πριν ξεκινήσετε αυτό το σεμινάριο, βεβαιωθείτε ότι έχετε:
- Ολοκληρώσει τον Οδηγό Πλήρους Ροής Συναλλαγών Kora — θα βασιστούμε σε αυτές τις έννοιες
- Node.js (LTS ή νεότερη έκδοση)
- Εξοικείωση με τις συναλλαγές Solana
- Εξοικείωση με τις Δέσμες Jito
Kora v2.2.0 Beta
Σημαντικό: Αυτός ο οδηγός απαιτεί την έκδοση beta Kora v2.2.0. Μπορείτε να βρείτε την έκδοση εδώ. Αυτή είναι μια προ-έκδοση και ενδέχεται να περιέχει σφάλματα.
cargo install kora-cli@2.2.0-beta.7
Βασικά Στοιχεία Δεσμών Jito
Στο Solana, κάθε οδηγία σε μια συναλλαγή είναι ατομική—εάν αποτύχει μία οδηγία, αποτυγχάνει ολόκληρη η συναλλαγή. Οι δέσμες είναι ένα εργαλείο που σας επιτρέπει να εκτελέσετε έως 5 συναλλαγές ατομικά και διαδοχικά. Οι δέσμες παρακινούνται από ένα φιλοδώρημα—όσο υψηλότερο το φιλοδώρημα, τόσο υψηλότερη η προτεραιότητα.
Αυτός ο οδηγός προϋποθέτει ότι έχετε κάποια βασική κατανόηση και εμπειρία με τις Δέσμες Jito.
Δομή Έργου
Ο δείγμα κώδικα για αυτή τη δοκιμαστική εφαρμογή μπορεί να βρεθεί στα παραδείγματα Kora:
jito-bundles/├── client/│ ├── src/│ │ └── index.ts # Bundle demo implementation│ └── package.json├── server/│ ├── kora.toml # Kora configuration with bundles enabled│ └── signers.toml # Signer configuration└── scripts/└── start-kora.sh # Server startup script
Κλωνοποιήστε το αποθετήριο kora και μεταβείτε στον κατάλογο jito-bundles:
git clone https://github.com/solana-foundation/kora.gitcd kora/examples/jito-bundles
Διαμόρφωση Διακομιστή Kora
kora.toml
Η βασική διαμόρφωση για την υποστήριξη δεσμών:
[kora]rate_limit = 100[kora.auth]api_key = "kora_facilitator_api_key_example"[kora.enabled_methods]sign_bundle = truesign_and_send_bundle = trueestimate_bundle_fee = trueget_blockhash = trueget_config = trueget_payer_signer = true[validation]max_allowed_lamports = 1000000max_signatures = 10price_source = "Mock"allowed_programs = ["11111111111111111111111111111111", # System Program"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr", # Memo Program][validation.fee_payer_policy.system]allow_transfer = true # Required for Jito tip transfers[validation.price]type = "free" # No payment required for this demo[kora.bundle]enabled = true[kora.bundle.jito]block_engine_url = "https://mainnet.block-engine.jito.wtf"
Σημαντικές ρυθμίσεις για την υποστήριξη δεσμών:
- sign_bundle / sign_and_send_bundle — Ενεργοποίηση των μεθόδων RPC δεσμών
- allow_transfer = true — Ο υπογράφων του Kora πληρώνει το φιλοδώρημα Jito, επομένως χρειάζεται άδεια μεταφοράς
- bundle.enabled = true — Γενικός διακόπτης για τη λειτουργικότητα δεσμών
- Χρησιμοποιούμε τη δημόσια διεύθυνση URL της μηχανής μπλοκ mainnet για αυτή τη δοκιμαστική εφαρμογή. Σε παραγωγή, θα χρησιμοποιούσατε την ιδιωτική διεύθυνση URL της μηχανής μπλοκ.
signers.toml
[signer_pool]strategy = "round_robin"[[signers]]name = "main_signer"type = "memory"private_key_env = "KORA_PRIVATE_KEY"
Φροντίστε να μετονομάσετε το .env.example σε .env και ορίστε τη μεταβλητή
περιβάλλοντος KORA_PRIVATE_KEY στο ιδιωτικό σας κλειδί mainnet. Το πορτοφόλι
του υπογράφοντα χρειάζεται SOL στο mainnet για να πληρώσει:
- Τα τέλη συναλλαγών για όλες τις συναλλαγές δεσμών
- Το φιλοδώρημα Jito (ελάχιστο 1.000 lamport)
Σημαντικό: Αυτός ο οδηγός επιδεικνύει τη χρήση φιλοδωρημάτων Jito στο Solana Mainnet. Τα φιλοδωρήματα δεν επιστρέφονται.
Εκκίνηση του Διακομιστή
Από τον κατάλογο server/:
kora --config kora.toml --rpc-url https://api.mainnet-beta.solana.com rpc start --signers-config signers.toml
Ή χρησιμοποιήστε το παρεχόμενο script. Από τον κατάλογο server/:
../scripts/start-kora.sh
Υλοποίηση Πελάτη
Θα εξετάσουμε την υλοποίηση του πελάτη βήμα προς βήμα, ξεκινώντας με τις εισαγωγές.
Εισαγωγές και Διαμόρφωση
import { KoraClient } from "@solana/kora";import {createNoopSigner,address,getBase64EncodedWireTransaction,partiallySignTransactionMessageWithSigners,Blockhash,KeyPairSigner,pipe,createTransactionMessage,setTransactionMessageFeePayerSigner,setTransactionMessageLifetimeUsingBlockhash,appendTransactionMessageInstruction,generateKeyPairSigner} from "@solana/kit";import { getAddMemoInstruction } from "@solana-program/memo";import { getTransferSolInstruction } from "@solana-program/system";const MINIMUM_JITO_TIP = 1_000n; // lamportsconst CONFIG = {solanaRpcUrl: "https://api.mainnet-beta.solana.com",koraRpcUrl: "http://localhost:8080/",jitoTipLamports: MINIMUM_JITO_TIP,bundleSize: 4, // We'll create 4 transactions for this demopollIntervalMs: 6000,pollTimeoutMs: 60000};
Ρυθμίζουμε:
- Εισαγωγές Solana Kit για τη δημιουργία συναλλαγών
- Πρόγραμμα Memo για τις επιδεικτικές συναλλαγές μας (θα το αντικαταστήσετε με πραγματικές λειτουργίες)
- System Program για τη μεταφορά φιλοδωρήματος Jito
- Διαμόρφωση για τα τελικά σημεία RPC και τις παραμέτρους πακέτου
Λογαριασμοί Φιλοδωρήματος Jito
Το Jito διαθέτει 8 λογαριασμούς φιλοδωρήματος στους οποίους μπορείτε να στείλετε SOL. Επιλέγουμε έναν τυχαία για αυτή την επίδειξη.
// Jito tip accounts - one is randomly selected by the block engineconst JITO_TIP_ACCOUNTS = ["96gYZGLnJYVFmbjzopPSU6QiEV5fGqZNyN9nmNhvrZU5","HFqU5x63VTqvQss8hp11i4wVV8bD44PvwucfZ2bU7gRe","Cw8CFyM9FkoMi7K7Crf6HNQqf4uEMzpKw6QNghXLvLkY","ADaUMid9yfUytqMBgopwjb2DTLSokTSzL1zt6iGPaS49","DfXygSm4jCyNCybVYYK6DwvWqjKee8pbDmJGcLWNDXjh","ADuUkR4vqLUMWXxW9gh6D6L8pMSawimctcNZ5pGwDcEt","DttWaMuVvTiduZRnguLF7jNxTgiMBZ1hyAumKUiL2KRL","3AVi9Tg9Uo68tJfuvoKvqKNWKkC5wPdSSdeBnizKZ6jT"];function getRandomTipAccount(): string {return JITO_TIP_ACCOUNTS[Math.floor(Math.random() * JITO_TIP_ACCOUNTS.length)];}
Οι λογαριασμοί φιλοδωρήματος είναι διευθύνσεις που λειτουργούν από το Jito. Η αποστολή SOL σε οποιονδήποτε από αυτούς σηματοδοτεί το ποσό του φιλοδωρήματός σας στους validators.
Βήμα 1: Αρχικοποίηση Πελατών
Αρχικοποιούμε τον πελάτη Kora με το κλειδί API μας, το οποίο ταιριάζει με αυτό
που έχει διαμορφωθεί στο kora.toml. Στην παραγωγή, θα το φορτώνατε από μια
μεταβλητή περιβάλλοντος.
async function initializeClients() {console.log("\n[1/4] Initializing clients");console.log(" → Kora RPC:", CONFIG.koraRpcUrl);console.log(" → Solana RPC:", CONFIG.solanaRpcUrl);const client = new KoraClient({rpcUrl: CONFIG.koraRpcUrl,apiKey: "kora_facilitator_api_key_example"});return { client };}
Βήμα 2: Ρύθμιση Κλειδιών
async function setupKeys(client: KoraClient) {console.log("\n[2/4] Setting up keypairs");const senderKeypair = await generateKeyPairSigner();console.log(" → Sender:", senderKeypair.address);const { signer_address } = await client.getPayerSigner();console.log(" → Kora signer address:", signer_address);return { senderKeypair, signer_address };}
Χρησιμοποιούμε το generateKeyPairSigner() για να δημιουργήσουμε ένα νέο
keypair για την επίδειξη. Επειδή το keypair υπογράφει μόνο τις οδηγίες memo και
δεν χρειάζεται να πληρώσει καμία χρέωση Kora (σύμφωνα με τη διαμόρφωσή μας), δεν
χρειάζονται SOL ή άλλα tokens. Ο υπογράφων του Kora (που ανακτάται μέσω του
getPayerSigner) πληρώνει όλες τις χρεώσεις και το φιλοδώρημα Jito.
Βήμα 3: Δημιουργία Συναλλαγών Πακέτου
Τώρα ας δημιουργήσουμε ένα πακέτο συναλλαγών. Δημιουργούμε πολλαπλές συναλλαγές, η καθεμία με τις δικές της μοναδικές οδηγίες. Χρησιμοποιούμε εδώ μοναδικές οδηγίες memo για να επαληθεύσουμε εύκολα τις συναλλαγές μας αφού εγκατασταθούν στο Solana Mainnet.
async function createBundleTransactions(client: KoraClient,senderKeypair: KeyPairSigner,signer_address: string) {console.log("\n[3/4] Creating bundle transactions");const noopSigner = createNoopSigner(address(signer_address));const latestBlockhash = await client.getBlockhash();const tipAccount = getRandomTipAccount();console.log(" → Blockhash:", latestBlockhash.blockhash.slice(0, 8) + "...");console.log(" → Tip account:", tipAccount.slice(0, 8) + "...");const transactions: string[] = [];for (let i = 0; i < CONFIG.bundleSize; i++) {const isLastTransaction = i === CONFIG.bundleSize - 1;console.log(` → Transaction ${i + 1}: Kora Memo "Bundle tx #${i + 1}"${isLastTransaction ? " + Jito tip" : ""}`);// Build transaction with memolet transactionMessage = pipe(createTransactionMessage({version: 0}),(tx) => setTransactionMessageFeePayerSigner(noopSigner, tx),(tx) =>setTransactionMessageLifetimeUsingBlockhash({blockhash: latestBlockhash.blockhash as Blockhash,lastValidBlockHeight: 0n},tx),(tx) =>appendTransactionMessageInstruction(getAddMemoInstruction({memo: `Kora Bundle tx #${i + 1} of ${CONFIG.bundleSize}`,signers: [senderKeypair]}),tx),// Add Jito tip to the LAST transaction only(tx) =>isLastTransaction? appendTransactionMessageInstruction(getTransferSolInstruction({source: noopSigner,destination: address(tipAccount),amount: CONFIG.jitoTipLamports}),tx): tx);// Sign with sender keypair (required for memo instruction)const signedTransaction =await partiallySignTransactionMessageWithSigners(transactionMessage);const base64Transaction =getBase64EncodedWireTransaction(signedTransaction);transactions.push(base64Transaction);}console.log(` ✓ ${transactions.length} transactions created for bundle`);return transactions;}
Σημαντικό: Φιλοδώρημα που πληρώνεται από τον υπογράφοντα Kora: Εφόσον
θέλουμε ο κόμβος Kora να πληρώσει το φιλοδώρημα Jito, χρησιμοποιούμε έναν
υπογράφοντα "no-op" (noopSigner), όπου η διεύθυνση του Kora είναι η πηγή της
μεταφοράς φιλοδωρήματος. Το Kora θα το υπογράψει κατά την επεξεργασία του
πακέτου.
Βήμα 4: Υπογραφή και Υποβολή Πακέτου
Τώρα μπορούμε να τα συνδυάσουμε όλα μαζί και να στείλουμε το bundle στο Kora για υπογραφή και υποβολή στη μηχανή block του Jito.
async function main() {console.log("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");console.log("KORA JITO BUNDLE DEMO");console.log("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");try {// Step 1: Initialize clientsconst { client } = await initializeClients();// Step 2: Setup keysconst { senderKeypair, signer_address } = await setupKeys(client);// Step 3: Create bundle transactionsconst transactions = await createBundleTransactions(client,senderKeypair,signer_address);// Step 4: Sign and send bundleconsole.log("\n[4/4] Signing and sending bundle");const { bundle_uuid } = await client.signAndSendBundle({transactions,signer_key: signer_address});console.log("\nBundle UUID:");console.log(bundle_uuid);} catch (error) {console.error("\n━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");console.error("ERROR: Demo failed");console.error("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━");console.error("\nDetails:", error);process.exit(1);}}main().catch((e) => console.error("Error:", e));
Εκτέλεση του Demo
1. Ξεκινήστε τον Διακομιστή Kora
cd examples/jito-bundles/serverkora --config kora.toml --rpc-url https://api.mainnet-beta.solana.com rpc start --signers-config signers.toml
2. Εκτελέστε τον Client
Σε ένα νέο τερματικό, μεταβείτε στον κατάλογο client/ και εκτελέστε το demo:
cd examples/jito-bundles/client# Install dependenciespnpm install# Run the demopnpm start
Αναμενόμενο Αποτέλεσμα
Θα πρέπει να δείτε την εκτέλεση βήμα προς βήμα με ένα επιτυχημένο bundle στο τέλος. Το bundle θα:
- Δημιουργήσει 4 συναλλαγές memo
- Προσθέσει ένα φιλοδώρημα Jito (1.000 lamport) στην τελευταία συναλλαγή
- Έχει όλες τις συναλλαγές υπογεγραμμένες από το Kora ως πληρωτής τελών
- Υποβάλει ατομικά στη μηχανή block του Jito
Σημείωση:
- Ο προεπιλεγμένος δρομολογητής του Jito μπορεί να φτάσει τα όρια ρυθμού. Αν λάβετε σφάλμα 429, μπορείτε να δοκιμάσετε ξανά αργότερα ή να ζητήσετε υψηλότερα όρια. Ρίξτε μια ματιά στην τεκμηρίωση περιορισμού ρυθμού του Jito για περισσότερες πληροφορίες.
- Επειδή το demo μας χρησιμοποιεί ένα πολύ μικρό φιλοδώρημα, το bundle ενδέχεται να μην καταχωρηθεί στο Solana Mainnet. Αν δεν δείτε το bundle στον εξερευνητή bundle του Jito, μπορείτε να δοκιμάσετε ξανά αργότερα με υψηλότερο φιλοδώρημα.
Κατανόηση Αυτού που Συνέβη
Ορίστε τι συνέβη διαφορετικά από τις μεμονωμένες συναλλαγές:
- Πολλαπλές Συναλλαγές — Αντί για μία συναλλαγή, δημιουργήσαμε 4 που πρέπει να εκτελεστούν μαζί
- Φιλοδώρημα Jito — Προσθέσαμε μια μεταφορά φιλοδωρήματος (πληρωμένη από τον υπογράφοντα του Kora) για να δώσουμε κίνητρο στους validator
- Επικύρωση Bundle — Το Kora επικύρωσε ότι όλες οι συναλλαγές πληρούν τις
απαιτήσεις που καθορίζονται στο
kora.toml - Ατομική Υποβολή — Όλες οι συναλλαγές υποβλήθηκαν ως μία ενιαία μονάδα στο Jito από τον διακομιστή Kora μας με όλα τα τέλη και τα φιλοδωρήματα να πληρώνονται από τον υπογράφοντα του Kora
Το αποτέλεσμα: είτε και οι 4 συναλλαγές εκτελούνται σε ακολουθία, είτε καμία. Χωρίς ενδιάμεσες καταστάσεις.
Επιπλέον Πόροι
- Χρειάζεστε βοήθεια; Κάντε ερωτήσεις στο
Solana Stack Exchange με ετικέτα
Kora - Τεκμηρίωση Jito — Επίσημη τεκμηρίωση Jito MEV
- Μέθοδοι Bundle RPC — signBundle, signAndSendBundle, estimateBundleFee
- Αποθετήριο GitHub — Πηγαίος κώδικας και παραδείγματα
Is this page helpful?