كل أصل قابل للتداول على Solana — بما في ذلك الأصول الأساسية والمقابلة لكل مجموعة Raydium — عبارة عن توكن مضروب من قِبل أحد البرنامجين: برنامج SPL Token القديم أو خليفته Token-2022. وهما برنامجان منفصلان في عناوين منفصلة، بتخطيطات حسابات وبنى امتداد مختلفة. يدعم Raydium كليهما، لكن ليس في كل مكان: يقبل CPMM و CLMM و Farm v6 توكنات Token-2022؛ AMM v4 لا يقبلها. يعتبر فهم هذا الانقسام ضروريًا قبل التكامل مع أي مجموعة.
البرنامجان
| SPL Token | Token-2022 |
|---|
| معرّف البرنامج | TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA | TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb |
| تاريخ الإطلاق | 2020 | 2022 |
| حجم الحساب (حساب التوكن) | 165 B | 165 B + الملحقات (متغير) |
| الملحقات | لا | نعم — أكثر من 17 ملحق رسمي |
| التوافقية القديمة | كاملة | اختياري حسب التوكن |
يتم صيانة كلاهما من قِبل فريق Solana Labs (الآن Anza) ويوجدان في مستودع solana-program-library.
لماذا برنامجان؟
تم تجميد SPL Token للتوافقية العكسية — كود البايتات الخاص به غير قابل للتغيير بشكل فعلي، مما يجعله أساساً نظيفاً للنظام البيئي بأكمله. مع توسع حالات الاستخدام (العملات المستقرة التي تريد رسوم التحويل، والتوكنات المؤسسية التي تحتاج سلطات التجميد الدقيقة، و NFTs التي تحتاج مؤشرات البيانات الوصفية)، قدم فريق Solana Token-2022 كبرنامج منفصل وقابل للتوسع بدلاً من ترقية SPL Token. وهذا يحافظ على التكاملات الموجودة ويتيح لكل توكن اختيار الملحقات التي يحتاجها بالضبط.
Token-2022 هو مجموعة فائقة من حيث الوظائف، وليس من حيث مساحة العنوان: يتعايش البرنامجان معاً، وأي توكن في عنوان معين ينتمي إلى واحد منهما فقط.
هيكل الحساب
حساب التوكن (Mint account)
يحدد هوية التوكن.
توكن SPL Token (82 بايت):
u32 mint_authority_option
Pubkey mint_authority
u64 supply
u8 decimals
bool is_initialized
u32 freeze_authority_option
Pubkey freeze_authority
توكن Token-2022: نفس التخطيط الأساسي، بالإضافة إلى صفر أو أكثر من سجلات TLV للملحقات (type-length-value) مُلحقة بعد الأساس.
حساب التوكن (Token account)
يحتفظ برصيد من توكن معين لمالك معين.
حساب SPL Token (165 بايت):
Pubkey mint
Pubkey owner
u64 amount
u32 delegate_option
Pubkey delegate
u8 state // initialized, frozen
u32 is_native_option
u64 is_native
u64 delegated_amount
u32 close_authority_option
Pubkey close_authority
حساب Token-2022: نفس الأساس، بالإضافة إلى سجلات TLV للملحقات إن كانت أي ملحقات مفعّلة.
ملحقات Token-2022
الملحقات هي ميزات معيارية يمكن إرفاقها بالتوكنات أو الحسابات. كل ملحق عبارة عن سجل TLV منفصل. الملحقات الرئيسية لـ Raydium:
رسم التحويل (Transfer fee)
يمكن للتوكن فرض رسم بنسبة مئوية على كل تحويل. يذهب الرسم إلى سلطة سحب مكوّنة. مدعوم من قِبل Raydium CPMM و CLMM عبر SwapV2 — يأخذ البرنامج الرسم في الاعتبار عند حساب أسعار الصرف، لذلك يبقى رياضيات المجموعة متماسكة.
let extension = TransferFeeConfig {
transfer_fee_config_authority,
withdraw_withheld_authority,
withheld_amount: 0,
older_transfer_fee: ...,
newer_transfer_fee: ...,
};
خطاف التحويل (Transfer hook)
يشير التوكن إلى برنامج يستدعيه البيئة التشغيلية عند كل تحويل. يمكن لبرنامج الخطاف رفض التحويل أو إجراء تأثيرات جانبية (تحديث حالة الامتثال، تسجيل، إلخ). يستدعي Raydium CPMM/CLMM الخطاف عبر SwapV2 — تتضمن المعاملة برنامج الخطاف وأي حسابات إضافية يحتاجها.
محمل على الفائدة (Interest-bearing)
الرصيد المتسلسل يتراكم بفائدة بمعدل مكوّن. للعرض فقط (تظهر الأرصدة أعلى بمرور الوقت) وليس توكن فعلي؛ العرض الأساسي لم يتغير.
سلطة إغلاق التوكن (Mint close authority)
يسمح بإغلاق التوكن بمجرد وصول العرض إلى الصفر.
المفوّض الدائم (Permanent delegate)
يمكن لمحفظة معينة تحويل أو حرق التوكنات من أي حساب بدون قيود. يحظر Raydium إنشاء مجموعة لتوكنات بهذا الملحق — إنه غير متوافق مع الثابت الذي ينص على أنه لا يمكن الاستيلاء على احتياطيات المجموعة.
غير قابل للتحويل (Non-transferable)
لا يمكن نقل التوكنات من الحساب الذي تم ضربها فيه. يحظر Raydium إنشاء مجموعة — لا يمكن أن يكون أصل غير قابل للتداول أساس أو مقابل لمجموعة LP.
حالة الحساب الافتراضية (Default account state)
حسابات التوكن الجديدة لهذا التوكن مجمدة افتراضياً ويجب إلغاء تجميدها من قِبل سلطة التجميد. قابل للاستخدام لكنه نادر.
التحويل السري (Confidential transfer)
الأرصدة ومبالغ التحويل مشفرة. لا يدعم Raydium توكنات التحويل السري (رياضيات المجموعة تتطلب أرصدة نصية واضحة).
يستبدل بيانات Metaplex الوصفية لتوكنات Token-2022. مدعوم لقوائم مجموعات Raydium.
مؤشر المجموعة / الأعضاء (Group / Member pointer)
يعلن أن التوكن ينتمي إلى مجموعة (على سبيل المثال، مجموعة NFT). معلوماتي؛ يستخدمه Raydium للعرض.
انظر صفحة ملحقات Token-2022 الرسمية للقائمة الكاملة.
منتجات Raydium التي تدعم ماذا
| المنتج | SPL Token | Token-2022 | ملاحظات |
|---|
| AMM v4 | نعم | لا | يتطلب تكامل OpenBook توكن SPL |
| CPMM | نعم | نعم | يتطلب SwapV2 لمجموعات Token-2022 |
| CLMM | نعم | نعم | يتطلب SwapV2 لمجموعات Token-2022 |
| Farm v6 | نعم | نعم | مدعوم لكل من توكن الحصة وتوكنات المكافآت |
| LaunchLab | نعم | نعم | مجموعات CPMM المتخرجة ترث دعم Token-2022 |
أهلية التوكن لمجموعات Raydium — جميع الملحقات مسموحة إلا إذا تم إدراجها:
- مسدود: غير قابل للتحويل، مفوّض دائم، تحويل سري، حالة حساب افتراضية (في تكوينات مرفوضة).
- مسموح مع تحفظات (يجب على LP قبول المخاطر): رسم التحويل، خطاف التحويل، سلطة التجميد نشطة.
- مسموح بالكامل: محمل على الفائدة، مؤشر البيانات الوصفية، مؤشر المجموعة، سلطة إغلاق التوكن.
يتضمن رد استجابة getPoolInfoFromRpc أعلام امتداد التوكن — يجب على العملاء التحقق قبل LP.
معايير حساب التوكن
حساب التوكن المرتبط (Associated Token Account - ATA)
يشترك كلا البرنامجين في اتفاقية حساب التوكن المرتبط: PDA مشتق من [owner, programId, mint] عبر برنامج الحساب المرتبط (ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL). يتم تخزين حساب التوكن الخاص بكل مستخدم تقريباً على Solana في ATA.
import { getAssociatedTokenAddressSync } from "@solana/spl-token";
// SPL Token
const ata = getAssociatedTokenAddressSync(mint, owner);
// Token-2022
const ata22 = getAssociatedTokenAddressSync(
mint,
owner,
false, // allowOwnerOffCurve
TOKEN_2022_PROGRAM_ID,
);
يقوم برنامج ATA بإنشاء حسابات مملوكة لبرنامج التوكن المناسب بناءً على البرنامج الذي يمتلك التوكن.
حسابات التوكن غير المرتبطة (Non-ATA)
يمكن للمحفظة أن تمتلك عدة حسابات توكن لنفس التوكن؛ ATA مجرد اتفاقية. على سبيل المثال، خزانات المجموعة ليست ATAs — فهي PDAs في برنامج المجموعة، تحتفظ باحتياطيات المجموعة.
الكشف عن البرنامج الذي ينتمي إليه التوكن
لكل حساب توكن حقل owner يشير إلى SPL Token أو Token-2022:
const mintInfo = await connection.getAccountInfo(mintPubkey);
if (mintInfo.owner.equals(TOKEN_PROGRAM_ID)) {
console.log("SPL Token mint");
} else if (mintInfo.owner.equals(TOKEN_2022_PROGRAM_ID)) {
console.log("Token-2022 mint");
}
يتعامل SDK الخاص بـ Raydium مع هذا الكشف تلقائياً — يعود getPoolInfoFromRpc بـ programId المناسب لكل توكن حتى يتمكن العملاء من بناء ATAs صحيحة.
تعليمات المبادلة حسب البرنامج
لكل من CPMM و CLMM في Raydium تعليمتا مبادلة:
| التعليمة | التوكنات المدعومة |
|---|
Swap / SwapBaseInput (legacy) | SPL Token فقط |
SwapV2 / SwapBaseInputV2 | SPL Token و Token-2022 معاً |
يأخذ SwapV2 حسابات إضافية: حسابات التوكن على كلا الجانبين، برنامج التوكن لكل جانب (حيث قد يختلفان)، و — لتوكنات خطاف التحويل — برنامج الخطاف وحساباته المطلوبة.
يجب على العملاء استخدام SwapV2 دائماً عندما يكون أحد الجانبين Token-2022؛ يعمل SwapV2 أيضاً مع مجموعات SPL فقط، لكن Swap القديم أرخص من حيث الحساب.
يختار SDK الخيار الصحيح تلقائياً.
ترحيل مشروع SPL Token إلى Token-2022
Token-2022 ليس بديلاً فوري على مستوى التوكن — التوكن في العنوان X إما SPL أو Token-2022، وهذا ثابت عند الإنشاء. للـ “ترحيل” يجب عليك:
- إنشاء توكن جديد تحت Token-2022 بالملحقات التي تريدها.
- توفير آلية تبديل/الالتفاف لحاملي توكن SPL القديم لتبديله بالجديد.
- تحديث جميع مجموعات LP والمزارع والتكاملات للإشارة إلى التوكن الجديد.
هذا ثقيل. معظم المشاريع التي تم إطلاقها تحت SPL تبقى تحت SPL ما لم تجبرها احتياجات ملحق محددة على الانتقال.
مثال عملي: إنشاء توكن Token-2022 برسم تحويل
import {
Connection, Keypair, SystemProgram, Transaction, sendAndConfirmTransaction,
} from "@solana/web3.js";
import {
TOKEN_2022_PROGRAM_ID, ExtensionType, createInitializeMintInstruction,
getMintLen, createInitializeTransferFeeConfigInstruction,
} from "@solana/spl-token";
const connection = new Connection("https://api.mainnet-beta.solana.com");
const payer = Keypair.generate();
const mint = Keypair.generate();
const extensions = [ExtensionType.TransferFeeConfig];
const mintLen = getMintLen(extensions);
const rentLamports = await connection.getMinimumBalanceForRentExemption(mintLen);
const tx = new Transaction().add(
SystemProgram.createAccount({
fromPubkey: payer.publicKey,
newAccountPubkey: mint.publicKey,
space: mintLen,
lamports: rentLamports,
programId: TOKEN_2022_PROGRAM_ID,
}),
createInitializeTransferFeeConfigInstruction(
mint.publicKey,
payer.publicKey, // transfer fee authority
payer.publicKey, // withdraw-withheld authority
50, // 50 bps = 0.5%
BigInt(1_000_000), // max fee per transfer (smallest units)
TOKEN_2022_PROGRAM_ID,
),
createInitializeMintInstruction(
mint.publicKey,
9, // decimals
payer.publicKey, // mint authority
null, // freeze authority
TOKEN_2022_PROGRAM_ID,
),
);
await sendAndConfirmTransaction(connection, tx, [payer, mint]);
يمكن لهذا التوكن أن يكون LP في مجموعة Raydium CPMM؛ سيدفع المتداولون رسم التحويل 0.5% بالإضافة إلى رسم المجموعة.
الاعتبارات الأمنية
قبل LP أو المبادلة من خلال توكن Token-2022:
- تحقق من
freeze_authority. إذا كانت غير فارغة ومحتفظ بها من قِبل طرف مركزي، يمكنهم تجميد ATA الخاص بك (وربما خزانة المجموعة).
- تحقق من
transfer_hook. يمكن لبرنامج الخطاف حظر التحويلات بشكل تعسفي — تحقق بنفسك من مصدر الخطاف.
- تحقق من
transfer_fee. احسب الرسم في الناتج المتوقع للمبادلة.
- تحقق من
permanent_delegate و non_transferable. يرفض برنامج Raydium هذه، لكن تحقق إذا كنت تبني تكاملاً مخصصاً.
انظر security/oracle-and-token-risks لإطار عمل قبول المخاطر الكامل.
مؤشرات
المصادر: