العنوان
95 محرفًا: بادئة الشبكة ومفتاحان عامان ومجموع تحقق بصيغة Base58 خاصة
عنوان Monero القياسي = Base58( prefix ‖ B ‖ A ‖ checksum ). تحدد البادئة الشبكة ونوع العنوان، وB وA هما مفتاحا الإنفاق والعرض العامّان، ومجموع التحقق هو أول 4 بايتات من Keccak-256 لكل ما يسبقه.
البنية
بادئة الشبكة
تُكتب البادئة بصيغة varint (بايت واحد للأعداد الصغيرة). وبسبب طريقة عمل Base58 تحدد البادئة المحرف الأول من العنوان:
| الشبكة | قياسي | مدمج | عنوان فرعي |
|---|---|---|---|
| mainnet | 18 → 4… | 19 → 4… | 42 → 8… |
| stagenet | 24 → 5… | 25 → 5… | 36 → 7… |
| testnet | 53 → 9…/A… | 54 → A… | 63 → B… |
مجموع التحقق
إذا كان في العنوان خطأ مطبعي، فلن يتطابق مجموع التحقق وسترفض المحفظة الإرسال.
Base58 في Monero ليست مثل Bitcoin
الأبجدية نفسها (من دون 0 O I l)، لكن الترميز مختلف. تحوّل Bitcoin الرسالة كلها إلى عدد كبير واحد وتحوله إلى الأساس 58. أما Monero فيقطع البيانات إلى كتل من 8 بايتات ويرمّز كل كتلة على حدة إلى 11 محرفًا بالضبط (والكتلة الجزئية الأخيرة إلى عدد أقل، وفق الجدول).
| البايتات في الكتلة | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
|---|---|---|---|---|---|---|---|---|
| المحارف | 2 | 3 | 5 | 6 | 7 | 9 | 10 | 11 |
69 بايتًا = 8 كتل كاملة (88 محرفًا) + 5 بايتات (7 محارف) = 95 محرفًا. الميزة: طول العنوان ثابت دائمًا والترميز يستغرق زمنًا خطيًا.
const ENC_BLOCK = [0, 2, 3, 5, 6, 7, 9, 10, 11];
function encodeBlock(block) {
let n = 0n;
for (const x of block) n = (n << 8n) | BigInt(x); // big-endian داخل الكتلة
let s = '';
while (n > 0n) { s = ALPHABET[Number(n % 58n)] + s; n /= 58n; }
return s.padStart(ENC_BLOCK[block.length], '1');
}
العنوان المدمج
العنوان المدمج (البادئة 19) = عنوان قياسي + معرّف دفع (payment ID) من 8 بايتات (106 محارف). يُشفَّر معرّف الدفع داخل المعاملة ويساعد المتجر على معرفة أي طلب دُفع. أما اليوم فيُنصح باستخدام العناوين الفرعية بدلًا منه: عنوان فرعي جديد لكل طلب.
ما لا يحتويه العنوان
من المهم أن العنوان لا يُكتب أبدًا على سلسلة الكتل. يستخدم المرسِل A وB لبناء عنوان لمرة واحدة، وهذا وحده ما يصل إلى سلسلة الكتل.