استخدم هذه الصفحة لقراءة rand_getSupply قراءة صحيحة وللاستدلال على الإصدار: من أين يأتي RAND، وإلى أين يذهب، والمتطابقة التي تجعل عرض سلسلة محمية دقيقًا تمامًا مع أن أحدًا لا يستطيع جمع ملاحظاتها.
من أين يأتي RAND وإلى أين يذهب
لا تستطيع السلسلة المحمية أن تجمع أموالها بنفسها: فقيمة الملاحظة مخبأة داخل التزامها. أما العلني فهو كل عبور لحدود المجمّع. وهي خمسة أنواع، وسبعة على سلسلة فيها خزائن البرامج (RPL-2، السلسلة 20):
| الاتجاه | العبور | متى |
|---|---|---|
| دخول | ملاحظة إيداع في التكوين الأول (alloc في ملف التكوين الأول، مفتوحة منذ السلسلة 14) | الكتلة 0 |
| دخول | سك من الصنبور (Mint، حتى 100 RAND، بتوقيع مدقّق، ويحمل فتح الملاحظة منذ السلسلة 14) | سلاسل testnet التي فيها "faucet": true؛ وعلى السلسلة 20 لا يكون إلا لـ 16 محفظة في القائمة المسموح بها، بتوقيع أحد الساكّين الثمانية عشر المدرجين في التكوين الأول، وبما لا يزيد على 10,000 RAND في كل حقبة من 1,000 كتلة |
| دخول | Withdraw من مدقّق، يدفع الحصة المحرَّرة والمكافآت إلى ملاحظة | في أي وقت |
| خروج | fee الحزمة، إلى rewards مقترِح الكتلة | كل حزمة |
| خروج | burn_r الحزمة: Bond يحرق حصة في stake العلنية لمدقّق | كل ربط |
| خروج | burn_r في Invoke: RAND يُودَع في خزينة علنية لبرنامج | السلسلة 20، منذ v0.6.8 |
| دخول | دفعة من خزينة: RAND يدفعه Invoke من خزينة برنامج في صورة ملاحظة، ومبلغها ومستلمها علنيان | السلسلة 20، منذ v0.6.8 |
وعلى سلسلة يضبط تكوينها الأول tokens.burn_registration_fee، كما في السلسلة 20، فإن registration_fee البالغة 1 RAND لتسجيل رمز تخرج أيضًا من المجمّع عبر burned، لكنها لا تدخل في أي قيد من قيود السجل: فهي تُتلَف، ولا يحتفظ المقترِح إلا بالرسم الأساسي للحزمة.
وإلى جانب المجمّع يقع سجل المدقّقين، الذي يحتفظ بالمبالغ علنًا لأن وزن الإجماع يجب أن يكون علنيًا. والحصة في السجل هي RAND حقيقي: يمكن فك ربطها وسحبها إلى ملاحظة من جديد. وعلى السلسلة 20 تشكّل خزائن البرامج رصيدًا علنيًا ثانيًا بجانبه: فالـ RAND الذي يودعه استدعاء يظل قابلًا للعدّ هناك إلى أن تعيده دفعة إلى المجمّع في صورة ملاحظة.
لا مكافآت كتل ولا تضخم على السلسلة 20. وأول إصدار مجدول للسلسلة هو إعانة تجميع الكتل — مقدار متناقص من RAND الجديد لكل كتلة مختومة، يُدفع للمُجمِّع الذي يغطي إثباته تلك الكتلة — وهو غير مفعَّل على السلسلة 20 (الإثباتات). السلسلة 20 سلسلة جديدة، بدأت العمل في 2026-10-01 الساعة 06:17 بالتوقيت العالمي، مشتقة من السلسلة 19 (fullnode v0.6.8، شوكة صلبة). وقد أصدر تكوينها الأول 31,184.243719258 RAND: 26,000 مرهونة عبر المدقّقين الستة والعشرين في التكوين الأول، و5,184.243719258 في سبع ملاحظات إيداع، هي أرصدة محافظ المشغّلين السبع المنقولة من السلسلة 19. أما ما كانت تحتفظ به المحافظ الأخرى على السلسلة 19، نحو 519.9 RAND (سك من الصنبور لمستلمين في القائمة المسموح بها، ومدفوعات إلى المستخدمين)، فلم يُنقل، لأن الملاحظة لا يمكن إعادة إنشائها دون عنوان صاحبها؛ ولم تُنقل كذلك 0.499 RAND من مكافآت المدقّقين غير المسحوبة. وملاحظتان أخريان في التكوين الأول، فيصبح مجموعها تسعًا، تحملان 99 zUSD للجسر (10 و89)، وهي ليست RAND وتقع خارج هذا التدقيق. وتقرأ rand_getSupply على السلسلة 20 القيمة genesis_deposited = 5,184,243,719,258 وحدة وinvariant_holds: true (الارتفاع 3,037، 2026-10-01). أما السلسلة 19، المشتقة في اليوم نفسه من لقطة للسلسلة 18 عند الارتفاع 141,935، فقد أصدرت 31,294.644359629 RAND: الحصة المرهونة نفسها 26,000 و5,294.644359629 في سبع ملاحظات، إلى جانب ملاحظة واحدة بقيمة 10 zUSD. وكل سك من الصنبور بعد ذلك يضيف إلى الرقم المُصدَر، وكل رسم تسجيل محروق يخصم منه. وأما السلسلة 15، المشتقة في 2026-09-26، فقد أصدرت 23,000 RAND في تكوينها الأول، 18,000 مرهونة عبر 18 مدقّقًا و5,000 في خمس ملاحظات؛ وقد ربط مدقّقوها الثمانية اللاحقون من ملاحظات موجودة، فلم يُصدروا شيئًا.
الرموز خارج هذا التدقيق
العبورات المذكورة أعلاه هي عبورات RAND. أما رمز RPL، مجسَّرًا كان أم أصليًا، فلا يعبر حدود RAND أبدًا: فمؤشر الأصل 0 محجوز لـ RAND ولا يمنحه سجل الرموز لأحد، ولذلك فإن BridgeAttest أو TokenMint أو السك الأولي لتسجيلٍ ما يودع دائمًا ملاحظة من أصل آخر، وإن burn_a في BridgeBurn أو TokenBurn يتلف دائمًا ملاحظة من هذا النوع (ويُرفض حرق RAND عبر burn_a). ويُحتسب fees_paid وburned من fee وburn_r في الحزمة وحدهما، وتحويل الرمز داخل المجمّع لا يحرّك أي عدّاد على الإطلاق، إذ إن أصله ليس علنيًا حتى. وعلى السلسلة 20 يستطيع Invoke أيضًا أن يُدخل رمزًا عبر burn_a: إلى خزينة البرنامج (deposit)، ولا يغيّر ذلك عرضه، أو يتلفه (burn)، لرمز البرنامج نفسه فقط. أما ملاحظات رسوم الجسر (السلسلة 20، 10 نقاط أساس من كل إيداع وحرق لـ zUSD، إلى عنوان خزينة) فهي zUSD وليست RAND أبدًا: مُصدَرة ومغطّاة، فيتحرك غطاء الإيداع والعرض بالمبلغ الإجمالي، ويتحرك الحرق بمقدار amount − fee نزولًا. وعرض الرمز نفسه هو العدّ العلني للسجل: تعيد rand_getTokenSupply القيمة total_supply وتعيد، للرمز المجسَّر، مبلغ locked لكل غطاء، ومجموعها يساوي العرض (رموز RPL).
متطابقة التدقيق
ستة عدّادات رتيبة بالوحدات (1 RAND = 10⁹)، واثنان يسجّلان ما أُتلف، واثنان على السلسلة 20 لخزائن البرامج:
| العدّاد | يجمع |
|---|---|
genesis_deposited | ملاحظات إيداع alloc في ملف التكوين الأول |
genesis_staked | الحصص التي زرع بها التكوين الأول السجل |
faucet_minted | كل Mint مقبول |
withdraw_deposited | الملاحظات التي أنشأتها عمليات Withdraw المقبولة (amount − 0.001 RAND لكل منها) |
fees_paid | كل رسم حزمة |
burned | كل burn_r في حزمة (حصة Bond، وعلى السلسلة 20 إيداع استدعاء في خزينة)، وكل رسم تسجيل محروق |
slashed | ضمانات المُجمِّعين المصادَرة (تجميع الكتل؛ 0 ما دام معطّلًا) |
registration_fees_burned | رسوم التسجيل المحروقة بموجب tokens.burn_registration_fee، وهي داخل burned أيضًا |
program_rand_out | ملاحظات RAND التي دفعتها خزائن البرامج (RPL-2؛ 0 دون قسم program_state) |
program_rand_held | الـ RAND الذي ما زالت الخزائن تحتفظ به: burn_r كل استدعاء ناقص program_rand_out. وقد وصل إلى هناك عبر burned، فهو جانب الخزائن من ذلك العدّاد |
pool_value = genesis_deposited + faucet_minted + withdraw_deposited + program_rand_out − fees_paid − burned
register_total = Σ over the register of (stake + pending + rewards)
total_supply = pool_value + register_total + program_rand_held
issued = genesis_deposited + genesis_staked + faucet_minted
invariant: total_supply == issued − slashed − registration_fees_burned
pool_value هو ما دخل ناقص ما خرج — وهو الرقم نفسه الذي يساوي مجموع الملاحظات، وهو ما لا يستطيع أحد حسابه. والرسم الأساسي للسحب البالغ 0.001 RAND ليس عبورًا: فهو ينتقل من صف في السجل إلى صف المقترِح، والملاحظة وحدها هي التي عبرت. وكون invariant_holds خاطئة يعني خللًا في الإجماع أو قاعدة بيانات تالفة، وليس حالة مشروعة أبدًا. والحدّان المتعلقان بالبرامج صفر في سلسلة بلا خزائن برامج، فتكون المتطابقة هناك هي متطابقة السلسلة 19. وقسم vesting في التكوين الأول، الذي لم تعرفه أي سلسلة، سيضيف سجلًا علنيًا ثالثًا بالطريقة نفسها (JSON-RPC).
وإليك تتبّع ربطٍ واحد وسحبٍ واحد بمقدار 1,000 RAND على سلسلة أودعت 2,000 ورهنت 4,000:
| بعد | burned | withdraw_deposited | fees_paid | pool_value | register_total | total_supply |
|---|---|---|---|---|---|---|
| التكوين الأول | 0 | 0 | 0 | 2,000 | 4,000 | 6,000 |
| ربط بمقدار 1,000 (الرسم 0.001) | 1,000 | 0 | 0.001 | 999.999 | 5,000.001 | 6,000 |
| فك ربطه | 1,000 | 0 | 0.001 | 999.999 | 5,000.001 | 6,000 |
| سحبه بمقدار 1,000 | 1,000 | 999.999 | 0.001 | 1,999.998 | 4,000.002 | 6,000 |
قراءتها
curl -s http://127.0.0.1:8545 -H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"rand_getSupply","params":[]}'
{ "height": 1998,
"genesis_deposited": "2000000000000", "genesis_staked": "4000000000000",
"faucet_minted": "0", "withdraw_deposited": "999999000000",
"fees_paid": "1000000", "burned": "1000000000000",
"slashed": "0", "registration_fees_burned": "0",
"pool_value": "1999998000000", "register_total": "4000002000000",
"total_supply": "6000000000000", "invariant_holds": true }
كل مبلغ سلسلة عشرية من الوحدات، لأن عددًا في JSON لا يكون عددًا صحيحًا دقيقًا بعد 2⁵³. ويحمل الكائن الكامل حقولًا أكثر مما يظهر هنا، منها زوج الصنبور لكل حقبة faucet_epoch وfaucet_minted_in_epoch، اللذان تتحقق منهما السلسلة 20 بالنسبة إلى ميزانيتها، وprogram_rand_out وprogram_rand_held (منذ v0.6.8)، وأربعة عدّادات vesting_* تقرأ "0" على السلسلة 20 التي ليس في تكوينها الأول قسم vesting (JSON-RPC). ويقدّم المستكشف الكائن نفسه عند GET /supply والأرقام الرئيسية عند GET /stats.
ما مدى دقتها
في كل ما فعلته السلسلة بنفسها تكون العدّادات دقيقة: فكل منها يُزاد في مسار الشيفرة الذي يطبّق الإجراء، انطلاقًا من الحقول العلنية للإجراء نفسه.
كان قيدان يقومان على ادّعاء، وتحوّلهما السلسلة 14 كليهما إلى فحوص (التدقيق v3، POOL-1):
- يحمل
Mintالصادر عن الـ faucet فتحَ الـ note. إلى جانبcmوamount، يَنشر الإجراءpkوtimeوr. ويعيد القبول حساب الالتزام الخاص بـ(pk, no sender, amount, asset 0, time, r)ويرفض أي عدم تطابق مع الرسالةthe mint's commitment does not open to its published note and amount، ويقيّدtimeبنافذة الحزمة. ويوقّع الـ minter الحقول السبعة جميعها ضمن النطاقrand-mint-2. وقبل ذلك، كان بإمكان الـ validator أن ينشر مبلغًا ويختم note بقيمة مبلغ آخر. والكلفة أن مالك الـ note الصادر عن الـ faucet، أيpk، يصبح علنيًا، كما هي الحال في مخرجات السحب؛ أما معاملاتrand_mintفلم تتغير. - يحمل note الـ
allocفي genesis فتحَه أيضًا. في سلسلة تتضمن قسمtokens، يكون كل صف على الشكل{ cm, envelope, amount, opening: { pk, time, r } }، وتعيد العقدة حساب الالتزام عند asset 0 ما لم يسمِّ الفتحُassetلرمز مدرج، وترفض ملف genesis الذي لا يطابقcmفيه الالتزام المحسوب. ولا تُحتسب فيgenesis_depositedسوى صفوف asset 0. فقد كانcmالمعتم الطريقة الوحيدة التي يستطيع بها مؤلف genesis إدخال note غير مغطّاة، من أي أصل، إلى المجمّع دون أن يتمكن أحد من التحقق منها. ولذلك فإن مالك note الـ genesis ومبلغها علنيان بحكم التصميم متى نُشر الملف؛ ويبقى خاصًا فقط وقتُ إنفاقها وما تُنفَق فيه لاحقًا. ويكتبrand-node genesisالفتحَ دائمًا.
أما في سلسلة أُنشئت دون قسم tokens، فما زالت القاعدة الأقدم سارية: genesis_deposited هو مجموع حقول amount المعلنة، ويؤخذ على الثقة من ملف genesis. وكلا مبلغَي genesis مضمّنان في hash الـ genesis، فتتفق جميع العقد عليهما في الحالتين.
العدّادات ليست حالة إجماع عن قصد — فجذر الحالة لا يُجزِّئها — ويعيد rand-node verify --mode quick حساب كل واحد منها بإعادة تشغيل السلسلة، ويبلغ عن أي عدم تطابق إذا خالفتها اللقطة المخزَّنة.