از این صفحه برای خواندن درست rand_getSupply و استدلال دربارهٔ انتشار استفاده کنید: RAND از کجا میآید، به کجا میرود، و کدام اتحاد عرضهٔ یک زنجیرهٔ شیلدشده را دقیق میکند، با اینکه هیچکس نمیتواند نوتهای آن را جمع بزند.
RAND از کجا میآید و به کجا میرود
یک زنجیرهٔ شیلدشده نمیتواند پول خودش را جمع بزند: مقدار هر نوت درون تعهد (commitment) آن قرار دارد. آنچه عمومی است، هر عبور از مرز استخر است. این عبورها پنج نوعاند، و در زنجیرهای با خزانههای برنامه (RPL-2، زنجیرهٔ 20) هفت نوع:
| جهت | عبور | زمان |
|---|---|---|
| ورود | یک نوت واریز در genesis (alloc در فایل genesis، که از زنجیرهٔ 14 باز شده است) | بلاک 0 |
| ورود | یک mint از faucet (Mint، تا 100 RAND، با امضای اعتبارسنج، و از زنجیرهٔ 14 حامل بازگشایی نوت) | زنجیرههای testnet با "faucet": true؛ در زنجیرهٔ 20 فقط برای 16 کیف پول در فهرست مجاز، با امضای یکی از 18 minter ثبتشده در genesis، حداکثر 10,000 RAND در هر دورهٔ 1,000 بلاکی |
| ورود | Withdraw یک اعتبارسنج، که stake آزادشده و پاداشها را به یک نوت پرداخت میکند | هر زمان |
| خروج | fee یک بسته (bundle)، به rewards پیشنهاددهندهٔ بلاک | هر بسته |
| خروج | burn_r یک بسته: یک Bond که stake را در stake عمومی یک اعتبارسنج میسوزاند | هر bond |
| خروج | burn_r یک Invoke: RAND واریزشده به خزانهٔ عمومی یک برنامه | زنجیرهٔ 20، از v0.6.8 |
| ورود | پرداخت از خزانه: RAND که یک Invoke از خزانهٔ یک برنامه به صورت نوت پرداخت میکند، با مقدار و گیرندهٔ عمومی | زنجیرهٔ 20، از v0.6.8 |
در زنجیرهای که genesis آن tokens.burn_registration_fee را تنظیم میکند، مانند زنجیرهٔ 20، registration_fee به مقدار 1 RAND برای ثبت یک توکن نیز از طریق burned از استخر خارج میشود، اما وارد هیچ ردیف ثبت (register) نمیشود: نابود میشود و پیشنهاددهنده فقط پایهٔ بسته را نگه میدارد.
در کنار استخر، ثبت اعتبارسنجها قرار دارد که مقادیر را آشکار نگه میدارد، زیرا وزن اجماع باید عمومی باشد. stake در این ثبت RAND واقعی است: میتوان آن را unbond کرد و دوباره به یک نوت withdraw کرد. در زنجیرهٔ 20، خزانههای برنامه یک موجودی عمومی دوم در کنار آن هستند: RANDای که یک invoke واریز میکند، تا زمانی که یک پرداخت آن را به صورت نوت به استخر برگرداند، همانجا قابل شمارش میماند.
در زنجیرهٔ 20 پاداش بلاک و تورمی وجود ندارد. نخستین انتشار برنامهریزیشدهٔ زنجیره، یارانهٔ تجمیع بلاک است — مقداری کاهنده از RAND تازه برای هر بلاک مهرشده، که به تجمیعکنندهای پرداخت میشود که اثبات او آن بلاک را پوشش میدهد — و در زنجیرهٔ 20 فعال نیست (Proofs). زنجیرهٔ 20 یک زنجیرهٔ تازه است، فعال از 2026-10-01 ساعت 06:17 UTC، که از زنجیرهٔ 19 جدا شده است (fullnode v0.6.8، یک hard fork). genesis آن 31,184.243719258 RAND منتشر کرد: 26,000 stakeشده در میان 26 اعتبارسنج genesis و 5,184.243719258 در هفت نوت واریز، یعنی موجودی هفت کیف پول اپراتور که از زنجیرهٔ 19 منتقل شد. آنچه کیف پولهای دیگر در زنجیرهٔ 19 نگه داشتند، حدود 519.9 RAND (mintهای faucet برای گیرندگان فهرست مجاز، پرداختها به کاربران)، منتقل نشد، زیرا یک نوت را بدون نشانی صاحبش نمیتوان دوباره ساخت؛ 0.499 RAND از پاداشهای برداشتنشدهٔ اعتبارسنجها نیز منتقل نشد. دو نوت genesis دیگر، در مجموع نه نوت، 99 zUSD پل را حمل میکنند (10 و 89)، که RAND نیست و بیرون از این حسابرسی است. rand_getSupply در زنجیرهٔ 20 مقدار genesis_deposited را 5,184,243,719,258 واحد و invariant_holds: true میخواند (ارتفاع 3,037، 2026-10-01). زنجیرهٔ 19، که همان روز از یک snapshot زنجیرهٔ 18 در ارتفاع 141,935 جدا شد، 31,294.644359629 RAND منتشر کرد: همان 26,000 stakeشده و 5,294.644359629 در هفت نوت، در کنار یک نوت 10 zUSD. هر mint از faucet از آن زمان به رقم منتشرشده میافزاید و هر هزینهٔ ثبت سوزاندهشده از آن میکاهد. زنجیرهٔ 15، جداشده در 2026-09-26، در genesis مقدار 23,000 RAND منتشر کرد، 18,000 stakeشده در میان 18 اعتبارسنج و 5,000 در پنج نوت؛ هشت اعتبارسنج بعدی آن از نوتهای موجود bond شدند، که چیزی منتشر نکرد.
توکنها بیرون از این حسابرسیاند
عبورهای بالا مربوط به RANDاند. یک توکن RPL، چه پلشده و چه بومی، هرگز از مرز RAND عبور نمیکند: اندیس دارایی 0 برای RAND رزرو شده است و ثبت توکنها هرگز آن را نمیدهد، بنابراین یک BridgeAttest، یک TokenMint یا mint اولیهٔ یک ثبت، همیشه نوتی از دارایی دیگری واریز میکند، و burn_a در یک BridgeBurn یا TokenBurn همیشه یکی را نابود میکند (RAND سوزاندهشده از طریق burn_a رد میشود). fees_paid و burned فقط از fee و burn_r یک بسته شمرده میشوند، و انتقال توکن درون استخر هیچ شمارندهای را تغییر نمیدهد، چون دارایی آن حتی عمومی نیست. در زنجیرهٔ 20 یک Invoke همچنین میتواند توکنی را از طریق burn_a وارد کند: به خزانهٔ برنامه (deposit)، که عرضهٔ آن را بدون تغییر میگذارد، یا نابودشده (burn)، فقط برای توکن خود برنامه. نوتهای کارمزد پل (زنجیرهٔ 20، 10 bps از هر واریز و سوزاندن zUSD، به نشانی خزانهداری) zUSD هستند، نه RAND: منتشرشده و پشتوانهدار، بهطوری که پشتوانهٔ یک واریز و عرضه به اندازهٔ مقدار ناخالص حرکت میکنند و در سوزاندن به اندازهٔ amount − fee کاهش مییابند. عرضهٔ خود یک توکن، شمارش عمومی ثبت است: rand_getTokenSupply مقدار total_supply را برمیگرداند و برای یک توکن پلشده، مقدار locked هر پشتوانه را، که مجموعشان با آن برابر است (RPL tokens).
اتحاد حسابرسی
شش شمارندهٔ یکنوا بر حسب واحد (1 RAND = 10⁹)، دو شمارنده که آنچه نابود شده را ثبت میکنند، و در زنجیرهٔ 20 دو شمارنده برای خزانههای برنامه:
| شمارنده | مجموع میزند |
|---|---|
genesis_deposited | نوتهای واریز alloc در فایل genesis |
genesis_staked | stakeهایی که genesis ثبت را با آنها آغاز کرد |
faucet_minted | هر Mint پذیرفتهشده |
withdraw_deposited | نوتهایی که Withdrawهای پذیرفتهشده ساختند (هرکدام amount − 0.001 RAND) |
fees_paid | هر کارمزد بسته |
burned | هر burn_r بسته (stake یک Bond، و در زنجیرهٔ 20 واریز خزانهٔ یک invoke)، و هر هزینهٔ ثبت سوزاندهشده |
slashed | bondهای تجمیعکنندهٔ slashشده (تجمیع بلاک؛ 0 تا زمانی که خاموش است) |
registration_fees_burned | هزینههای ثبتی که تحت tokens.burn_registration_fee سوزانده شدند، که درون burned نیز هستند |
program_rand_out | نوتهای RAND که خزانههای برنامه پرداخت کردهاند (RPL-2؛ 0 بدون بخش program_state) |
program_rand_held | RANDای که خزانهها هنوز نگه میدارند: burn_r هر invoke منهای 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 یک withdraw عبور نیست: از یک ردیف ثبت به ردیف پیشنهاددهنده منتقل میشود، و فقط نوت عبور کرد. اگر invariant_holds نادرست باشد، آن یک باگ اجماع یا پایگاه دادهٔ آسیبدیده است، هرگز یک حالت مشروع نیست. دو جملهٔ برنامه در زنجیرهای بدون خزانهٔ برنامه صفرند، پس اتحاد در آنجا همان اتحاد زنجیرهٔ 19 است. یک بخش vesting در genesis، که هیچ زنجیرهای نداشته است، به همین روش یک ثبت عمومی سوم میافزود (JSON-RPC).
دنبالشده از طریق یک bond و یک withdraw به مقدار 1,000 RAND در زنجیرهای که 2,000 واریز و 4,000 stake کرده است:
| پس از | burned | withdraw_deposited | fees_paid | pool_value | register_total | total_supply |
|---|---|---|---|---|---|---|
| genesis | 0 | 0 | 0 | 2,000 | 4,000 | 6,000 |
| یک bond به مقدار 1,000 (کارمزد 0.001) | 1,000 | 0 | 0.001 | 999.999 | 5,000.001 | 6,000 |
| unbond آن | 1,000 | 0 | 0.001 | 999.999 | 5,000.001 | 6,000 |
| withdraw آن به مقدار 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 یعنی faucet_epoch و faucet_minted_in_epoch، که زنجیرهٔ 20 آنها را با بودجهاش بررسی میکند، program_rand_out و program_rand_held (از v0.6.8)، و چهار شمارندهٔ vesting_* که در زنجیرهٔ 20 مقدار "0" میخوانند، چون genesis آن بخش vesting ندارد (JSON-RPC). explorer همین شیء را در GET /supply و ارقام اصلی را در GET /stats ارائه میدهد.
چقدر دقیق است
برای هر کاری که خود زنجیره انجام داد، شمارندهها دقیقاند: هر یک در مسیر کدی که آن عمل را اعمال میکند، از فیلدهای عمومی خود آن عمل، افزایش مییابد.
دو ورودی پیشتر بر یک ادعا تکیه داشتند، و زنجیرهٔ 14 هر دو را به بررسی تبدیل میکند (audit v3، POOL-1):
- یک
Mintفاست، بازشدگی note را حمل میکند. افزون برcmوamount، این اقدامpk،timeوrرا نیز منتشر میکند. فرایند پذیرش، تعهد (commitment) مربوط به(pk, no sender, amount, asset 0, time, r)را دوباره محاسبه میکند و هر ناهمخوانی را با پیامthe mint's commitment does not open to its published note and amountرد میکند، وtimeرا در بازهٔ زمانی bundle نگه میدارد. minter هر هفت فیلد را تحت دامنهٔrand-mint-2امضا میکند. پیش از این، یک validator میتوانست یک مقدار را منتشر کند و noteای با ارزش دیگر را مهروموم کند. هزینهٔ این کار آن است کهpkمالک note فاست عمومی است، همانگونه که پرداخت یک withdraw عمومی است؛ پارامترهایrand_mintبدون تغییر ماندهاند. - یک note از
allocدر genesis نیز بازشدگی خود را حمل میکند. در زنجیری که بخشtokensدارد، هر ردیف به شکل{ cm, envelope, amount, opening: { pk, time, r } }است، و گره تعهد را دوباره محاسبه میکند، در asset 0 مگر آنکه opening بهassetیک توکن فهرستشده اشاره کند، و فایل genesisای را کهcmآن مطابقت ندارد رد میکند. تنها ردیفهای asset 0 درgenesis_depositedشمرده میشوند. یکcmمبهم تنها راهی بود که نویسندهٔ genesis میتوانست noteای بدون پشتوانه، از هر دارایی، را وارد استخر کند بیآنکه کسی بتواند آن را بررسی کند. بنابراین مالک و مقدار یک note در genesis، پس از انتشار فایل، عمداً عمومی هستند؛ تنها اینکه چه زمانی و به چه چیزی خرج میشود خصوصی میماند.rand-node genesisهمیشه opening را مینویسد.
در زنجیری که بدون بخش tokens ساخته شده باشد، قاعدهٔ قدیمیتر همچنان برقرار است: genesis_deposited مجموع فیلدهای amount اعلامشده است که از فایل genesis بهعنوان قابل اعتماد پذیرفته میشود. هر دو مقدار genesis در هش genesis قرار دارند، بنابراین همهٔ گرهها در هر دو حالت بر سر آنها همنظرند.
شمارندهها عمداً بخشی از وضعیت اجماع نیستند — ریشهٔ وضعیت (state root) آنها را هش نمیکند — و rand-node verify --mode quick هر یک را با بازپخش زنجیر دوباره محاسبه میکند و در صورت ناهمخوانی با snapshot ذخیرهشده، آن را گزارش میدهد.