سرور JSON-RPC 2.0 را روی HTTP در --rpc ارائه میکند (پیشفرض 127.0.0.1:8545) و برای اشتراکها (subscriptions) یک WebSocket هم روی همان درگاه دارد. از نسخه v0.6.8 میتواند یک شنوندهٔ دوم و عمومی هم باز کند (--public-rpc، در ادامه). randprotocol_client::RpcClient (Rust) همهٔ متدهای زیر را در بر میگیرد. این صفحه فهرست متدها است، آنگونه که v0.6.8 (c9c9bd3c)، یعنی ساختی که chain 20 اجرا میکند، آنها را ارائه میدهد؛ هر جا متدی در کد وجود دارد اما روی chain 20 غیرفعال است، همین را میگوید.
curl -s http://127.0.0.1:8545 -H 'content-type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"rand_getHead","params":[]}'
نقطهٔ پایانی عمومی
https://rpc.randprotocol.org (همان پروکسی در https://randprotocol.org/api/rpc هم در دسترس است) درخواستها را به یک گره آرشیو chain-20 که همهٔ بلاکها را نگه میدارد میفرستد، برای کیفپولها و صفحاتی که گره اختصاصی ندارند (rand --rpc https://rpc.randprotocol.org …). فقط HTTP POST را میپذیرد، CORS آن باز است و WebSocket ندارد، و محدودتر از یک گره کامل است:
- در هر فراخوانی یک درخواست. یک batch با
-32600رد میشود. - فهرستی مجاز از متدها: از 2026-10-01 همان مجموعهای که شنوندهٔ عمومی خود گره ارائه میدهد (
rpc::PUBLIC_METHODSدر v0.6.8)؛ بنابراین خواندنهای وضعیت برنامه کهrand program invokeنیاز دارد،rand_getAdmitted، خواندنهای aggregation و خواندنهای vesting در آن هستند، همراه باrand_checkTransactionوrand_sendTransaction.rand_mint،rand_importViewingKey،rand_getViewingNotes،rand_removeViewingKeyوrand_getPeersدر آن نیستند و بیآنکه به گره برسند با-32601و پیامmethod not allowed hereپاسخ میدهند: faucet عمومی سطح سوءاستفاده است و viewing key را فقط باید به گرهٔ خودتان داد. - بدنهٔ درخواست حداکثر 12 MiB، که هر انتقال، عملیات توکن یا استقرار را در خود جا میدهد، و نیز فراخوانیای که اثبات آن تا حدود 3.4 MB باشد (تراکنش بهصورت hex کدگذاری میشود و اثباتهای bundle و auth آن پیش از اثبات فراخوانی حدود 2.85 MB میگیرند). فراخوانی بزرگتر باید به گرهٔ خودتان برود. بیش از سقف: HTTP 413 و
-32600. - بهازای هر نشانی، 1,200 درخواست در دقیقه و برای
rand_sendTransactionتعداد 6 در دقیقه. بیش از آن: HTTP 429 و-32005. سهمیهٔ خواندن برای همگامسازی اول یک کیفپول اندازهگیری شده است، که چند صد درخواست در یک انفجار است (645 درخواست در ارتفاع 99,000 در chain 18). -32000با پیامupstream unavailableوقتی گرهٔ پشت پروکسی پاسخ نمیدهد.
هر چیز دیگر در این صفحه دربارهٔ خود گره است.
دو شنوندهٔ گره
از v0.6.8 (audit v6) هر گره دو شنوندهٔ JSON-RPC دارد.
--rpc <ADDR>، شنوندهٔ اپراتور. همهٔ متدها، batchها و WebSocket. فراخواننده را با نشانی سوکتش شناسایی میکند و به loopback اعتماد دارد: متدهای viewing-key فقط به loopback پاسخ میدهند و loopback محدودیت نرخ ندارد. آن را روی127.0.0.1نگه دارید. یک reverse proxy یا یک SSH forward از طریق loopback میرسد، پس پشت آنها هر بازدیدکننده خودِ اپراتور محسوب میشود: هرگز یک نقطهٔ پایانی عمومی را به این درگاه وصل نکنید.--public-rpc <ADDR>، شنوندهٔ عمومی، دقیقاً برای همین حلقهٔ میانی. مجموعهای ثابت از متدها را ارائه میدهد: خواندنهایی که کیفپول، explorer یا یک صفحه نیاز دارد، بهعلاوهٔrand_sendTransaction(rpc::PUBLIC_METHODS).rand_importViewingKey،rand_getViewingNotes،rand_removeViewingKey،rand_mintوrand_getPeersهرگز در آن ارائه نمیشوند، و هر متدی هم که بعداً اضافه شود تا در فهرست نیاید ارائه نمیشود؛ چنین فراخوانی با-32000و پیام<method> is not served on this node's public listenerپاسخ میگیرد. batch برابر-32600است و مسیر WebSocket ندارد. یک شمارندهٔ واحد همهٔ فراخوانندهها را با هم پوشش میدهد، 600 درخواست در یک انفجار و 150 درخواست در ثانیه؛ بیش از آن، HTTP 429 با بدنهٔ-32000. محدودیت بهازای هر بازدیدکننده بر عهدهٔ پروکسی است، که بازدیدکنندهها را میبیند. فراخوانندههای آن حداکثر نیمی از اسلاتهای خواندنِ مسدودکنندهٔ گره را در اختیار دارند، تا شنوندهٔ اپراتور هرگز گرسنه نماند.
هر دو شنونده دو محدودیت خواندن را به اشتراک میگذارند. خواندنی مسدودکننده که ظرف 30 s برنگردد با -32000 و پیام this read took longer than 30 s on this node; retry with a smaller range پاسخ میگیرد. rand_getBlocks صفحهٔ خود را وقتی به 64 MiB بلاک رسید تمام میکند.
--rpc-viewing-token-file <PATH> یک bearer token روی متدهای viewing-key در --rpc میگذارد: خط اول فایل، دستکم 32 نویسه، که بهصورت Authorization: Bearer <token> فرستاده میشود. با آن، loopback بهتنهایی کافی نیست و هر فراخوانندهای در هر جا که آن را ارائه کند پاسخ میگیرد.
قراردادها
- نشانیهای validator رشتههای base58 هستند (32 بایت). هشها 64 نویسهٔ hex هستند، با
0xیا بدون آن. مقادیر محافظتشده (shielded) — commitmentها، nullifierها، anchorها، ریشههای درخت، سطوح witness — از نوعWord8هستند: هشت واژهٔu32بهصورت little-endian، در قالب 64 نویسهٔ hex با حروف کوچک. - نشانیهای محافظتشده
rand1+ base58 هستند، به طول 1,667 نویسه. پارامتری بلندتر از 2,000 نویسه پیش از تجزیه، بهدلیل طولش رد میشود. - هر مقدار
u64یک رشتهٔ دهدهی است ("1500000000"= 1.5 RAND؛ 1 RAND = 10⁹ واحد): واحدهای RAND یا واحدهای توکن، وضعیت زنجیره یا فیلد خودِ یک تراکنش رمزگشاییشده. عدد JSON پس از 2⁵³ عدد صحیح دقیق نیست، و عرضهٔ یک توکن 9 رقم اعشاری در چند ده میلیون واحد از آن میگذرد. برای آنچه این تغییر عوض کرد، یادداشت تاریخدار زیر را ببینید. - شاخصها، nonceها، ارتفاعها، شاخصهای برگ، viewها، طولها، تعداد ارقام اعشار و شمارندهٔ روز (
mint_day) هرگز مقدار مالی نیستند و همهجا عدد صحیح JSON هستند. - هر درخواست باید عضو
idداشته باشد. شیئی بدون آن یک notification است و با-32600رد میشود؛"id": nullصریح یک درخواست عادی است. - هیچ متد موجودی و هیچ متد حسابی وجود ندارد. کیفپول موجودی خود را با اسکن
rand_getCommitmentsوrand_getNullifiersبا viewing key خود محاسبه میکند.rand_getBalance،rand_getAccountوrand_getAssetBalanceبا-32601پاسخ میدهند.
تغییر ناسازگار، 2026-09-20 (chain 14): هر مقدار مالی یک رشتهٔ دهدهی است
پیش از chain 14، مقادیر مالی داخل یک تراکنش رمزگشاییشده عدد صحیح JSON بودند. آن استثنا حذف شده است. این فیلدها از عدد JSON به رشتهٔ دهدهی تغییر کردند، بیآنکه معنا یا جایگاهشان عوض شود:
bundle.fee، درtxمتدrand_getTransactionو درtransactions[]متدهایrand_getBlockByHeight/rand_getBlockByHash؛action.amountبرایkind=mint،bond،unbond،withdraw،bridge_attest(در همان سه متد)؛action.amountوaction.relayer_feeبرایkind=bridge_burn(در همان سه متد)؛lockedدر ردیفهایrand_getAssetsوrand_getBridgeState.assets[].
کلاینتی که هر یک از اینها را بهصورت عدد میخواند باید بهجای آن رشته را تجزیه کند. aggregation.subsidy_base در rand_status (فقط زنجیرههای دارای aggregation) در همین تغییر رشته شد. هر مقدار مالی دیگر از پیش رشته بود: rand_getSupply، rand_getEmission، rand_getValidators، noteهای viewing، و هر فیلدی که با chain 14 معرفی شد — burn_a و burn_r در bundle، عرضههای توکن، locked هر پشتوانه، mint_cap_per_day و minted_today، registration_fee، و amount در token_mint، token_burn و register_token (initial_amount، initial.amount).
Batchها
بدنهٔ POST میتواند آرایهای از حداکثر 20 شیء درخواست باشد، که با آرایهای همطول و به ترتیب درخواستها پاسخ داده میشود، خطاها هم همینطور. درخواستها یکی پس از دیگری اجرا میشوند. آرایهٔ خالی، آرایهٔ بیش از 20 عضو، یا بدنهای که نه شیء است و نه آرایه، یک -32600 واحد با id تهی است. کل بدنه همچنان با محدودیت اندازهٔ بدنهٔ درخواست گره محدود میشود، که برای یک تراکنش همراه با اثبات تعیین شده است: batch حاوی دو فراخوانی rand_sendTransaction همراه با اثبات با 413 رد میشود. در batch خواندن بفرستید، نه ارسالهای اثباتدار.
زنجیره و گره
rand_chainId
پارامترها []. نتیجه: شناسهٔ زنجیره (عدد صحیح)؛ روی testnet برابر 20.
rand_tokenInfo
پارامترها []. نتیجه { "symbol": "RAND", "decimals": 9 }.
rand_getHead
پارامترها []. نتیجه { "height": 1998, "hash": "…", "view": 2251 }. view همان view جاری اجماع گره است، که وقتی viewها زمانشان تمام میشود از ارتفاع جلوتر میرود.
rand_status (نام مستعار rand_syncStatus)
پارامترها []. نتیجه:
{
"height": 1998, "head_hash": "…", "view": 2251, "high_qc_view": 2250,
"syncing": false, "sync_target": 1998,
"sync_inflight_age_ms": null, "sync_failures": 0, "sync_late_batches": 0,
"peer_count": 26, "connected_peers": 26, "reserved_peers": 25, "ws_clients": 0, "refused_cache": 0,
"verify_queue": 0, "mempool_size": 0,
"is_validator": true, "active_validator": true, "faucet": true, "confidential": true,
"testnet": true, "fri_profile": "production", "programs": 10, "viewing_keys": 0,
"notes": 197, "nullifiers": 160, "tree_root": "72b9…1197", "hc_bundle": "60af…3fce", "hc_auth": "1e4e…39c1",
"binding_domain": 1,
"address": "5TAofR…", "peer_id": "12D3KooW…",
"gas_prices": { "gas_price": "100", "byte_price": "800" }
}
is_validator: این گره کلید validator دارد؛ active_validator: آن کلید در مجموعهای است که دورهٔ (epoch) جاری را اجرا میکند. reserved_peers (v0.6.8) تعداد همتایانی را میشمارد که فراتر از سقف اتصال ورودی پذیرفته شدهاند: bootstrapها، هر --reserved-peer، و هر هویت validator که از یک binding امضاشدهٔ همتا آموخته شده، هر کدام یک بار؛ روی گرهٔ یک fleet باید ظرف یک دقیقه از شروع به تعداد validatorها برسد. viewing_keys تعداد viewing keyهایی است که گره برای اسکن سمت گره در حافظه نگه میدارد. verify_queue تعداد تراکنشهایی است که منتظر یکی از چهار worker تأیید اثبات هستند (حداکثر 64 در صف). hc_bundle همان bundle guest است که اثباتهای این زنجیره در برابر آن هستند و hc_auth همان auth guest که genesis آن را پین میکند (احراز مجوز تفکیکشده، از chain 17)، یا null در زنجیرهای که آن را ندارد؛ گرهای که ساختش با هر یک ناهمخوان باشد از شروع به کار امتناع میکند. testnet و binding_domain فیلدهای genesis با همین نامها هستند، همانطور که rand_getLimits ارائه میدهد. gas_prices قیمتهای gas جاری دفتر tip است، که در هر commit بهروز میشود، بهصورت رشتههای دهدهی؛ در زنجیرهای بدون بخش gas برابر null است. قیمتهای chain 20 پویا هستند و در هر بلاک بر اساس پر بودن جابهجا میشوند، هرگز زیر کفهای 100 و 800 و هرگز بالای سقفهای 10,000 و 80,000، پس آنها را از همینجا یا از rand_getLimits بخوانید و ثابت در کد ننویسید. این شیء یک شیء aggregation هم دارد (subsidy_base آن رشتهٔ دهدهی و بقیه عدد صحیح)، که در زنجیرهای بدون بخش aggregation همهصفر است، همانطور که chain 20 است.
این شیء همچنین disk_free_bytes (یک عدد) و disk_low را دارد، و جفت نگهداری: prune_floor، پایینترین ارتفاعی که این گره هنوز نگه میدارد (روی آرشیو 0)، و prune_history_secs، بازهای که گرهٔ شروعشده با --prune-history نگه میدارد (null وقتی همهچیز را نگه میدارد). روی chain 20، مانند chain 19، 24 تا از 26 validator بلاکهای 24 ساعت را نگه میدارند؛ دو آرشیو همهٔ آنها را. گرههای هرسشده را ببینید.
rand_getPeers
پارامترها []. نتیجه: آرایهای از { "peer_id": "12D3KooW…", "addrs": ["/ip4/…/tcp/30303"], "connected_secs": 1241 }.
rand_getBlockByHeight / rand_getBlockByHash
پارامترها [height] یا [hash]. نتیجه null اگر ناشناخته باشد، وگرنه:
{
"hash": "647b…", "height": 50, "view": 92, "parent": "2d41…",
"proposer": "3v3VBJ…", "timestamp_ms": 1788000123456,
"tx_root": "0000…", "state_root": "a1b2…", "justify_view": 91,
"tx_count": 0, "transactions": [ ]
}
فقط بلوکهای commitشده ارائه میشوند. transactions همان ساختار tx در rand_getTransaction را دارد. هر بلوک یک فیلد sealed هم دارد و هر تراکنش آن یک sealed_by؛ در زنجیرهای بدون aggregation این دو بهترتیب false و null هستند.
rand_getBlocks
پارامترها [from_height, to_height]. نتیجه: سرایندهای بلوک، از قدیمیترین، حداکثر 1,024 بلوک از from_height (128 در گرهای قبل از 2026-09-24): همان فیلدهای rand_getBlockByHeight بدون transactions. بازهای که از سقف پهنتر باشد یا از head فراتر برود کوتاه میشود و رد نمیشود. از v0.6.8 به بعد، صفحهای هم که 64 MiB از بلوکها را خوانده باشد پایان مییابد؛ از آخرین ارتفاع بازگرداندهشده ادامه دهید. اگر to_height کمتر از from_height باشد، خطای -32602 برمیگردد.
از v0.6.8 هر سرایند یک public_notes هم دارد: تراکنشهای bridge_attest، token_mint و register_token بلوک، و در زنجیرهای با کارمزد bridge، تراکنشهای bridge_burn آن، به شکل [{ "hash", "raw" }] (همان رمزنگاریای که rand_getRawTransaction ارائه میکند)؛ برای هر بلوک دیگر خالی است. burn با proofهای تهیشده و "proofs_stripped": true ارائه میشود؛ hash آن شناسه واقعی تراکنش است. همگامسازی اول یک کیف پول این صفحهها را میخواند و برای بازسازی نوتهای عمومی به چیز دیگری نیاز ندارد.
rand_getFinality
پارامترها [height] یا [hash]. نتیجه، یکی از { "status": "committed", "height", "hash" }، { "status": "certified", "height", "hash", "qc_view" }، { "status": "proposed", "height", "hash" }، { "status": "unknown" }. ارتفاع همیشه فقط با زنجیره commitشده مقایسه میشود، پس پاسخش committed یا unknown است؛ hash میتواند certified هم باشد (در درخت commitنشده replica همراه با quorum certificate) یا proposed (در درخت بدون آن).
rand_getProposer
پارامترها [view] یا [from_view, to_view]، حداکثر 64 view. نتیجه { "epoch": 3, "proposers": [ { "view": 2251, "proposer": "2nRdFC…" } ] }: رهبر هر view بر پایه مجموعه validator فعلی، نه مجموعهای که در آن view در گذشته اجرا میشد. برای بازه معکوس یا بیش از 64 view، خطای -32602 برمیگردد.
rand_getVersion
پارامترها []. نتیجه { "version", "git_sha", "chain_id", "hc_bundle", "hc_auth", "fri_profile" }. version نسخه crate در workspace است؛ git_sha هش commit که هنگام build ثبت شده و اگر فایلهای ردیابیشده تفاوت داشتند -dirty به انتهای آن اضافه میشود، یا "unknown". hc_auth همان auth guest در genesis است، مانند rand_status، یا null. نقطه پایانی عمومی در 2026-10-01، روی chain 20:
{ "version": "0.6.8", "git_sha": "c9c9bd3c1903aa4cc5833b7ab8c62fc3e6942017", "chain_id": 20,
"hc_bundle": "60af094acfe65d85fdb18fb3d06cf9085dcf28c96e59e87f1ee527226e6e3fce",
"hc_auth": "1e4e347f44cf86750b30a9a4bdf9ec9256efe353d4ff8017451eca7d195639c1",
"fri_profile": "production" }
rand_getGenesisHash
پارامترها []. نتیجه: هش genesis بهصورت hex؛ روی chain 20 مقدار "6210cf071a390d7ac61d8cbea5dd9d139d1a493a862b54a45a498f36af2d5135" (مقدار chain 19 برابر a3defc93…228a بود). شناسه زنجیره بهتنهایی دو برش زنجیره را از هم تفکیک نمیکند؛ این مقدار تفکیک میکند. روی chain 20 این هش در binding هر تراکنش و هر پیام action امضاشده هم هست (binding_domain: 1، ببینید rand_getLimits).
rand_getHealth
پارامترها []. نتیجه، یکی از { "status": "disk_low", "free_bytes": "3221225472" }، { "status": "ok" }، { "status": "syncing", "behind": 412 }، { "status": "behind", "behind": 30 }. disk_low بر بقیه مقدم است، وقتی فضای آزاد در filesystem دایرکتوری داده کمتر از چهار برابر --min-free-disk-mb گره باشد (پیشفرض 1024، یعنی کمتر از 4 GB)؛ free_bytes یک رشته دهدهی است. ok وقتی است که sync_target - height حداکثر 2 باشد و هیچ درخواست batch همگامسازی در جریان نباشد؛ syncing تا زمانی که یکی در جریان است؛ behind وقتی که گره در حال همگامسازی نیست و عقبماندگی هنوز بیش از 2 است.
rand_getMempoolInfo
پارامترها []. نتیجه { "count": 2, "bytes": 2611200, "oldest_ms": 1450, "max_count": 10000 }. bytes مجموع طول رمزنگاریشده هر تراکنش در pool است؛ oldest_ms وقتی pool خالی باشد null است. از v0.6.8 حجم pool بر حسب بایت هم سقف دارد، برابر هشت برابر max_block_bytes در genesis (160 MiB روی chain 20): پس از رسیدن به آن، تراکنشی که بهازای هر KiB بیشتر از کف خود میپردازد ارزانترین تراکنش را جابهجا میکند، و تراکنشی که کمتر یا برابر بپردازد با mempool full رد میشود. actionهای governance از هر دو سقف عبور میکنند.
ارسال
rand_sendTransaction
پارامترها [hex]، که hex همان bincode(Transaction) است. نتیجه: هش تراکنش. گره تراکنش را به ترتیب پذیرش (تراکنشها) اعتبارسنجی میکند، آن را در pool میگذارد و gossip میکند. خطاها -32000 همراه با دلیل هستند: nullifier already spent، anchor is not one of the last 1024 roots، time 12 is outside [1500, 2524] (هر دو پنجره برابر proof_window_blocks در genesis هستند، 1,024 روی chain 20؛ 256 روی زنجیرهها تا 19)، fee 1000000 below minimum 2000000، the bundle's digest is not what its proof published، invalid bundle proof: …، unknown program …، already in mempool، conflicts with a pending transaction over <nullifier>، faucet is disabled on this chain؛ برای invoke، cell <key> is no longer what this transition read (یک حکم وضعیتی: سلول را دوباره بخوانید و دوباره prove کنید) یا the vault holds … of asset … and the transition pays …؛ برای Bond ثبتکننده تحت پذیرش با رأی، validator … has not been admitted by the validator set's vote (staking.admission_by_vote); ask the validators for an AdmitValidator first؛ برای bundleای که با genesis زنجیره 20 سازگار نیست، envelope is 1348 bytes, this chain requires exactly 1860، this chain requires an auth proof on every bundle (genesis hc_auth)، the auth proof publishes a different commitment than the bundle's auth_commit، auth proof: …، bundle proof declares gas limit …, this chain requires exactly 20479، non-canonical proof: … — re-prove with an up-to-date wallet؛ برای actionهای bridge، bridge: attestation already consumed، the attestation names a different recipient، the attestation deposits under asset 2, and the transaction names 1، the bundle burns 399, not the 400 the action declares؛ برای bundleای که burnای حمل میکند که action آن مجاز نیست، the bundle burns asset 2 on an action that burns no token، a burn of 5 is not allowed on this action یا RAND burned through burn_a (5); a RAND burn goes through burn_r؛ برای وضعیت bridge، bridge minting is paused، mint cap … per backing per day، already paused، not paused، wrong pause nonce، wrong list nonce، chain N has no registered emitter؛ و برای رجیستری توکن، wrong mint nonce و wrong token index. پذیرفتهشدن به معنای commit شدن نیست: rand_getTransaction یا rand_getTransactionStatus را poll کنید.
تراکنشی که از سقف بلوک زنجیره (max_block_bytes از rand_getLimits) بزرگتر باشد، پیش از رسیدن به mempool با -32000 و ذکر هر دو اندازه رد میشود. بدنه درخواست سقف 2 × (2 × max_proof_bytes + 4 × 2048 + max_call_envelope_bytes + 16,384 + 64 KiB) + 256 KiB دارد که هنگام راهاندازی از genesis محاسبه میشود: 8,867,840 بایت روی یک زنجیره پیشفرض و 17,350,656 در حدهای chain 20، همان مقدار زنجیرههای 17 تا 19 (34,127,872 روی زنجیرههای 13 تا 15 که سقف proof آنها 8 MiB بود). 4 × 2048 چهار envelope یک bundle در سقف envelope است. بدنهای بیش از آن -32600 میگیرد و حد در پیام ذکر میشود.
فقط -32000 (پذیرش آن را رد کرد) و -32602 (رمزگشایی نشد) حکمی درباره تراکنشاند. هر شکست دیگر، از جمله -32603، سرنوشت تراکنش را نامعلوم میگذارد: گره پیش از پاسخ، تراکنش را در pool میگذارد و gossip میکند، پس گرهای که در همان فاصله متوقف شود ممکن است چیزی را پذیرفته باشد که هرگز پاسخش را نداده است. randprotocol_client ارسال را فقط با همین دو کد ردشده میداند.
rand_getTransactionStatus
پارامترها [[hash, …]]، از 1 تا 64 هش. نتیجه: یک مورد برای هر هش، به همان ترتیب:
[ { "hash": "…", "status": "committed", "height": 1998, "index": 0 },
{ "hash": "…", "status": "pending" },
{ "hash": "…", "status": "rejected", "reason": "bad mint signature" },
{ "hash": "…", "status": "unknown" } ]
ترتیب جستجو برای هر هش: committed (storage)، pending (mempool)، rejected (cache ردشدهها که refused_cache در rand_status آن را میشمارد)، وگرنه unknown. rejected فقط ردهایی را شامل میشود که به بایتهای خود تراکنش مربوطاند و هیچ بلوک بعدی نمیتواند آنها را تغییر دهد: proof نامعتبر، digest بستهای که همان چیزی نیست که proof منتشر کرده، امضای mint نادرست، شناسه زنجیره اشتباه، بخش بیشازحد بزرگ، nullifier یا commitment تکراری درون تراکنش، envelope با اندازه نادرست، auth proof غایب یا ناسازگار، و bundle یا auth proof که gas limit نادرست اعلام کرده است. ردی که به وضعیت گره در آن لحظه بستگی دارد — nullifier خرجشده، anchor یا time خارج از پنجره، کارمزد کمتر از کف (که روی chain 20 با قیمتهای gas جابهجا میشود)، برنامه ناشناخته، nonce ثبت، خواندن کهنه invoke — به خاطر سپرده نمیشود و unknown خوانده میشود. برای فهرست خالی یا بیش از 64 هش، -32602 برمیگردد.
rand_mint (faucet در testnet)
پارامترها [address] یا [address, amount]؛ address یک آدرس rand1… و amount رشتهای از واحدها حداکثر 100000000000 (100 RAND، پیشفرض). نتیجه: هش تراکنش mint. فقط روی زنجیرهای که genesis آن "faucet": true دارد؛ در غیر این صورت -32000 با faucet is disabled on this chain. یک observer پاسخ میدهد faucet mints are signed by validators; ask a validator node.
روی زنجیرهای که genesis آن staking.faucet_recipients را تعیین میکند، مانند chain 20 (16 کیف پول)، فقط به کیف پولهای فهرستشده میتوان پرداخت کرد: mint به هر آدرس دیگر با the faucet may not mint to this recipient (not in staking.faucet_recipients) رد میشود. genesis زنجیره 20 همچنین staking.faucet_minters را تعیین میکند (18 کلید validator): فقط کلید فهرستشده میتواند mint را امضا کند. faucet بودجهای برای هر epoch هم دارد، staking.faucet_budget_per_epoch (10,000 RAND در هر epoch با 1,000 بلوک روی chain 20)؛ mint فراتر از آن با FaucetBudgetExhausted رد میشود، حکمی وضعیتی که پس از خروج از pool unknown خوانده میشود.
نرخ دسترسی faucet بهازای هر پردازهٔ نود محدود شده است: هشت mint پشتسرهم، با بازپرشدن یک mint در هر ثانیه. فراتر از آن، فراخوانی با این پیام پاسخ میدهد: faucet is rate limited on this node (8 mints back to back, refilling at 1/s); try again shortly. بنابراین سیل درخواستهای faucet نمیتواند استخر را پیش از PauseMints پل پر کند. این اقدام، مانند سه اقدام دیگر حاکمیت پل، از رد شدن با mempool full در استخر نیز معاف است و در بلوک اول ترتیب میگیرد.
از chain 14 به بعد، mint گشوده است: اقدام Mint افزون بر cm و amount، مقادیر pk، time و r یادداشت را نیز حمل میکند، پذیرش تعهد را دوباره محاسبه میکند و cmی را که به آنها باز نشود رد میکند (the mint's commitment does not open to its published note and amount)، و minter هر هفت فیلد را زیر دامنهٔ rand-mint-2 امضا میکند؛ در chain 20 (با binding_domain: 1) زیر rand-mint-3 و با hash ژنسیس در ابتدا. از این رو مالک و مقدار یادداشت faucet عمومی است، همانطور که پرداخت یک withdraw عمومی است. پارامترهای rand_mint تغییری نکردهاند.
rand_estimateFee
پارامترها [spec]، یکی از {"kind":"bundle"}، {"kind":"deploy","words":n,"public_words":m}، {"kind":"call","tier":t,"bytes":b,"gas":g} که t در 10، 12، 14، 16، 18، 20 است. نتیجه: حداقل کارمزد برحسب واحد، بهصورت رشته. {"kind":"bundle"} برابر "1000000" است. public_words (اختیاری، پیشفرض 0) مانند کد بهازای هر کلمه پرداخت میشود، پس کارمزد برابر کارمزد deploy برای n + m کلمه است. bytes (اختیاری، پیشفرض 0) مجموع طول اثبات فراخوانی و طول پاکت ورودی آن است.
قیمتگذاری یک فراخوانی به gas_metering در rand_getLimits بستگی دارد:
"circuit"، زنجیرهای با بخشgasمخصوص خود، مانند chain 20.gasسقف گازی است که اثبات فراخوانی اعلام میکند و الزامی است: بدون آن، فراخوانی با-32602و پیامunder the gas section a call estimate needs its gasپاسخ میدهد. پاسخ برابر است با1,000,000 + gas_price × gas + byte_price × ⌈bytes / 1024⌉به قیمتهای کنونی سر زنجیره، همانهایی کهrand_getLimitsارائه میکند. با قیمتهای کف chain 20 یعنی 100 و 800، فراخوانیای که 20,479 گاز اعلام میکند و اثبات و پاکتش جمعاً 1,300,000 بایت است، برابر"4063900"میشود. قیمتها در هر بلوک تغییر میکنند، پس برآورد را نزدیک به زمان ارسال بگیرید."header"، سیاست گاز در سطح نود برای زنجیرهای بدون این بخش. مشخصهٔ فراخوانیkeccak_log_heightوsha256_log_heightرا میپذیرد (اختیاری، پیشفرض 0، هرکدام در بازهٔ 0 تا 40، وگرنه-32602)، یعنی ارتفاع جدولهای hash که سرایند اثبات اعلام میکند، و پاسخ برابر است با بزرگتر از دو مقدار: کف ردهٔ دفتر کل و کف گاز آن سرایند. زیر بخشgasاین دو ارتفاع پذیرفته میشوند اما استفاده نمیشوند.null، هیچکدام. فقط جدول ردهٔ دفتر کل: تا سقف سهمیهٔ رایگان (2,097,152 + 18,432 بایت) فراخوانی کارمزد ردهٔ خود را میپردازد؛ بهازای هر KiB بیش از آن، که KiB ناقص کامل شمرده میشود، 1,000 واحد اضافه میشود.
از v0.6.8، {"kind":"invoke", …, "created_cells": c} یک invoke از نوع RPL-2 را قیمتگذاری میکند: همهٔ فیلدهای مشخصهٔ فراخوانی، بهعلاوهٔ created_cells (اختیاری، پیشفرض 0، حداکثر max_writes، وگرنه -32602)، یعنی سلولهایی که گذار ایجاد میکند. هر سلول cell_fee زنجیره را اضافه میکند (rand_getLimits.program_state). شمارش با فراخوان است: نوشتن مقداری ناصفر در سلولی که rand_getProgramCell آن را صفر میخواند. در chain 20، همان فراخوانی بالا با دو سلول ایجادشده برابر "24063900" است. در زنجیرهای بدون بخش program_state، این kind خطای -32602 میدهد.
کارمزدها جدول کامل را دارد.
استخر
rand_getTreeInfo
پارامترها []. نتیجه { "next_index": 41, "root": "6b1d…c4", "nullifiers": 12 }: تعداد برگها، ریشهٔ کنونی، و تعداد یادداشتهای خرجشده.
rand_getCommitments
پارامترها [from_index] یا [from_index, limit]. نتیجه: صفحهای از برگها از from_index به بعد، قدیمیترین نخست، حداکثر 1,000 سطر، هرقدر هم limit بزرگ باشد.
[ { "index": 40, "cm": "2a9f…07", "height": 37,
"envelope": { "kem_ct": "b41c…", "to_receiver": "77e0…", "to_sender": "0c31…", "body": "9dd2…" } } ]
rand_getNullifiers
پارامترها [from_height] یا [from_height, limit]. نتیجه: هر nullifier که از آن ارتفاع به بعد منتشر شده است، با همان سقف 1,000 سطر. ممکن است صفحه در میانهٔ یک ارتفاع تمام شود؛ برای صفحهبندی به بالاترین ارتفاعِ دیدهشده برگردید.
[ { "height": 37, "nullifier": "8c04…d1" }, { "height": 41, "nullifier": "12be…9a" } ]
rand_getCompactBlocks
پارامترها [from_height, to_height]، هر دو الزامی. نتیجه: یک سطر برای هر بلوک، قدیمیترین نخست، با آنچه یک کیف پول سبک نیاز دارد و نه بیشتر:
[ { "height": 192, "hash": "63f6…08", "timestamp_ms": 1788000123456,
"commitments": [],
"transactions": [
{ "hash": "4f2c…e7",
"commitments": [ { "index": 40, "cm": "2a9f…07", "envelope": { "kem_ct": "…", "to_receiver": "…", "to_sender": "…", "body": "…" } } ],
"nullifiers": ["8c04…d1", "5e77…20", "03aa…6f", "e19b…42"] } ] } ]
هر تراکنشِ حامل بسته در اینجا مالک چهار یادداشت و چهار nullifier است، یعنی چهار جایگاهش، از جمله جایگاههای ساختگی که هیچ خوانندهای آنها را از واقعیها تشخیص نمیدهد (فقط نخستین سطر تعهد در مثال نشان داده شده است). از v0.6.8 برخی بعد از آن چهار یادداشت، یادداشتهای بیشتری دارند: یک invoke بهازای هر پرداخت یک یادداشت دارد، ابتدا pays و سپس mints، هرکدام با پاکت مخصوص همان پرداخت، پس دریافتکننده آن را با رمزگشایی آزمایشی پیدا میکند؛ در زنجیرهای با کارمزد پل، مانند chain 20، یک bridge_burn یادداشت کارمزد خزانهٔ خود را دارد و یک bridge_attest یادداشت کارمزدش را پس از واریزش. پاکت یادداشت کارمزد تهی است و برای هیچکس مهر و موم نشده است: کیف پول خزانه یادداشت را از فیلدهای عمومی تراکنش بازسازی میکند.
حداکثر 128 بلوک در هر فراخوانی (بازهٔ پهنتر کوتاه میشود) و، پس از بلوک نخست که همیشه کامل ارائه میشود، 1,000 یادداشت؛ از آخرین height برگرداندهشده بهعلاوهٔ یک ادامه دهید. آرایهٔ commitments در سطح بلوک، واریزهای ژنسیس را در ارتفاع 0 نگه میدارد و در جاهای دیگر تهی است؛ یادداشتهای مشتقشدهٔ Withdraw و BridgeAttest زیر تراکنش خودشان میآیند. برای بازهٔ معکوس یا کران گمشده -32602.
rand_getAnchor
پارامترها [] برای سر زنجیره، یا [height]. نتیجه { "height": 192, "root": "6b1d…c4" }، یا -32001 برای ارتفاعی که لنگر ثبتشده ندارد. فقط ریشههای پایان بلوک لنگر هستند. نود ممکن است برای ارتفاعی قدیمی پاسخ دهد، اما لنگر یک بسته فقط وقتی پذیرفتنی است که یکی از آخرین proof_window_blocks ریشه باشد: 1,024 در chain 20 و 256 در زنجیرهها تا 19. بر پایهٔ سر زنجیره بسازید.
rand_getWitness
پارامترها [index]. نتیجه null برای نقطهای فراتر از انتهای درخت، وگرنه مسیر Merkle آن برگ، با برگ در ابتدا، دقیقاً 32 سطح، همراه با ریشهٔ کنونی درخت:
{ "index": 40, "root": "6b1d…c4", "path": ["0000…00", "f2a1…3b", "…"] }
پرهزینهترین خواندنی که نود ارائه میکند (کل درخت با عمق 32 را بازسازی میکند) و تنها درخواستی که چیزی دربارهٔ فراخوان افشا میکند. هر نود حداکثر همزمان دو بازسازی درخت اجرا میکند، rand_getWitness و rand_getWitnesses روی هم؛ درخواستی که بیش از 10 s برای یک جایگاه منتظر بماند با -32000 و پیام witness builds are busy on this node; retry shortly رد میشود.
rand_getWitnesses
پارامترها [[index, …]]، از 1 تا 32 اندیس برگ. نتیجه { "root": "…", "witnesses": [ { "index": 7, "path": ["…"] }, { "index": 9, "path": null } ] }: همان rand_getWitness که روی چند برگ در یک بار ساخت درخت اعمال شده است، تا کیف پولی که چند یادداشت را اثبات میکند هزینهٔ بازسازی را یک بار بپردازد. اندیسی فراتر از انتهای درخت برای آن ورودی path: null میدهد. برای فهرست تهی یا بیش از 32 اندیس -32602.
کلیدهای مشاهده و افشا
rand_importViewingKey
پارامترها [viewing_key] یا [viewing_key, rescan_from_height]، کلید بهصورت 64 نویسهٔ hex. نتیجه { "imported": true, "rescan_from_height": 0, "viewing_keys": 3 }. نود کلید را فقط در حافظه نگه میدارد: حداکثر 64 کلید در هر نود، با راهاندازی مجدد پاک میشود؛ وارد کردن کلیدی که پیشتر نگهداری میشود بیاثر است ("imported": false). وارد کردن هرگز پویش نمیکند؛ پویش را متد بعدی پیش میبرد. برای کلید بدشکل -32602؛ در کلید شصتوپنجم -32000.
این سه متد کلید مشاهده فقط به فراخوان loopback پاسخ میدهند و دیگران را با -32000 رد میکنند، مگر آنکه نود با --rpc-viewing-open پشت چیزی اجرا شود که احراز هویت میکند. rand_removeViewingKey ([viewing_key] ← { "removed": bool, "viewing_keys": n }) یک جایگاه را آزاد و کلید را صفر میکند. رجیستری با شناسهای یکطرفه از کلید، یعنی blake3("rand-viewing-registry-id-1" ‖ nk)، کلیدگذاری میشود و هرگز با خود کلید، پس واردسازی تنها نسخهٔ بلندمدت است و حذف آن را پاک میکند. متن JSON خود درخواست و نسخههای گذرایی که رمزگشایی آزمایشی میسازد پاک نمیشوند.
rand_getViewingNotes
پارامترها [viewing_key] یا [viewing_key, from_index, limit] (پیشفرض و بیشینهٔ limit برابر 1,000). هر فراخوانی پویش کلید را تا 10,000 برگ پیش میبرد، سپس صفحه را ارائه میکند:
{ "scanned_index": 10041, "next_index": 10041, "complete": true,
"notes": [
{ "index": 40, "cm": "2a9f…07", "height": 37, "role": "received",
"note": { "pk": "…", "from": "…", "amount": "1500000000", "asset": 0, "time": 5, "memo": "coffee" },
"nullifier": "8c04…d1", "spent": false },
{ "index": 43, "cm": "b310…88", "height": 39, "role": "sent",
"note": { "pk": "…", "from": "…", "amount": "25000000", "asset": 0, "time": 9, "memo": null },
"nullifier": null, "spent": null } ] }
role برابر received است (پاکت بهعنوان گیرنده باز شد و یادداشت pk کلید را نام میبرد) یا sent (از طریق کلید مشاهدهٔ خروجی باز شد). memo یادداشت، memo رمزگذاریشدهٔ فرستنده است، متن UTF-8 حداکثر 510 بایت، یا null وقتی وجود ندارد یا فیلدش بدشکل باز شده است؛ memo بدشکل هرگز یادداشت را از گیرنده نمیگیرد. memo متن هرکسی است: آن را نامطمئن نمایش دهید. برای کلیدی که این نود وارد نکرده است -32001.
rand_checkTransaction
پارامترها [hash, key]، که key یک TxKey مخصوص هر تراکنش بهصورت 64 نویسهٔ hex است. نتیجه برای hash ناشناخته null است، وگرنه آنچه کلید افشا میکند:
{ "tx": "4f2c…e7", "height": 192,
"disclosed": [ { "output": "bundle:0", "cm": "2a9f…07", "index": 40,
"note": { "pk": "…", "from": "…", "amount": "1500000000", "asset": 0, "time": 5, "memo": "invoice 7" } } ] }
ایستا (Stateless): کلید همراه با فراخوانی دور انداخته میشود. output برای چهار شکاف خروجی بسته، bundle:0 … bundle:3 است (شکافهای ۰ و ۱ خروجیهای دارایی خصوصی و شکافهای ۲ و ۳ خروجیهای RAND هستند، همراه با دادههای ساختگی)، برای پاکت واریز در گواهی bridge، deposit است، برای نوت یک TokenMint، token_mint است، برای mint اولیهٔ یک RegisterToken، initial_mint است، برای تنها پاکت یک mint فاست، mint:0 است، و (v0.6.8) برای نوتهایی که یک invoke پرداخت کرده، payout:0 … payout:3 است، که بر اساس جایشان در گذار شمارهگذاری شدهاند، ابتدا pays و سپس mints؛ asset_bundle:* همراه با بستهٔ دوم حذف شده است. در زنجیرهای که کارمزد bridge دارد، deposit واریز خالص را باز میکند، یعنی مبلغ ناخالص منهای کارمزد. note افشاشده asset خود را دارد: این فراخوانی، با کلیدی که فرستنده با آن مهر کرده، تنها جایی است که RPC نشان میدهد یک انتقال کدام دارایی را جابهجا کرده است. memo را هم دارد، همانطور که rand_getViewingNotes دارد: کلیدی که نوت را باز میکند، یادداشت (memo) را هم از همان بدنهٔ مهرشده باز میکند. کلید نادرست { "disclosed": [] } برمیگرداند، که از تراکنشی که چیزی افشا نمیکند قابل تشخیص نیست. پاکتهای یک withdraw و یک genesis alloc آزموده نمیشوند: آنها درون node با کلیدهایی مهر میشوند که بلافاصله دور انداخته میشوند، بنابراین هیچ TxKey برایشان وجود ندارد. پاکت یک mint فاست آزموده میشود: دریافتکنندهٔ آن کلید را از نیمهٔ KEM پاکت بازیابی میکند (rand tx-key).
تراکنشها
rand_getTransaction
پارامترها [hash]. نتیجه تا زمان commit شدن null است، و سپس:
{
"height": 192, "index": 0, "block_hash": "63f6…08",
"tx": {
"hash": "4f2c…e7", "chain_id": 20,
"bundle": { "anchor": "6b1d…c4",
"nullifiers": ["8c04…d1", "5e77…20", "03aa…6f", "e19b…42"],
"commitments": ["2a9f…07", "b310…88", "77c1…0e", "5d20…b3"],
"fee": "1000000", "burn_a": "0", "burn_r": "0", "burn_asset": 0, "time": 5,
"proof_len": 1490435, "envelope_len": [1860, 1860, 1860, 1860],
"auth_commit": "9217…ee9e", "auth_proof_bytes": 1361161 },
"action": { "kind": "none" }
}
}
bundle در کنشهای بدون بسته null است. اثباتها و پاکتها فقط با طولشان گزارش میشوند. envelope_len در chain 20 برای هر شکاف برابر 1,860 است، چون genesis آن اندازهٔ پاکت نوت را در همین مقدار تثبیت میکند (envelope_bytes در rand_getLimits)؛ در chainهای 14 تا 17 برابر 1,348 بود. auth_commit و auth_proof_bytes به احراز مجوز تفکیکشده (از chain 17) مربوطاند: تعهد عمومی c = H(AUTH, nk, salt) که اثبات بسته و اثبات auth هر دو منتشر میکنند، و طول اثبات auth. در زنجیرهای بدون hc_auth مقدار آنها صفر و 0 است.
bundle بستهٔ دارایی پنهان است (از chain 14): چهار شکاف ورودی و چهار شکاف خروجی، پس همیشه چهار nullifiers، چهار commitments و چهار envelope_len وجود دارد، همراه با دادههای ساختگی. هر تراکنش حداکثر یکی دارد؛ بستهٔ دومی وجود ندارد. این بسته فیلد asset ندارد: شکافهای ۰ و ۱ یک دارایی خصوصی و شکافهای ۲ و ۳ RAND را حمل میکنند، و هیچ چیز عمومی نمیگوید شکافهای ۰ و ۱ کدام دارایی را جابهجا کردهاند. انتقال RAND و انتقال هر توکن RPL هر دو "kind": "none" هستند و burn_a، burn_r و burn_asset در هر دو 0 است، یعنی شکل یکسان، فیلد به فیلد. نوع token_transfer وجود ندارد. سه فیلد burn تنها اظهار عمومی بسته دربارهٔ خروج ارزش از استخر هستند:
burn_a/burn_asset— مقداری از دارایی خصوصی که سوزانده شده، و اینکه کدام دارایی. درtoken_burnیاbridge_burnغیرصفر است، که در آنها باamountوassetکنش برابر است، و درinvokeای کهinflowآنdepositیاburnباشد.burn_r— RAND سوزاندهشده. درbond(برابر باamountآن)،register_aggregator، وinvokeای که RAND را به خزانهٔ (vault) برنامه واریز میکند، غیرصفر است.fee— کارمزد RAND، که همیشه از شکافهای ۲ و ۳ پرداخت میشود.
نمایش کنشها (هر amount، relayer_fee و initial_amount یک رشتهٔ اعشاری است؛ مقدار یک توکن به واحد خودش است، نه RAND):
| نوع | فیلدها |
|---|---|
none | — |
mint | cm، amount، minter (اعتبارسنج، base58) |
deploy | program، words، public_words_len |
call | program، proof_len، input_envelope_len (وقتی فراخوانی هیچ ورودیای ندارد null است) |
bond | validator، amount، registered |
unbond | validator، amount، nonce |
withdraw | validator، amount، nonce، time |
bridge_attest | attestation_len، recipient، asset، asset_index، amount، time، r، commitment، pq_signers (اندیسهای نگهبانان همامضاکننده در pq_guardians؛ امضاهای 2,420 بایتی نمایش داده نمیشوند). asset_index، amount و commitment برای چرخش مجموعهٔ نگهبانان null هستند. r مشتقشده است، blake3("rand-deposit-r-1" ‖ mu) روی چکیدهای که نگهبانان امضا کردهاند. از v0.6.8 همچنین deposit_amount (نوت واریزکننده: amount، یعنی مبلغ ناخالصی که نگهبانان امضا کردهاند، منهای کارمزد bridge) و fee_note ({ amount, asset, time, r, commitment }، نوت خزانه بدون مالکش، یا null بدون کارمزد bridge)؛ commitment برگ واریز خالص است |
bridge_burn | asset، amount، relayer_fee، to_chain، token (پشتوانهای که بازخرید میشود)، to. یک بسته کل burn را حمل میکند: burn_asset و burn_a آن برابر asset و amount کنشاند. از v0.6.8 همچنین release_amount (آنچه بدنهٔ امضاشده آزاد میکند، یعنی amount منهای کارمزد bridge) و fee_note، مانند attest |
register_token | name، symbol، decimals، authority ("none"، "key"، "bridge" یا "program")، index، initial_amount، initial ({ amount, recipient, time, r } یا null) |
token_mint | asset، amount، recipient، time، r، nonce |
set_authority | asset، nonce، new_authority (base58، یا null برای انصراف از اختیار) |
token_burn | asset، amount؛ burn_asset / burn_a بسته آنها را تکرار میکنند |
pause_mints | nonce؛ بدون بسته و بدون کارمزد، امضاشده با کلید توقف genesis |
unpause_mints | nonce، pq_signers؛ بدون بسته و بدون کارمزد |
register_bridged_token | name، symbol، salt، chain، token، decimals (ارقام اعشار مبدأ نخستین پشتوانه)، nonce، asset_id، pq_signers |
list_backing | token_index، chain، token، decimals، nonce، pq_signers |
rotate_pq_guardians | new_pq_guardians، nonce (همان rotation_nonce مصرفشده)، pq_signers (اندیسها در مجموعهٔ PQ پیش از چرخش)؛ بدون بسته و بدون کارمزد، فقط در chainهای bridge با rules_v2 |
rotate_pause_key | new_pause_key، nonce، pq_signers؛ مانند بالا |
rotate_pq_guardians_v2, rotate_pause_key_v2 | v0.6.8: فیلدهای v1، بهعلاوهٔ possession_signatures (یک شمارنده) در شکل PQ. بدون بسته و بدون کارمزد؛ در chainی الزامی است که bridge.rotation در genesis آن needs_possession را تنظیم کرده باشد، مانند chain 20. چرخش delay_secs بعد اعمال میشود (در chain 20 برابر 86,400 s) |
cancel_rotation | v0.6.8: rotation_kind ("pq_guardians" یا "pause_key")، nonce؛ با کلید توقف فعلی امضا میشود و یک چرخش در انتظار را لغو میکند |
admit_validator | v0.6.8: candidate (نشانی)، candidate_key (hex)، voters (نشانیها). بدون بسته و بدون کارمزد: رأی مجموعهٔ اعتبارسنجها برای اجازهٔ ثبتنام یک کلید جدید، در chainی با staking.admission_by_vote، مانند chain 20 |
slash_equivocation | v0.6.8: offender، view، first و second ({ hash, height })؛ فقط در chainهای دارای staking.slashing، که chain 20 از آنها نیست |
invoke | v0.6.8، RPL-2: فیلدهای یک call (program، proof_len، input_envelope_len) و transition آن (در ادامه). فقط در chainهای دارای بخش program_state، مانند chain 20 |
register_aggregator, unbond_aggregator, withdraw_aggregator, slash_aggregator, aggregate | فیلدهای عمومی آنها؛ فقط در chainهای دارای تجمیع |
claim_vested, revoke_vesting, bond_vested, unbond_vested | entry (hex)، amount (در revoke برابر unvested)، nonce؛ time در claim یا revoke؛ validator و registers در bond؛ از v0.6.8 signers در revoke (جایگاه امضاکنندگان آن در revokers ورودی). بدون بسته؛ فقط در chainهای دارای بخش vesting در genesis، که chain 20 از آنها نیست |
ثبت و mintهای یک توکن عمومی است، همانطور که واریز bridge عمومی است: هر واژهٔ یک نوت mintشده در کنش آمده است (from آن MINT_FROM ثابت chain است)، بنابراین دریافتکننده نوت را از این فیلدها بازسازی میکند، بدون رمزگشایی هیچ چیز. رشتههای نوع bridge_attest، token_mint، register_token و invoke همانهایی هستند که اسکن کیف پول بر آنها تکیه دارد و با یک آزمون تثبیت شدهاند.
یک invoke در ارتفاع 3,079 از chain 20، که یک cell را خواند، آن را حذف کرد و دو نوت را از vault پرداخت کرد:
{ "kind": "invoke", "program": "aaaf…4b21", "proof_len": 1433874, "input_envelope_len": null,
"transition": {
"reads": [{ "key": "0100…fa98", "value": "0000000004000000…00000000" }],
"writes": [{ "key": "0100…fa98", "value": "0000000000000000000000000000000000000000000000000000000000000000" }],
"inflow": "none",
"pays": [{ "asset": 0, "amount": "1000000000", "recipient": "rand1…", "time": 3027, "r": "87e6…9a67", "cm": "2555…6487" },
{ "asset": 4, "amount": "2000000000", "recipient": "rand1…", "time": 3027, "r": "b833…f390", "cm": "2b70…f204" }],
"mints": [] } }
همهٔ اینها عمداً عمومی است. reads همان cellهایی هستند که برنامه خوانده، با مقادیری که خوانده: اثبات بر پایهٔ آنها ساخته شده، و لجر تراکنش را رد میکند مگر اینکه هنوز برقرار باشند. writes cellهایی هستند که برنامه نوشته؛ مقدار نوشتهشدهٔ 64 صفر، cell را حذف میکند. کلید یا مقدار یک cell از نوع Word8 است. آنچه وارد شده از آنِ بسته است: burn_r همان RAND واریزشده به vault برنامه است، و burn_a از burn_asset همان توکنی است که inflow نام میبرد، یعنی deposit به vault یا burn (توکن خود برنامه)، و وقتی burn_a برابر 0 باشد none. آنچه خارج شده یک نوت محاسبهشده توسط chain برای هر پرداخت است، ابتدا pays از vault و سپس mints از توکنی که اختیار mint آن با این برنامه است. هر واژهٔ هر نوت اینجا با نام فیلدهای token_mint آمده است؛ time از آنِ بسته است، cm برگی است که chain افزوده، و from نوت PROGRAM_FROM ثابت chain است. هشت واژهٔ خروجی برنامه روی رسید است، همانطور که برای یک call هست.
هیچ پاسخ انتقالی فرستنده، دریافتکننده، nonce، مبلغ یا دارایی ندارد: چنین فیلدی در یک انتقال ذخیرهشده وجود ندارد.
rand_getRawTransaction
پارامترها [hash]. نتیجه: تراکنش کامل commit شده بهصورت bincode hex، شامل بایتهای اثبات — آنچه یک تجمیعگر نیاز دارد و rand_getTransaction هرگز نمایش نمیدهد.
برنامهها و رسیدها
rand_getProgram
پارامترها [program_id]. نتیجه null یا { "id", "base_pc", "words_len", "code_hash", "deployed_at", "public_words_len", "public_digest" }. فیلد deployer وجود ندارد: هزینهٔ deploy را یک بسته میپردازد. public_words_len طول ورودی عمومی زمان deploy برنامه است (بدون آن 0)؛ public_digest چکیدهٔ آن است، مقداری که اثبات هر call در برابرش بررسی میشود، یا بدون آن null.
rand_getProgramCode
پارامترها [program_id]. نتیجه null یا { "base_pc": 0, "words": [ … ] }.
rand_getProgramPublic
پارامترها [program_id]. نتیجه: کلمههای عمومیِ زمان استقرار برنامه، بهصورت یک رشتهی هگز، هر کلمه با ۴ بایت little-endian خودش (۸ رقم هگز برای هر کلمه): [1, 2, 0xdeadbeef] میشود "0100000002000000efbeadde". برای برنامهای که بدون ورودی عمومی مستقر شده "" است و برای شناسهای که هیچ برنامهای ندارد null. کیف پولی که برای یک فراخوانی اثبات میسازد، این کلمهها را به اثباتکننده میدهد؛ دفتر کل تعهدِ اثبات را با public_digest برنامه مقایسه میکند.
rand_getProgramCell
v0.6.8، RPL-2. پارامترها [program_id, key]، که کلید یک Word8 است بهصورت ۶۴ رقم هگز (با 0x یا بدون آن). نتیجه { "key": "<64 hex>", "value": "<64 hex>" }. سلولی که برنامه هرگز در آن ننوشته، یا در آن صفر نوشته (که آن را حذف میکند)، بهصورت ۶۴ صفر خوانده میشود، یعنی تنها رمزگذاریِ «نبودن»؛ هر کلیدِ برنامهای که کسی مستقر نکرده نیز همینطور است، چون وجود برنامه بررسی نمیشود. در زنجیرهای بدون بخش program_state پاسخ { "enabled": false } است. سلول طبق طراحی عمومی است: کیف پول برای ساختن reads یک invoke همین را میخواند.
rand_getProgramCells
v0.6.8. پارامترها [program_id, { "after": "<64 hex>" | null, "limit": n }]، که شیء اختیاری است. نتیجه { "cells": [{ "key", "value" }, …], "next": "<64 hex>" | null }: سلولهای برنامه به ترتیب کلید (مقایسهی بدون علامتِ هشت کلمه)، با شروع پس از after، حداکثر به تعداد limit (به بازهی ۱ تا 1,000 محدود میشود). next آخرین کلیدِ ارائهشده است، هرگاه ادامهای باشد؛ آن را بهعنوان after پس بفرستید. در صفحهی آخر null است. برنامهای که هیچ سلولی ندارد پاسخ { "cells": [], "next": null } میگیرد؛ بدون این بخش پاسخ { "enabled": false } است.
rand_getProgramVault
v0.6.8. پارامترها [program_id]. نتیجه [{ "asset": 0, "amount": "123" }, …]، به ترتیب صعودیِ شاخص دارایی (۰ همان RAND است و هر شاخص دیگر از آنِ ثبتدفتر توکنهاست)، مقدارها رشتههای اعشاریِ بر حسب واحد خودِ دارایی. ردیفی که صفر باشد وجود ندارد، پس خزانهی خالی، و نیز برنامهای که کسی مستقر نکرده، [] است. بدون این بخش پاسخ { "enabled": false } است. ارزش از راه بستهی یک invoke وارد خزانه میشود (burn_r، و burn_a از burn_asset وقتی inflow برابر deposit باشد) و بهصورت نوتهایی که pays گذار نام میبرد از آن خارج میشود.
rand_getLimits
پارامترها []. نتیجه: آنچه کیف پول برای ساختن تراکنش از genesis زنجیره لازم دارد: پنج حد فراخوانی، اندازهی پاکت نوت، کلید v0.6، راهنمای احراز هویت (auth guest)، شرایط گس و، از v0.6.8، فیلدهای genesis مربوط به audit-v6 و حدهای وضعیت برنامه. در زنجیرهی 20:
{ "max_program_words": 65535, "max_proof_bytes": 4194304, "max_block_bytes": 20971520,
"max_call_envelope_bytes": 65536, "max_program_public_words": 32768,
"envelope_bytes": 1860, "hardening_v6": true,
"hc_auth": "1e4e347f44cf86750b30a9a4bdf9ec9256efe353d4ff8017451eca7d195639c1",
"gas_metering": "circuit", "gas_price": "100", "byte_price": "800",
"bundle_gas_limit": 20479, "adjust_bps": 1250,
"max_gas_price": "10000", "max_byte_price": "80000", "byte_load": "paying",
"admission_by_vote": true, "testnet": true, "slashing": null, "binding_domain": 1,
"proof_window_blocks": 1024,
"program_state": { "cell_fee": "10000000", "max_reads": 8, "max_writes": 8, "max_payouts": 4 } }
genesis بدون پنج فیلد حد (زنجیرهی 12) مقادیر 4096، 2097152، 4194304، 18432 و 0 را میگیرد. max_proof_bytes در زنجیرههای 13 تا 15 برابر 8,388,608 بود.
| فیلد | معنا |
|---|---|
envelope_bytes | 1860 وقتی genesis هر پاکتِ نوتساز را دقیقاً با همین طول ثابت کرده باشد، یعنی قالبِ حامل یادداشت (memo)؛ null در genesis بدون این فیلد (زنجیرههای 14 تا 17)، که در آن کیف پول پاکت ۱,۳۴۸ بایتیِ بدون memo را مهروموم میکند. مقدار دیگری وجود ندارد |
hardening_v6 | true وقتی genesis قواعد اعتبارسنجی v0.6 را اجرا کند. در این حالت کیف پول فراخوانی را روی ورودی عمومی برنامه بهعلاوهی اتصال فراخوانیِ تراکنش اثبات میکند، نه روی ورودی عمومی بهتنهایی: نوتهای بستهی کارمزد اول انتخاب میشوند، فراخوانی دوم اثبات میشود و بسته آخر. زنجیرهای که این پرچم را دارد اثبات قدیمی را رد میکند و زنجیرهای که ندارد اثبات جدید را |
hc_auth | راهنمای احراز هویتی که genesis ثابت میکند، بهصورت هگز، یا null. اگر مقدار داشته باشد، hc_bundle راهنمای بستهی نسخهی ۳ است و هر بسته auth_commit و یک اثبات احراز هویت دارد: کیف پول nk و یک salt تازه به راهنمای بسته میدهد و راهنمای احراز هویت را روی کلید خرج اثبات میکند |
gas_metering | "circuit" در زنجیرهای که genesis آن بخش gas دارد (شمارشگر درون مدار)؛ "header" در زنجیرهای بدون آن، وقتی نود سیاست گس خودش را اجرا میکند (--gas-price، --byte-price)؛ null در صورت نبودن هیچکدام |
gas_price, byte_price | واحد به ازای هر گس، و واحد به ازای هر KiB از اثبات و پاکت ورودیِ یک فراخوانی، بهصورت رشتههای اعشاری. زیر بخش gas اینها وضعیت اجماعاند و در همهی نودها یکسان: با gas.dynamic، مانند زنجیرهی 20، قیمتهای فعلیِ سر زنجیرهاند که در هر بلاک بر اساس پر بودن جابهجا میشوند، هرگز از کفهای genesis (100 و 800) پایینتر نمیروند و هرگز از سقفها بالاتر نمیروند؛ بدون آن، قیمتهای ثابتِ همان بخشاند. بدون بخش، سیاستِ خودِ این نود هستند و دو نود ممکن است پاسخ متفاوت بدهند |
bundle_gas_limit | گس ثابتی که اثبات هر بسته باید اعلام کند، از بخش gas در genesis؛ بدون آن بخش null |
adjust_bps | بزرگترین جابهجاییِ قیمت در یک بلاک توسط کنترلکنندهی پویا، بر حسب نقطهی پایه (basis point)؛ در زنجیرهی بدون gas.dynamic برابر null |
max_gas_price, max_byte_price | v0.6.8: سقفهایی که کنترلکننده هرگز قیمت را از آنها بالاتر نمیبرد، رشتههای اعشاری؛ در زنجیرهی 20 برابر "10000" و "80000"، و null هرجا genesis سقفی تعیین نکرده باشد (زنجیرههای 18 و 19) |
byte_load | v0.6.8: "paying" وقتی فقط اثبات و پاکت ورودیِ یک فراخوانی byte_price را جابهجا کند، پس بلاکی از انتقالها هیچ جابهجاییای ایجاد نمیکند، مانند زنجیرهی 20؛ null هرجا بایتهای هر تراکنش شمرده شود (زنجیرههای 18 و 19) |
admission_by_vote | v0.6.8: اینکه آیا وثیقهای که کلید اعتبارسنج جدیدی را ثبت میکند، ابتدا به رأی مجموعهی اعتبارسنجها نیاز دارد (rand_getAdmitted)؛ در زنجیرهی 20 true |
testnet | v0.6.8: نشانگر testnet در genesis، که اجازه میدهد faucet در کنار بخش bridge قرار گیرد؛ در زنجیرهی 20 true و در هر زنجیرهی پیش از آن false |
slashing | v0.6.8: { "equivocation_bps", "jail_epochs" }، یعنی هزینهی دوگانهگویی (equivocation) یک رهبر، یا null؛ در زنجیرهی 20 null |
binding_domain | v0.6.8: 0 هرجا اتصال تراکنش و هر پیام کنشِ امضاشده فقط به شناسهی زنجیره متصل شود (زنجیرههای 14 تا 19)، 1 هرجا هش genesis را هم حمل کنند، بهطوریکه اثبات یا امضایی که برای یک زنجیره ساخته شده روی هیچ زنجیرهی دیگری تأیید نشود (زنجیرهی 20). کیف پول بر اساس شناسهی زنجیره تصمیم میگیرد کدام شکل را اثبات کند، نه بر اساس این پاسخ: کیف پول rand در v0.6.8 برای شناسههای زنجیرهی 14 تا 19 شکل مبتنی بر شناسهی زنجیره و برای هر شناسهی دیگر شکل متصل به genesis را به کار میبرد و این فیلد را فقط برای رد زودهنگام میخواند. کیف پولی قدیمیتر از v0.6.8 نمیتواند در زنجیرهی 20 ارسال کند |
proof_window_blocks | v0.6.8: اینکه لنگر (anchor) یک بسته حداکثر چند بلاک میتواند قدیمی باشد و time آن حداکثر چند بلاک میتواند از ارتفاع عقب باشد، یک پنجره برای هر دو؛ در زنجیرهی 20 برابر 1024 و در زنجیرههای تا 19 برابر null (256). کیف پولی که اثباتکنندهی کند یا واگذارشده دارد، این را میخواند تا بداند اثبات چقدر میتواند طول بکشد |
program_state | v0.6.8، RPL-2: بخش program_state در genesis و حدهای invoke آن، یا null، که در آن هر invoke رد میشود و هیچ توکن برنامهای ثبت نمیشود. cell_fee واحدهای RAND است (رشتهی اعشاری) که کفِ کارمزدِ یک invoke به ازای هر سلولی که میسازد افزایش میدهد، یعنی نوشتن مقداری غیرصفر در سلولی که صفر خوانده میشود؛ بازنویسی، حذف یا نوشتن صفر هزینهای ندارد. max_reads، max_writes و max_payouts (pays و mints با هم) سقفهای سختاند. در عمل قاعدهی قطعه (segment) زودتر محدود میکند: کلمههای زمینهی گذار (11 + 16 به ازای هر خواندن یا نوشتن + 3 به ازای هر پرداخت) باید در کنار ورودی عمومی برنامه و ۸ کلمهی اتصال جا شوند، بیآنکه جدول عمومیِ zkVM بزرگتر شود؛ برای برنامهای بدون ورودی عمومی این جدول ۱۲۸ ردیف است، که ۱۱۹ کلمهی زمینه باقی میگذارد |
نودی که از یک فیلد قدیمیتر است بدون آن پاسخ میدهد. هیچ چیز در این پاسخ احراز هویت نشده است، پس کیف پول envelope_bytes را فقط به گفتهی نود نمیپذیرد: کیف پول rand در شناسههای زنجیرهی 14 تا 17 هر پاسخی که نود بدهد پاکت قدیمی را مهروموم میکند، و کلاینتهای دیگر هم باید همین کار را بکنند.
rand_getReceipt
پارامترها [tx_hash]. نتیجه تا زمانی که فراخوانی ثبت نشده null است، سپس { "tx", "program", "tier": 14, "outputs": [1, 0, 25, 0, 0, 0, 0, 0], "height": 17, "index": 0, "h_in": "9c0e…7f", "h_pub": null }. فیلد effect وجود ندارد. h_pub چکیدهی ورودی عمومیِ زمان استقرار برنامه است که اثبات فراخوانی در برابر آن بررسی شده، و برای برنامهای بدون ورودی عمومی null است. یک invoke (v0.6.8) رسید یک فراخوانی را دارد، و rand_getReceipts و موضوع receipts آن را بدون تغییر حمل میکنند.
rand_getReceipts
پارامترها [program_id, from_height, to_height, limit?]. نتیجه { "receipts": [ … ], "next_height": 2051 }: رسیدهای program_id با from_height <= height <= to_height، به ترتیب ارتفاع و سپس شاخص، که هر کدام دقیقاً همان شیء rand_getReceipt است. limit بهطور پیشفرض و حداکثر 256 است و هرگز یک ارتفاع را نمیشکند: وقتی صفحهای به limit رسید باز هم بقیهی رسیدهای همان ارتفاع را ارائه میکند. next_height نخستین ارتفاعِ ارائهنشده است، یا null وقتی to_height صفحه را پایان داده باشد. برای to_height کمتر از from_height خطای -32602 برمیگردد.
rand_getCallEnvelope
پارامترها [tx_hash]. نتیجه null است، یا { "tx", "h_in", "kem_ct", "to_sender", "to_auditor", "body" } بهصورت هگز — رونوشت ورودیِ مهرومومشدهی فراخوانی، که عیناً ارائه میشود؛ نود کلیدی که آن را بگشاید ندارد. وقتی فراخوانی چیزی منتشر نکرده باشد (--no-envelope)، تراکنش فراخوانی نباشد، یا رسیدی وجود نداشته باشد، null است.
Staking and supply
rand_getValidators
پارامترها []. نتیجه: یک ردیف برای هر ورودیِ ثبتدفتر، به ترتیب نشانی، مقدارها بهصورت رشتههای اعشاری:
[{ "address": "…", "stake": "1000000000000",
"pending": [{ "release_epoch": 41, "amount": "5000000000" }],
"rewards": "4000000", "payout": "rand1…", "nonce": 3, "active": true, "jailed_until": null }]
jailed_until (v0.6.8) نخستین epoch است که یک کلیدِ slashشده میتواند دوباره در یک مجموعه باشد (18446744073709551615 برای همیشه)، و وقتی زندانی نیست null است. زنجیرهی 20 staking.slashing ندارد، پس در آن همیشه null است.
rand_getAdmitted
v0.6.8. پارامترها []. نتیجه { "admission_by_vote": true, "max": 256, "admitted": ["<address>", …] }: کلیدهایی که مجموعه اعتبارسنجها با یک AdmitValidator به آنها رأی داده است و هنوز ثبتنام نکردهاند، به ترتیب آدرس. در زنجیرهای که genesis آن staking.admission_by_vote را تنظیم میکند، مانند زنجیره ۲۰، یک Bond که کلید جدیدی را ثبت میکند باید در میان آنها باشد. max تعداد کلیدهایی است که دفتر کل همزمان نگه میدارد. در زنجیرهای بدون این پرچم، admission_by_vote برابر false است، فهرست همیشه خالی است و ثبتنام به رأی نیاز ندارد. زنجیره ۲۰ در 2026-10-01 پاسخ "admitted": [] داد.
rand_getEpoch
پارامترها []. نتیجه { "epoch": 41, "epoch_blocks": 1000, "next_set": ["…", "…"] }؛ next_set یک پیشبینی است.
rand_getSupply
پارامترها []. نتیجه:
{ "height": 1998,
"genesis_deposited": "…", "genesis_staked": "…", "faucet_minted": "…",
"faucet_epoch": "…", "faucet_minted_in_epoch": "…",
"withdraw_deposited": "…", "fees_paid": "…", "burned": "…",
"subsidised": "…", "sealed_blocks": "…", "aggregator_bonds": "…", "slashed": "…",
"registration_fees_burned": "…",
"vesting_issued": "…", "vesting_released": "…", "vesting_in_register": "…", "vesting_locked": "…",
"program_rand_out": "…", "program_rand_held": "…",
"pool_value": "…", "register_total": "…", "total_supply": "…", "invariant_holds": true }
فیلدهای subsidised، sealed_blocks، aggregator_bonds و slashed فقط در زنجیرهی تجمیعی تغییر میکنند. faucet_epoch و faucet_minted_in_epoch شمارندهی هر دورهی faucet در برابر staking.faucet_budget_per_epoch هستند (در زنجیره ۲۰ بخشی از وضعیت اجماع). چهار فیلد vesting_* شمارندههای vesting در genesis هستند و در زنجیرهای بدون بخش vesting، که زنجیره ۲۰ چنین است، همگی "0" هستند. program_rand_out و program_rand_held (v0.6.8، RPL-2؛ بدون بخش program_state برابر "0") به ترتیب RAND ای هستند که invokeها از خزانههای برنامه به شکل نوت پرداخت کردهاند (سمت استخر، درون pool_value) و آنچه خزانهها هنوز نگه میدارند (سمت ثبت، درون total_supply)؛ این مقدار از طریق burn_r یک invoke وارد شده است، بنابراین در سمت استخر درون burned قرار دارد. registration_fees_burned برابر Σ کارمزدهای ثبت توکن است که تحت tokens.burn_registration_fee در genesis سوزانده شدهاند، و زنجیره ۲۰ آن را تنظیم میکند؛ invariant_holds آن را، همراه با slashed، از آنچه زنجیره صادر کرده کم میکند. Supply این اتحاد را توضیح میدهد.
rand_getEmission
پارامترها []. نتیجه { "inflation": "0", "subsidy": null, "faucet": true }. inflation همواره "0" است. subsidy برنامهی تجمیع بلوک است (current، base، halving_blocks، sealed_blocks، next_halving_at) و در زنجیرهای بدون بخش aggregation، که زنجیره ۲۰ چنین است، null است. faucet همان مقدار rand_status را بازتاب میدهد.
پل
هر چهار متد روی هر زنجیرهای پاسخ میدهند؛ در زنجیرهای بدون بخش bridge، وضعیت { "enabled": false } و رجیستری [] است. genesis زنجیره ۲۰ چنین بخشی دارد: مجموعهی نگهبانان ۱ (guardian_set_index برابر 1) با هشت نگهبان، هشت نگهبان PQ، یک کلید توقف، burn_sequence برابر 13 در genesis، یک کف بازپخش (min_inbound_sequence برابر 3 برای زنجیرههای مبدأ 2، 3 و 4، و 7 برای زنجیرهی مبدأ 5)، rules_v2 پل با سقف ضرب سراسری 4,000 zUSD در هر بازهی ۲۴ ساعته بر مجموع همهی پشتوانهها، و دو گروه جدید در v0.6.8: rotation (چرخش نگهبانان PQ یا کلید توقف به اثبات تملک کلیدهای جدید نیاز دارد و ۸۶٬۴۰۰ ثانیه پس از ثبت اعمال میشود) و fees (10 bps از هر واریز و 10 bps از هر سوزاندن، که روی Rand به شکل یک نوت zUSD به آدرس خزانه نگه داشته میشود). زنجیره ۱۹ مقدار burn_sequence برابر 8 و کفهای 1 و 4 داشت و هیچیک از آن دو گروه را نداشت. بخش tokens آن یک registration_fee برابر 1 RAND (سوزاندهشده)، یک mint_cap_per_day بهازای هر پشتوانه برابر 10000000000000 (100,000 zUSD با هشت رقم اعشار) دارد و خود zUSD را فهرست میکند: در genesis از زنجیره ۱۴ منتقل شده، با همان شناسهی دارایی، اندیس 1 و هفت پشتوانه.
rand_getBridgeState
پارامترها []. نتیجه { "enabled": false } یا:
{
"enabled": true,
"emitter": "01…",
"emitters": { "2": "02…" },
"guardian_set_index": 0,
"guardians": ["aabb…"],
"pq_guardians": ["…"],
"mint_paused": false,
"pause_nonce": 0,
"list_nonce": 0,
"pause_key": "…",
"registration_fee": "1000000000",
"burn_sequence": 1,
"rotation_nonce": 0,
"rules_v2": { "global_mint_cap_per_window": "…", "cap_window_secs": 86400,
"global_minted_in_window": "…", "global_mint_headroom": "…" },
"min_inbound_sequence": { "2": 2, "3": 2, "4": 2, "5": 2 },
"rotation_rules": { "delay_secs": 86400, "needs_possession": true },
"pending_rotations": [],
"fees": { "mint_bps": 10, "burn_bps": 10, "recipient": "rand1…" },
"assets": [ … ]
}
| فیلد | معنا |
|---|---|
emitter | آدرس منتشرکنندهی خروجی این زنجیره، ۳۲ بایت بهصورت hex |
emitters | شناسهی زنجیرهی مبدأ ← آدرس منتشرکنندهای که در آنجا مورد اعتماد است |
guardians | آدرسهای ۲۰ بایتی مجموعهی فعلی، بهصورت hex |
pq_guardians | مجموعهی PQ: کلیدهای عمومی Dilithium2 (1,312 بایت)، بهصورت hex، هماندیس با مجموعهی فعلی نگهبانان (مجموعهی 1 در زنجیره ۲۰). هر BridgeAttest حامل حد نصابی از همامضاهای این مجموعه است. چرخش مجموعهی نگهبانان هرگز آن را جابهجا نمیکند؛ فقط rotate_pq_guardians این کار را میکند، روی زنجیرهی rules_v2 |
mint_paused | تا زمانی که true است، هر attest انتقال با bridge minting is paused رد میشود؛ سوزاندنها و چرخشها باز میمانند |
pause_nonce | آنچه توقف یا رفع توقف بعدی باید حمل کند؛ هر دو آن را افزایش میدهند |
list_nonce | آنچه register_bridged_token یا list_backing بعدی باید حمل کند؛ هر دو آن را افزایش میدهند |
pause_key | تنها کلید Dilithium2 که میتواند ضرب را متوقف کند، بهصورت hex. این کلید فقط میتواند متوقف کند: رفع توقف به حد نصاب نگهبانان PQ نیاز دارد |
registration_fee | آنچه یک RegisterBridgedToken فراتر از پایهی بسته بدهکار است، به واحد RAND، بهصورت رشتهی اعشاری |
burn_sequence | تعداد پیامهای خروجی که تاکنون منتشر شدهاند |
rotation_nonce | آنچه rotate_pq_guardians / rotate_pause_key بعدی باید حمل کند |
rules_v2 | سقف ضرب سراسری و بازهی غلتان آن، یا null در زنجیرهای بدون قوانین پل v2. تحت آن، سقف هر پشتوانه نیز یک بازهی غلتان است و تا زمانی که ضرب متوقف است، فهرستکردن رد میشود. از v0.6.8 فیلدهای global_minted_in_window و global_mint_headroom را هم، بهصورت رشتهی اعشاری، حمل میکند |
min_inbound_sequence | کف بازپخش genesis: شناسهی زنجیرهی مبدأ ← کمترین sequence ای که یک انتقال از آن زنجیره میتواند حمل کند، اعداد ساده؛ در زنجیرهای که چنین کفی ندارد (زنجیره ۱۵ و پیش از آن) null. یک bridge_attest زیر آن با BelowReplayFloor رد میشود، که حکمی دائمی است. یک relayer آن را میخواند تا قفلی را که زنجیرهی مبدأ این زنجیره قبلاً ضرب کرده است کنار بگذارد |
rotation_rules | v0.6.8: { "delay_secs", "needs_possession" } از bridge.rotation در genesis، یا null. تحت آن، چرخش همان action از نوع _v2 است که امضاهای تملک کلیدهای جدید را حمل میکند و پیش از اعمال، delay_secs منتظر میماند |
pending_rotations | v0.6.8: چرخشهایی که ثبت شدهاند و هنوز اعمال نشدهاند، هر یک { "kind": "pq_guardians", "new_pq_guardians", "effective_at_secs" } یا { "kind": "pause_key", "new_pause_key", "effective_at_secs" }؛ بدون rotation_rules برابر null. یک cancel_rotation که کلید توقف فعلی امضا کرده باشد یکی را حذف میکند |
fees | v0.6.8: { "mint_bps", "burn_bps", "recipient" } از bridge.fees در genesis، یا null (زنجیرههای ۱۴ تا ۱۹). زنجیره این سهم را از هر واریز و هر سوزاندن، با گرد کردن به پایین تا یک واحد کامل آزادسازی پشتوانه، به شکل یک نوت zUSD به recipient نگه میدارد. یک واریز، مقدار ناخالص منهای کارمزد را اعتبار میدهد؛ بدنهی امضاشدهی یک سوزاندن، مقدار آن منهای کارمزد را آزاد میکند. یک کیف پول آن را میخواند تا واریز خود را ارزشگذاری کند و، وقتی خودش recipient است، نوتهای کارمزد خود را بازسازی کند |
assets | ردیفهای rand_getAssets |
بدون موجودی: ارزش پلشده نوت است. دیگر next_index وجود ندارد: یک توکن پلشده پیش از آنکه بتوان واریزش کرد، با اندیسی که ثبت آن از پیش تعیین کرده فهرست میشود، پس اندیسی برای پیشبینی باقی نمیماند. اندیس یک توکن فهرستشده را از assets یا rand_getTokens بخوانید.
rand_getAssets
پارامترها []. نتیجه: رجیستری داراییهای پل، صعودی بر اساس اندیس، یا []:
[{ "index": 1, "chain": 2, "token": "aaaa…", "asset_id": "…", "decimals": 6, "locked": "600",
"mint_cap_per_day": "10000000000000", "minted_today": "1000", "mint_day": 20350,
"minted_in_window": "1000", "mint_window_secs": 86400, "mint_headroom": "390000000000" }]
از v0.6.8 هر ردیف پشتوانه، اینجا و در هر جا که پشتوانهها ارائه میشوند (rand_getBridgeState.assets، backings در rand_getToken، rand_getTokens و rand_getTokenSupply)، حامل minted_in_window (رشتهی اعشاری) و mint_window_secs است که هر دو در زنجیرهی شمارندهی روزانه null هستند، و حامل mint_headroom: بزرگترین واریز به آن پشتوانه که سقفها در زمان بلوک سر زنجیره میپذیرند، یعنی سقف هر پشتوانه منهای آنچه ضرب کرده و، تحت rules v2، نه بیشتر از آنچه بازهی سراسری رجیستری باقی دارد. mint_headroom را بخوانید، نه mint_cap_per_day − minted_today را که سقف سراسری را نادیده میگیرد. تحت rules v2، مانند زنجیره ۲۰، minted_today شمار بازهی غلتان است، یعنی رقمی که سقف هر پشتوانه در برابر آن بررسی میشود؛ توصیف شمارندهی روزانه در ادامه مربوط به زنجیره ۱۴ است.
یک ردیف برای هر پشتوانه (سکهی مبدأ)، بنابراین توکنی با هفت پشتوانه، هفت ردیف زیر یک index است. index همان واژهی asset است که یک نوت از آن دارایی حمل میکند؛ اندیس 0 همان RAND است و هرگز در رجیستری نیست. decimals تعداد ارقام اعشار مبدأ پشتوانه است. locked، mint_cap_per_day و minted_today رشتههای اعشاری به واحدهای هشترقم اعشاری خود توکن هستند، نه RAND؛ mint_day یک عدد صحیح ساده است، شمارهی روز UTC. mint_cap_per_day همان tokens.mint_cap_per_day در genesis است، یعنی بیشترین مقداری که یک پشتوانه میتواند در هر روز UTC زمان بلوک ضرب کند. minted_today مقداری است که پشتوانه در mint_day ضرب کرده است، یعنی روز UTC (timestamp_ms / 86,400,000) بلوک سر زنجیره، بنابراین شمارندهای که از روز قبل مانده است، وقتی سر زنجیره از نیمهشب بگذرد "0" خوانده میشود. واریزی که از سقف بگذرد با MintCapExceeded رد میشود و روز بعد پذیرفتنی میشود. chain و token هویت روی شبکهای هستند که نگهبانان دربارهی آن امضا میکنند؛ asset_id همان blake3 این دو است، آنچه rand_bridgeAssetId محاسبه میکند.
rand_bridgeAssetId
پارامترها [token_chain, token_address] (عدد صحیح، ۳۲ بایت hex). نتیجه: شناسهی دارایی، ۶۴ نویسهی hex. محاسبهای صرف.
rand_getBridgeBurn
پارامترها [sequence]. نتیجه null یا { "sequence": 0, "body_hex": "…", "digest": "…", "tx": "…", "height": 2, "amount": "…", "release_amount": "…", "fee": "…" }.
سه فیلد آخر از v0.6.8 و روی هر زنجیرهای هستند، بهصورت رشتهی اعشاری به واحدهای هشترقم اعشاری توکن. release_amount مقداری است که بدنهی امضاشده حمل میکند، که از خود body_hex خوانده میشود: آنچه قرارداد مبدأ آزاد میکند و کارمزد relayer بدنه از آن پرداخت میشود. fee کارمزد پلی است که زنجیره به شکل یک نوت خزانه نگه داشته است، و amount آنچه بسته سوزانده است، یعنی release_amount + fee. بدون bridge.fees (زنجیرههای ۱۴ تا ۱۹) مقدار fee برابر "0" است. sequence 13 در زنجیره ۲۰، سوزاندن 0.999 zUSD: "amount": "99900000"، "fee": "99900"، "release_amount": "99800100".
توکنها (RPL)
رجیستری توکن RPL: هر توکن، پلشده و بومی. Tokens این استاندارد را توضیح میدهد.
rand_getTokens
پارامترها [from_index, limit]، هر دو اختیاری (0 و 1000؛ limit به 1,000 محدود میشود). نتیجه: رجیستری به ترتیب صعودی اندیس از from_index، که با بازه از آن اندیس خوانده میشود:
{ "enabled": true, "registration_fee": "1000000000", "next_index": 3, "max_tokens": 4096,
"burn_registration_fee": true, "bound_note_value": true,
"tokens": [
{ "index": 2, "id": "<64 hex>", "id_text": "rpl1…", "name": "Test Coin", "symbol": "TST",
"decimals": 6,
"authority": { "kind": "key", "key": "<Dilithium2 key, hex>", "address": "<base58>" },
"mint_nonce": 1, "total_supply": "5700", "registered_at": 3 }
] }
در زنجیرهای که بخش tokens ندارد: { "enabled": false, "tokens": [] }. index همان واژهٔ asset است که نوتِ آن توکن حمل میکند (0 همان RAND است و هرگز فهرست نمیشود). id شناسهٔ دارایی توکن و id_text شکل متنیِ دارای جمع کنترلی آن است: bech32m، با HRP برابر rpl، روی 32 بایت شناسه، در 62 نویسه. authority یکی از اینهاست:
kind | سایر فیلدها |
|---|---|
none | — (عرضهٔ ثابت، یا صرفنظرشده) |
key | key، address |
bridge | backings: [{ "chain", "token", "decimals", "locked", "mint_cap_per_day", "minted_today", "mint_day" }]، فیلدهای rand_getAssets، یک ردیف برای هر پشتوانه |
program | program |
عرضهها، locked، mint_cap_per_day، minted_today و registration_fee رشتههای اعشاریاند (واحد RAND برای registration_fee و واحد توکن برای بقیه)؛ next_index، mint_day و max_tokens عدد هستند. max_tokens سقف ثبتنام در رجیستری است که در genesis تعیین میشود (4,096 در زنجیرهٔ 20؛ بدون سقف null)، و ثبتنام پس از آن با RegistryFull رد میشود. burn_registration_fee مشخص میکند که کارمزد ثبتنام سوزانده میشود، نه اینکه به پیشنهاددهنده پرداخت شود؛ bound_note_value مشخص میکند که آیا mint یا واریز برابر یا بیشتر از 2⁶³ یک قاعدهٔ اعتبار است (پذیرش در هر زنجیرهای، فارغ از این، آن را رد میکند). هر سه در زنجیرهٔ 20 تنظیم شدهاند. صفحهای که کوتاهتر از limit باشد، آخرین صفحه است.
یک authority از نوع program ({ "kind": "program", "program": "<id>" }) فقط در زنجیرهای قابل ثبت است که بخش program_state داشته باشد، مانند زنجیرهٔ 20 (v0.6.8): توکن با عرضهٔ صفر آغاز میشود و فقط invokeهای همان برنامه آن را mint یا burn میکنند.
کیف پول شناسهٔ توکن را از طریق همین فهرست تعیین میکند، نه از طریق rand_getToken: دارایی یک انتقال روی زنجیره خصوصی است و خواندن کل رجیستری، فارغ از اینکه کدام توکن مدنظر باشد، هزینهٔ یکسانی دارد.
rand_getToken
پارامترها [token]: یک اندیس رجیستری (عدد یا رشتهٔ اعشاری)، شناسهٔ 64 رقمی هگزادسیمال (با 0x یا بدون آن، با هر حالت حروف) یا شکل متنیِ rpl1… (همه حروف کوچک یا همه حروف بزرگ). نتیجه: ردیف rand_getTokens همان توکن، یا null. شناسهٔ نادرست — جمع کنترلی غلط، HRP دیگر، طول نادرست، حروف مخلوط، غیرهگزادسیمال — خطای -32602 است، تا یک غلط تایپی هرگز به توکنی دیگر تبدیل نشود. جستوجوی تکی به node میفهماند که فراخواننده به کدام توکن اهمیت میدهد؛ این روش برای اکتشافگرها و خواندنهای یکباره است.
rand_getTokenSupply
پارامترها [token]، با همان شکلها. نتیجه null یا:
{ "total_supply": "600",
"backings": [{ "chain": 2, "token": "<32 bytes hex>", "decimals": 6, "locked": "600",
"mint_cap_per_day": "10000000000000", "minted_today": "1000", "mint_day": 20350 }] }
backings برای توکن بومی خالی است؛ برای توکن bridgeشده، مقادیر locked به total_supply جمع میشوند. همان نکتهٔ حریم خصوصیِ rand_getToken اینجا نیز صدق میکند.
تجمیع بلوک (در زنجیرهٔ 20 فعال نیست)
این روشها در node برای زنجیرههایی وجود دارند که genesis آنها بخش aggregation دارد. در زنجیرهٔ 20 رجیستر خالی است و هیچچیز هرگز unsealed نمیشود.
| روش | پارامترها | نتیجه |
|---|---|---|
rand_getAggregate | [hash] | covers، aggregator، subsidy، proving_share، n و height از تجمیعِ مهرکننده؛ برای هر تراکنش دیگر null |
rand_getAggregators | [] | رجیستر تجمیعکنندهها: address، bond، payout، nonce، unbonding برای هر ردیف |
rand_getUnsealed | [from, limit] | { "bundles": [{ "hash", "height", "excess" }], "next_from" }، دستههایی که یک تجمیعکننده هنوز میتواند پوشش دهد |
یک Aggregate مانند بقیه از طریق rand_sendTransaction ارسال میشود.
Vesting در genesis (در زنجیرهٔ 20 فعال نیست)
این روشها در node برای زنجیرههایی وجود دارند که genesis آنها بخش vesting دارد. هنوز هیچ زنجیرهای چنین بخشی ندارد: در زنجیرهٔ 20 هر یک { "enabled": false } پاسخ میدهد. نقطهٔ پایانی عمومی از 2026-10-01 آنها را عبور میدهد.
| روش | پارامترها | نتیجه |
|---|---|---|
rand_getVesting | [id] یا [id, at_ms]، شناسهٔ 64 رقمی هگزادسیمالِ ورودی | ورودی: کلاس، ذینفع، برنامه (amount، start_ms، cliff_ms، linear_ms، step_ms)، مقدار claimشده، revokeشده و bondشده، و vested_now، claimable_now و unvested_now در as_of_ms (بهطور پیشفرض زمان بلوک head)؛ برای شناسهٔ ناشناخته null. از v0.6.8، ورودیِ قابل revoke فهرست revokers، threshold لازم از آنها برای revoke و treasury که revoke به آن پرداخت میکند را نشان میدهد (اینها جایگزین revoker تکی میشوند)، و ورودی revoke_nonce و locked_now را نیز دارد |
rand_getVestingSummary | [] | { "enabled": true, "height", "as_of_ms", "entries", "issued", "released", "locked", "classes": [ … ] }: مجموع هر کلاس، بدون کلید یا مالک |
rand_getVestingSchedule | [from_ms, to_ms, step_ms]، حداکثر 1,000 نقطه | { "enabled": true, "issued", "points": [{ "t_ms", "locked" }] }: مجموع قفلشدهٔ رجیستر در طول زمان |
مقادیر رشتههای اعشاریاند. چهار اقدام vesting از طریق rand_sendTransaction ارسال میشوند.
اشتراکها (WebSocket)
ws://127.0.0.1:8545/ یا /ws. این سوکت فقط rand_subscribe و rand_unsubscribe را سرویس میدهد و به هر چیز دیگر با -32601 پاسخ میدهد. سه موضوع، جریانهای مستقل بدون هیچ تضمینی دربارهٔ ترتیب میان آنها:
newHeads— به شکلrand_getHead، یکبار برای هر بلوک commitشده و به ترتیب، از جمله هنگام همگامسازی ارسال میشود.viewدر اینجا view خود بلوک است.receiptsیاreceipts <program_id>— برای هر بلوک commitشده که دستکم یک رسید فراخوانیِ منطبق دارد، یک اعلان:{ "height", "hash", "receipts": [ … ] }، که هر رسید به شکلrand_getReceiptاست.transaction <hash>— یک اعلان، سپس node اشتراک را برمیدارد:{ "status": "committed", "height", "index" }، یا{ "status": "rejected", "reason" }برای ردی که به بایتهای خود تراکنش مربوط است (همان حدی کهrand_getTransactionStatusدارد). ردِ وابسته به وضعیت هرگز اعلام نمیشود، پس آن را با یک timeout همراه کنید.
{ "jsonrpc": "2.0", "id": 1, "method": "rand_subscribe", "params": ["newHeads"] }
{ "jsonrpc": "2.0", "id": 2, "method": "rand_unsubscribe", "params": ["1"] }
{ "jsonrpc": "2.0", "id": 3, "method": "rand_subscribe", "params": ["receipts", "<program_id>"] }
{ "jsonrpc": "2.0", "id": 4, "method": "rand_subscribe", "params": ["transaction", "<hash>"] }
{ "jsonrpc": "2.0", "id": 1, "result": "1" }
{ "jsonrpc": "2.0", "id": 2, "result": true }
{ "jsonrpc": "2.0", "method": "rand_subscription",
"params": { "subscription": "1", "result": { "height": 1998, "hash": "…", "view": 2251 } } }
حدود: 64 اتصال برای هر node (اتصال شصتوپنجم هنگام upgrade با 503 رد میشود)، 8 اشتراک برای هر اتصال، 64 KiB برای هر فریم کلاینت، یک ping در هر 30 s که باید ظرف 5 s پاسخ داده شود، و 256 مورد پسانباشت برای هر جریان — مشترکی که در جریانیِ مورد گوشدادنش بیشتر عقب بماند با کد 1008 بسته میشود و بافر نمیشود؛ دوباره متصل شوید و شکاف را با rand_getCompactBlocks (headها)، rand_getReceipts (رسیدها) یا rand_getTransactionStatus (یک تراکنش) پر کنید. یک GET / ساده بدون هدرهای upgrade با 400 پاسخ داده میشود.
خطاها
| کد | معنا |
|---|---|
-32601 | روش ناشناخته (از جمله روشهای بازنشستهٔ حساب) |
-32602 | پارامتر نامعتبر یا ناقص |
-32000 | رد شده: تراکنشی که mempool نپذیرفت، فراخوانی faucet که محدود نرخ شد، ساخت witness که بیش از 10 s منتظر ماند، خواندنی بیش از 30 s، روشی که شنوندهٔ عمومی سرویس نمیدهد، یا اشتراکی فراتر از سقف |
-32001 | شیء ارجاعشده یافت نشد |
-32010 | pruned: ارتفاعی پایینتر از کف نگهداری این node؛ data.floor آن را نام میبرد (پایین را ببینید) |
-32603 | خطای داخلی |
-32600 | درخواست نامعتبر: بدنه بیش از حد مجاز، غیر JSON، batch ناقص، یا یک notification |
{ "jsonrpc": "2.0", "id": 1, "error": { "code": -32000, "message": "…" } }
برای rand_sendTransaction، فقط -32000 و -32602 دربارهٔ تراکنش داوری میکنند؛ پس از هر کد دیگر، سرنوشت آن نامعلوم است (به rand_sendTransaction نگاه کنید).
nodeهای pruned: خطای -32010
nodeای که با --prune-history <window> راهاندازی شود کل دفتر کل (نوتها، nullifierها، anchorها، رجیستر) را نگه میدارد اما از بلوکها، تراکنشها و رسیدها فقط <window> آخر را؛ rand_status.prune_floor پایینترین ارتفاعی است که هنوز در اختیار دارد. در زنجیرهٔ 20، 24 از 26 validator با --prune-history 24h اجرا میشوند؛ دو آرشیو بدون این پرچم اجرا میشوند و هر بلوک را نگه میدارند، و نقطهٔ پایانی عمومی به یکی از آنها عبور میدهد.
- بر اساس ارتفاع، پایینتر از کف (بهجز genesis):
rand_getBlockByHeight،rand_getFinalityبر اساس ارتفاع، و بازهٔrand_getBlocks،rand_getCompactBlocksیاrand_getReceiptsکه به پایینتر از آن برسد، با-32010و پیامpruned: height h is below this node's retention floor fهمراه باdata: { "floor": f }پاسخ میدهند. از یک آرشیو بپرسید.[0, 0]همچنان genesis را سرویس میدهد. - بر اساس hash:
rand_getBlockByHash،rand_getReceipt،rand_getRawTransaction،rand_getCallEnvelopeوrand_getAggregateبرای hashِ prunedشدهnullپاسخ میدهند، مانند hashی که هرگز وجود نداشته؛ فقط یک آرشیو میتواند این دو را از هم تشخیص دهد.rand_getTransactionوrand_checkTransactionنیزnullپاسخ میدهند، و-32010فقط وقتی که ردیف مکانی باقی مانده باشد که ارتفاعی پایینتر از کف را نام ببرد.rand_getTransactionStatusدر nodeِ pruned به هر ورودیunknownفیلدfloorرا میافزاید. - اسکن کیف پول بیتأثیر است:
rand_getCommitments،rand_getNullifiers،rand_getAnchorو روشهای witness از خانوادههایی میخوانند که هرگز pruned نمیشوند.
تراکنش روی سیم
Transaction { chain_id: u64, bundle: Option<Bundle>, action: Action }
Bundle { // the hidden-asset bundle (since chain 14)
anchor: Word8, nullifiers: [Word8; 4], commitments: [Word8; 4],
fee: u64, burn_a: u64, burn_r: u64, burn_asset: u32, time: u32,
envelopes: [Envelope; 4], proof: Vec<u8>,
auth_commit: Word8, auth_proof: Vec<u8>, // since chain 17 (v0.6.3): split authorisation's c and
} // its proof; zeros and empty without hc_auth
Envelope { kem_ct: Vec<u8>, to_receiver: Vec<u8>, to_sender: Vec<u8>, body: Vec<u8> }
Action::None
Action::Mint { cm: Word8, pk: Word8, time: u32, r: Word8, envelope: Envelope, amount: u64,
minter: PublicKey, signature: Signature }
Action::Deploy { base_pc: u32, words: Vec<u32>, public: Vec<u32> }
Action::Call { program: Hash, proof: Vec<u8>, input_envelope: Option<CallEnvelope> }
Action::Bond { validator: Address, amount: u64, registration: Option<Registration> }
Action::Unbond { validator: Address, amount: u64, nonce: u64, signature: Signature }
Action::Withdraw { validator: Address, amount: u64, nonce: u64, time: u32, r: Word8,
envelope: Envelope, signature: Signature }
Action::BridgeAttest { attestation: Vec<u8>, recipient: ShieldedAddress, r: Word8, time: u32,
asset: u32, envelope: Envelope, pq_signatures: Vec<PqSignature> }
Action::BridgeBurn { asset: u32, amount: u64, relayer_fee: u64, to_chain: u16,
token: [u8; 32], to: [u8; 32] }
// the five aggregation variants sit here in the enum's declared order
Action::RegisterToken { name: String, symbol: String, decimals: u8, authority: MintAuthority,
initial: Option<InitialMint>, salt: [u8; 32], index: u32 }
Action::TokenMint { asset: u32, amount: u64, recipient: ShieldedAddress, r: Word8, time: u32,
envelope: Envelope, nonce: u64, signature: Signature }
Action::SetAuthority { asset: u32, new: Option<PublicKey>, nonce: u64, signature: Signature }
Action::TokenBurn { asset: u32, amount: u64 }
Action::PauseMints { nonce: u64, signature: Signature } // bundle-less, fee-less
Action::UnpauseMints { nonce: u64, pq_signatures: Vec<PqSignature> } // bundle-less
Action::RegisterBridgedToken { name: String, symbol: String, salt: [u8; 32], chain: u16,
token: [u8; 32], decimals: u8, nonce: u64,
pq_signatures: Vec<PqSignature> }
Action::ListBacking { token_index: u32, chain: u16, token: [u8; 32], decimals: u8, nonce: u64,
pq_signatures: Vec<PqSignature> }
Action::RotatePqGuardians { new_pq_guardians: Vec<PublicKey>, nonce: u64,
pq_signatures: Vec<PqSignature> } // bundle-less, fee-less
Action::RotatePauseKey { new_pause_key: PublicKey, nonce: u64,
pq_signatures: Vec<PqSignature> } // bundle-less, fee-less
// the four vesting variants (ClaimVested, RevokeVesting, BondVested, UnbondVested) follow, tags 24 to 27;
// since v0.6.8 RevokeVesting carries `signatures: Vec<RevokerSignature>` in place of one `signature`
Action::AdmitValidator { candidate: PublicKey, signatures: Vec<(PublicKey, Signature)> } // tag 28, v0.6.8
Action::SlashEquivocation { first: Box<SignedHeader>, second: Box<SignedHeader> } // tag 29
Action::RotatePqGuardiansV2 { new_pq_guardians: Vec<PublicKey>, possession: Vec<Vec<u8>>,
nonce: u64, pq_signatures: Vec<PqSignature> } // tag 30
Action::RotatePauseKeyV2 { new_pause_key: PublicKey, possession: Vec<u8>, nonce: u64,
pq_signatures: Vec<PqSignature> } // tag 31
Action::CancelRotation { kind: u8, nonce: u64, signature: Signature } // tag 32
Action::Invoke { program: Hash, proof: Vec<u8>, input_envelope: Option<CallEnvelope>,
transition: Transition } // tag 33, RPL-2
MintAuthority = None | Key(PublicKey) | Bridge { backings: Vec<Backing> } | Program(Hash)
InitialMint { amount: u64, recipient: ShieldedAddress, r: Word8, time: u32, envelope: Envelope }
Transition { reads: Vec<Cell>, writes: Vec<Cell>, inflow: Inflow, pays: Vec<Payout>, mints: Vec<Payout> }
Cell { key: Word8, value: Word8 } // keys strictly ascending in each list
Inflow = None | Deposit | Burn // what the bundle's burn_a of burn_asset is to the program
Payout { asset: u32, amount: u64, recipient: ShieldedAddress, r: Word8, envelope: Envelope }
Registration { public_key: PublicKey, payout: ShieldedAddress, signature: Signature }
CallEnvelope { kem_ct: Vec<u8>, to_sender: Vec<u8>, to_auditor: Vec<u8>, body: Vec<u8> }
PqSignature { index: u8, signature: Vec<u8> } // one guardian's Dilithium2 co-signature, by set index
پیکربندی پیشفرض bincode: اعداد صحیح با عرض ثابت، پیشوند طول 8 بایتی، و برچسبهای enum از نوع u32 به ترتیب اعلان. پنج variant تجمیع در enum پس از BridgeBurn و پیش از RegisterToken میآیند (تراکنشها); زنجیرهٔ 20 هرگز آنها را نمیپذیرد، و چهار variant مربوط به vesting و SlashEquivocation را هم نه، اما رمزگذاری که شمارهٔ برچسبها را ثابت در کد مینویسد باید آنها را هم بشمارد.
دو فیلد آخر bundle با v0.6.3 و زنجیرهٔ 17 آمدند. bincode موقعیتی است، پس رمزگذاری که برای زنجیرهٔ 16 یا قبلتر نوشته شده باشد تراکنشی تولید نمیکند که این زنجیره آن را رمزگشایی کند، و شناسهٔ هر تراکنش هم با آنها تغییر کرد: دامنهٔ شناسه اکنون rand-txid-3 است که auth_commit و digest اثبات auth را در بر میگیرد. کلاینتی که شناسهها را محلی بازمحاسبه میکند باید با آن همراه شود. در زنجیرهٔ 20 هر bundle یک اثبات auth دارد، چه خوداثباتشده و چه واگذارشده. v0.6.8 چیزی در چیدمان Transaction یا Bundle تغییر نمیدهد؛ اقدامهای 28 تا 33 را میافزاید.
هر تراکنش حداکثر یک بسته (bundle) حمل میکند. تراکنش Bond بستهای حمل میکند که در آن burn_r برابر با amount است و burn_a و burn_asset صفر هستند. تراکنشهای BridgeBurn و TokenBurn از طریق بسته میسوزانند: burn_asset باید همان asset اکشن باشد (هرگز 0 نباشد)، burn_a برابر با amount اکشن، و burn_r برابر با 0 باشد، در حالی که fee به RAND از اسلاتهای 2–3 پرداخت میشود. هر اکشن دیگری هیچ توکنی نمیسوزاند، و RAND همیشه فقط از طریق burn_r سوزانده میشود: بستهای که burn_asset آن 0 و burn_a آن غیرصفر باشد در همهجا رد میشود. مقدار r در BridgeAttest محاسبه میشود و قابل انتخاب نیست: پذیرش آن مستلزم blake3("rand-deposit-r-1" ‖ mu) است، روی همان چکیدهای که نگهبانان امضا کردهاند، و هر مقدار دیگری را رد میکند (WrongDepositBlinding، یک رد دائمی). یک توکن پلشده باید پیش از آنکه هر گواهیای از آن قابل پذیرش باشد فهرست شده باشد — در genesis، یا با RegisterBridgedToken / ListBacking؛ گواهی یک سکهی فهرستنشده با UnlistedToken رد میشود.
هر اثبات بسته روی تراکنشی که در آن قرار دارد ساخته و در برابر همان تأیید میشود: کل تراکنش با اثباتهای تهیشده، که با برچسبهای تازه به شناسهی زنجیره و، در زنجیرهی 20 (binding_domain: 1)، به هش genesis نیز پیوند خورده است. در زنجیرههای 14 تا 19 پیوند تنها شناسهی زنجیره بود، بنابراین اثباتی که برای زنجیرهی 19 ساخته شده باشد در زنجیرهی 20 تأیید نمیشود، و کیف پولی قدیمیتر از v0.6.8 نمیتواند در آنجا ارسال کند. در زنجیرههای 18 تا 20 یک بسته بدون دو اثباتش در 7,936 بایت کدگذاری میشود و یک تراکنش انتقال بدون آنها در 7,949 بایت (در زنجیرههای 14 تا 16 این مقادیر 5,848 و 5,861 بود، با پاکتهای 1,348 بایتی و بدون فیلدهای احراز). یک انتقال روی شبکه در پروفایل تولیدی حدود 2.85 MB است که تقریباً همهی آن اثبات است: یک اثبات بسته حدود 1.49 MB و یک اثبات احراز حدود 1.36 MB. پیش از احراز مجوز تفکیکشده حدود 1.43 MB بود.