استخدم هذه الصفحة لتوليد المفتاح المناسب للمهمة، ولتحليل عنوان أو التحقق من صحته، ولمعرفة ما يكشفه تسليم مفتاح لشخص آخر. لا توجد حسابات على هذه السلسلة: الرصيد حقيقة تخص ملف مفتاح، ولا تخص السلسلة أبدًا.
مفتاحان، ونوعان من العناوين
| مفتاح العقدة | مفتاح المحفظة | |
|---|---|---|
| يُكتب بواسطة | rand-node keygen | rand keygen |
| السر | بذرة من 32 بايت | مفتاح إنفاق من 256 بت |
| الهوية العامة | عنوان من 32 بايت بترميز base58، من 32 إلى 44 حرفًا | عنوان محمي rand1… من 1,665 أو 1,666 حرفًا |
| يوقّع | الكتل، والأصوات، وعمليات سك الفاوست، وUnbond وWithdraw وRegistration، وعلى السلسلة 20 صوت AdmitValidator؛ وبصفته سلطة السك Key لرمز: TokenMint وSetAuthority. وعلى السلسلة 20 تغطي كل رسالة من هذه الرسائل أيضًا تجزئة الكتلة الأولى (المعاملات) | لا شيء: تُجاز التحويلة بإثباتاتها |
| يظهر على السلسلة بصفته | مقترح كتلة، وصف في سجل المُصدِّقين، وسَاكّ عملية سك الفاوست، وسلطة key لرمز | لا يظهر أبدًا في تحويلة، إذ يكون مختومًا داخل المظاريف. ويُنشر حيث تدخل قيمة إلى المجمّع بمبلغ علني: إيداع عبر الجسر، وسك رمز، وعلى السلسلة 20 دفعة استدعاء، فهذه تسمّي عنوان المستلم؛ وعنوان دفع المُصدِّق موجود في السجل، وتسمّي كتلة التكوين الأولى للسلسلة 20 خزينة رسوم الجسر، ومنذ السلسلة 14 تنشر عملية سك الفاوست وملاحظة alloc في التكوين الأول قيمة pk الخاصة بالمالك، وهي أول 32 بايتًا من العنوان |
| الملف | { "seed", "address", "public_key" }، بصلاحية 0600 | { "version": 2, "spend_key": "<64 hex>" }، بصلاحية 0600 |
لا يختلط المفتاحان أبدًا. يُعرَّف المُصدِّقون بالنوع الأول، ويخدم شكل مفتاح Dilithium2 نفسه سلطة السك Key لرمز (يكتب rand token create --authority-key-out ملفًا بشكل ملف rand-node keygen)، ومفتاح إيقاف الجسر ومفاتيح حرّاسه الستة المقاومة للحوسبة الكمومية. أما مفاتيح الإفادة لدى الحرّاس فهي secp256k1 بعناوين من 20 بايت على نمط Ethereum (الجسر). وتُحفظ القيمة تحت النوع الثاني.
العنوان الشفاف
مفتاح العقدة بذرة من 32 بايت يُشتق منها زوج مفاتيح Dilithium2 اشتقاقًا حتميًا: مفتاح عام من 1,312 بايت وتوقيعات من 2,420 بايت. والعنوان تجزئة BLAKE3 معزولة النطاق للمفتاح العام، مُعرضة بترميز base58:
address = blake3("rand-address" || public_key) // 32 bytes, shown as base58
تحمل الكائنات الموقّعة (الأصوات والكتل وعمليات السك وإجراءات التخزين) المفتاح العام كاملًا، فيتحقق المُتحقِّق من blake3("rand-address" || public_key) == address بدلًا من الوثوق بعنوان مجرد. وتنتج البذرة نفسها أيضًا هوية libp2p للعقدة، وهي مفتاح ed25519 من blake3("rand-p2p-identity" || seed)، وهو معرّف النظير بعد /p2p/ في multiaddr الإقلاع.
rand-node keygen --out node.key.json # prints the address
rand-node address --key node.key.json # address, public key (hex), libp2p peer id
مثال: EdrEC2QRQrQF64iRXxF9927jNj6RidiHHByzx5xD6F1e أحد مُصدِّقي السلسلة 20. تعيد السلاسل من 15 إلى 20 استخدام المفاتيح الثمانية عشر التي دُوِّرت للسلسلة 14، فعناوينها ومعرّفات نظرائها لم تتغير، ولم يعد أي عنوان مُصدِّق أو معرّف نظير من السلسلة 13 قيد الاستخدام؛ وانضم ثمانية مُصدِّقين آخرين بالتزام على السلسلة 15، والستة والعشرون جميعًا في ملف التكوين الأول منذ السلسلة 16.
العنوان المحمي
المحفظة سرّ واحد هو مفتاح الإنفاق sk ذو 256 بت، وكل ما عداه مشتق منه. الاشتقاق بـ Poseidon2 مع وسم نطاق هو أول كلمة تُمتص (H(domain, msg))، وهي الدالة نفسها التي يحسبها zkVM داخل الدائرة:
spend key sk 256 bits, in wallet.key.json
│
├─ viewing key nk = H(NK, sk) sees the whole history; cannot spend
│ ├─ pk = H(PK, nk) the field a note names its owner by
│ ├─ nullifier(cm) = H(NF, nk, cm) what a spend publishes
│ ├─ ovk opens envelopes this wallet sent
│ └─ ML-KEM-768 decapsulation key opens envelopes sent to this wallet
└─ address rand1 + base58(pk || kem_ek)
العنوان هو بايتات pk الـ 32 يليها مفتاح التغليف ML-KEM-768 البالغ 1,184 بايت، بترميز base58 بعد البادئة rand1: 1,665 أو 1,666 حرفًا (يعتمد طول base58 على البايتات الأولى؛ نحو عنوان واحد من كل أربعة عشر هو الأقصر)، أي نحو 1.6 كيلوبايت، ومن غير مجموع اختباري. يحتاج المُرسِل إلى مفتاح التغليف ليختم مظروف الملاحظة، ولهذا هو في العنوان. وهو عام بالتصميم: يستطيع أي أحد الدفع إليه، وامتلاكه لا يدل على شيء مما يحتويه.
rand keygen # wallet.key.json; refuses to overwrite an existing file
rand address # rand1… on stdout, its fingerprint XXXX-XXXX-XXXX-XXXX on stderr
منذ v0.5.10 يطبع rand address العنوان وحده وسطرًا جديدًا على stdout، فيعمل $(rand address) في أي سكربت. وتذهب البصمة إلى stderr.
التحليل، كما تفعله ShieldedAddress::parse تمامًا: انزع rand1، وفكّ ترميز base58، واشترط 32 + 1,184 = 1,216 بايتًا بالضبط؛ أول 32 منها هي pk على هيئة ثماني كلمات u32 بترتيب little-endian، والباقي مفتاح التغليف. ويرفض RPC أي معامل أطول من 2,000 حرف قبل تحليله.
إلى جانب ملف المفتاح تحتفظ المحفظة بـ <key>.key.json.notes.json، وهو ذاكرة مؤقتة للملاحظات التي فتحها هذا المفتاح. وهي تحوي النصوص الصريحة للملاحظات، ولذلك تُكتب بصلاحية 0600 مثل المفتاح؛ وكل صف فيها يمكن استرجاعه بإعادة المسح من الورقة 0.
مشاركة عنوان: البصمة وروابط randpay:
العنوان أطول من أن يُقرأ بصوت عالٍ أو يُقارَن بالعين، ولا يحمل مجموعًا اختباريًا، ولذلك تعرض كل محفظة منذ v0.5.10 بصمة إلى جانبه. والبصمة للعرض فقط: لا شيء على السلسلة أو على الشبكة يحمل بصمة.
fingerprint = first 80 bits of blake3("rand-address-fingerprint-1" || pk_bytes || kem_ek)
= 16 Crockford base32 characters, shown as XXXX-XXXX-XXXX-XXXX
التجزئة على البايتات الخام الـ 1,216 التي يرمّزها العنوان. والأبجدية هي 0123456789ABCDEFGHJKMNPQRSTVWXYZ؛ ويتجاهل التحليل حالة الأحرف والواصلات، ويقرأ O على أنها 0 وI أو L على أنها 1.
يحمل رابط randpay: عنوانًا، واختياريًا ما يُدفع إليه:
randpay:<rand1…>[?amount=<decimal>][&asset=<index | 64 hex | rpl1…>][&memo=<percent-encoded UTF-8>]
يُعبَّر عن amount بوحدات عرض الأصل (RAND عشريًا بتسع خانات عشرية، والرمز بـ decimals الخاص بصف سجله) ويجب ألا يكون صفرًا. وmemo لا يزيد على 510 بايتات من UTF-8. ويُطابَق المخطط دون اعتبار لحالة الأحرف؛ ويُرفض أي معامل مجهول أو مكرر أو ترميز نسبة مئوية فاسد.
rand address --uri --amount 1.5 --memo "invoice #42" --qr # a randpay: link, as a terminal QR
rand contacts add alice rand1q9f… # shows the fingerprint, asks add? [y/N]
rand send alice 1.5 --memo "coffee" # to a contact, with a memo
يقبل rand send <TO> عنوان rand1… أو رابط randpay: أو اسم جهة اتصال محفوظة، ويجرّبها بهذا الترتيب. وتملأ قيم amount وasset وmemo في الرابط ما يتركه سطر الأوامر، ويُرفض أي اختلاف بين قيمة معطاة بالطريقتين. وقبل توليد الإثبات يطبع send السطر to <contact, if any> · fingerprint XXXX-XXXX-XXXX-XXXX · <amount> <asset> ويطلب التأكيد؛ وتمرّر السكربتات --yes. وتُخزَّن جهات الاتصال إلى جانب المفتاح في <key>.contacts.json، بصلاحية 0600. وتنتقل المذكرة داخل مظروف الملاحظة (الملاحظات).
لا يوجد rand balance <address> ولا RPC للرصيد: السلسلة لا تستطيع الإجابة عن ذلك لأي أحد. تحسب المحفظة رصيدها بمسح كل مظروف على السلسلة بمفتاح العرض الخاص بها (الملاحظات).
مفاتيح يمكنك تسليمها لغيرك
الإفصاح خاصية للمفاتيح، ولا تستطيع السلسلة إجبار أحد على شيء منه.
| المفتاح | يفتح | الدقة |
|---|---|---|
مفتاح العرض nk (64 hex) | كل ملاحظة استلمتها المحفظة يومًا، وعبر ovk كل ملاحظة أرسلتها يومًا، مع مبطِل (nullifier) كل إنفاق | كل شيء أو لا شيء، بأثر رجعي وبأثر مستقبلي |
مفتاح معاملة TxKey (32 بايت) | المظروف الواحد الذي ختمه بالضبط: الملاحظة، ومنذ السلسلة 18 مذكرتها | دفعة واحدة |
مفتاح استدعاء K_call | نص المدخلات الخاصة لاستدعاء سري واحد | استدعاء واحد |
لا يستطيع مفتاح العرض أن ينفق. فمنذ السلسلة 17 (التفويض المجزّأ) يُنتَج إثبات الحزمة نفسه من nk، وتحمل كل حزمة أيضًا إثبات تفويض ثانيًا صغيرًا لا يستطيع إنتاجه سوى مفتاح الإنفاق وهو مرتبط بالمعاملة الواحدة (الملاحظات). وهذا ما يتيح تسليم nk إلى مُثبِت مفوَّض، وبالتالي كل تاريخ المحفظة، دون أن يستطيع الإنفاق؛ وتنتج المحفظة إثبات التفويض دائمًا على جهازها. أما العناوين والمفاتيح والملاحظات القائمة فلا يغيّرها التجزيء. تشتق المحفظة nk في كل تشغيل ولا تخزّنه أبدًا؛ ويُسحب كل TxKey من جديد لكل مظروف ويُتلف بعد الختم. ويمكن تسليم مفتاح عرض إلى عقدة عبر rand_importViewingKey (في الذاكرة، بحد أقصى 64 لكل عقدة، ويزول عند إعادة التشغيل) لتمسح نيابة عن صاحبه — وهو مسار المستكشف — ويفحص rand_checkTransaction(hash, key) دفعة واحدة مقابل TxKey في استدعاء واحد عديم الحالة. ويطبع rand viewing-key المفتاح nk، ويطبع rand tx-key <hash> مفتاح كل ناتج من معاملة تستطيع هذه المحفظة فتحه.
معرّفات الرموز ليست عناوين
لرمز RPL نوع ثالث من المعرّفات النصية، وهو يسمّي رمزًا ولا يسمّي حاملًا أبدًا. يُعرض معرّف الأصل للرمز، وهو من 32 بايتًا، بصيغة 64 حرفًا hex وبصيغة rpl1…: bech32m (BIP-350) مع الجزء المقروء rpl فوق بايتات المعرّف الـ 32، أي 52 حرف بيانات و6 أحرف مجموع اختباري، 62 حرفًا. والتحليل صارم: يُرفض المجموع الاختباري الخاطئ، أو جزء مقروء آخر، أو حمولة ليست 32 بايتًا بالضبط، أو خلط الحالات، فلا يُحَلّ خطأ مطبعي إلى رمز آخر. ولا تحمل الملاحظة المعرّف؛ فكلمة asset فيها هي الفهرس الكثيف للرمز في السجل (رموز RPL).
مستلم الجسر
لصيغة الجسر على الشبكة خانة مستلم من 32 بايت، ولا يتسع فيها عنوان محمي. واليوم تحمل الخانة تجزئة للعنوان:
recipient_hash = blake3("rand-shielded-recipient" || pk_bytes || kem_ek)
يسمّي المودِع على سلسلة المصدر التجزئة، ويوقّعها الحرّاس، وتحمل معاملة BridgeAttest العنوان كاملًا ليتحقق السجل منه مقابلها (الجسر).
العنوان المحمي القصير: جُرِّب على السلسلة 11 ثم أُلغي
السلسلة 11 (وسم العقدة الكاملة v0.2، 2026-09-17) استبدلت العنوان الطويل بـمعرّف مستلِم من 53 إلى 55 حرفًا، هو rand1 + base58(blake3(receiver signing key) ‖ checksum)، ونقلت مفتاح التغليف ML-KEM إلى سجلّ مستلِم موقَّع يجلبه المرسِل من سجلّ المستكشف أو يتلقاه مضمَّنًا في طلب الدفع. عملت يومًا واحدًا ثم أُعيدت إلى ما كانت عليه في اليوم نفسه (العقدة الكاملة 17db41d)؛ وعادت السلسلة 12 إلى العنوان الطويل تمامًا كما هو موصوف أعلاه، وكل سلسلة بعدها، ومنها السلسلة 20، تحتفظ به.
لماذا أُزيل. معرّف المستلِم تجزئة، ولا يستطيع المرسِل أن يختم note على تجزئة. فأول دفعة إلى محفظة لم تُسجَّل قط كانت تتطلب من المستلِم أن يسلّم طلب دفع أو ملف سجلّ، والتسجيل نفسه كان يُدفع بتحويل ذاتي، وهو ما لا تستطيع محفظة جديدة فارغة أن تجريه. كما أن مسارَي التسليم كليهما كانا يُعلمان السجلّ بمن توشك أن تُدفع إليه الدفعة. أما التصميم الذي يحتفظ بعنوان قصير وبقابلية الإرسال غير المشروطة وبالخصوصية التشفيرية فهو عنوان هجين: مفتاح X25519 من 32 بايت مضمَّن (نحو 93 حرفًا)، والمفتاح المقاوم للحوسبة الكمومية يُجلب بالبحث، بحيث تكون أول دفعة إلى محفظة غير مسجَّلة سرّية في مواجهة الخصوم الكلاسيكيين، وكل دفعة بعدها مقاومة للحوسبة الكمومية بالكامل. هذا ما يُحدَّد في الجزء التالي؛ وإلى أن يصدر، يبقى العنوان الطويل هو العنوان.
تبقى مواصفة السلسلة 11 وتنفيذها في تاريخ العقدة الكاملة (docs/superpowers/specs/2026-09-17-short-shielded-address.md، الوسم v0.2) لأجل الأجزاء التي يعيد التصميم الهجين استخدامها: مفتاح توقيع المستلِم المشتق، والسجلّ الموقَّع ومُتحقِّقه، والسجلّ بوصفه حالة على السلسلة.