ایک امانت دار پر ہر صارف کا ایک بیلنس واجب الادا ہے۔ یہ پروگرام ثابت کرتا ہے کہ ان بیلنسوں کا مجموعہ اس ذخائر کے عدد سے زیادہ نہیں جو امانت دار نے شائع کیا ہے، اور اس کے لیے نہ کوئی ایک بیلنس شائع کیا جاتا ہے نہ مجموعہ۔ ہر صارف Python کی چند سطروں سے، کسی خاص ٹول کے بغیر، جانچ سکتا ہے کہ اس کا اپنا بیلنس شمار کیا گیا۔
مثالی پروگرام میں وہ تیاری درج ہے جو چاروں مثالی صفحات میں مشترک ہے۔
1. یہ کیا ثابت کرتا ہے
امانت دار ایک مرکل مجموعی درخت بناتا ہے۔ ایک پتّا ایک کھاتہ ہے: صارف کی شناخت اور بیلنس کا ہیش، اور اس کے ساتھ بیلنس۔ ایک نوڈ اپنے دو بچوں اور ان کے مجموعوں کا ہیش ہے، اور اس کے ساتھ دونوں مجموعوں کا حاصلِ جمع۔ چنانچہ جڑ اپنے نیچے کے ہر بیلنس کا کُل اٹھائے ہوتی ہے۔
درخت پروگرام کے اندر کھاتوں کی نجی فہرست سے بنایا جاتا ہے۔ کال یہ ثابت کرتی ہے:
- رسید میں شائع شدہ جڑ ان کھاتوں پر بنے مجموعی درخت کی جڑ ہے جو امانت دار نے فراہم کیے؛
- اس میں ہر مجموعہ اپنے نیچے کے دو مجموعوں کا درست حاصلِ جمع ہے، کسی اوورفلو کے بغیر؛
- جڑ پر کُل رقم ڈیپلائے کے وقت مقرر کردہ ذخائر کے عدد کے برابر یا اس سے کم ہے۔
نکتہ 2 وہ چیز ہے جو ثبوت کے بغیر شائع کیا گیا مجموعی درخت فراہم نہیں کر سکتا۔ سادہ مجموعی درخت پر معروف حملہ یہ ہے کہ امانت دار کسی والد کا مجموعہ اس کے بچوں کے مجموعے سے کم لکھ دے، جسے کوئی صارف کسی ایک راستے سے نہیں پکڑ سکتا۔ یہاں مجموعے پروگرام خود نکالتا ہے، اور کسی دوسری حساب کاری کا ثبوت وجود ہی نہیں رکھتا۔
ثبوت جس چیز کا احاطہ نہیں کرتا وہ مکمل ہونا ہے: کون سے کھاتے شامل ہوں، یہ امانت دار طے کرتا ہے۔ یہ خلا صارفین پُر کرتے ہیں۔ ہر صارف جانچتا ہے کہ اس کی شناخت اور اس کے بیلنس والا پتّا شائع شدہ جڑ کے نیچے موجود ہے (حصہ 7)۔ چھوڑا گیا کھاتہ اس کا مالک پکڑ لیتا ہے۔
2. انٹرفیس
| عوامی لفظ | مطلب |
|---|---|
| 0, 1 | ذخائر کا عدد، اثاثے کی سب سے چھوٹی اکائیوں میں ایک u64، پہلے نچلا لفظ پھر اونچا |
| 2 | اسنیپ شاٹ کا لیبل؛ پروگرام اسے نہیں پڑھتا، مگر پروگرام کی شناخت اسے پابند کرتی ہے |
| نجی لفظ | مطلب |
|---|---|
| 0 | کھاتوں کی تعداد n، زیادہ سے زیادہ 32 |
| پھر، ہر کھاتے کے لیے | شناخت (16 بائٹ، چار بگ-اینڈین الفاظ کی صورت میں)، بیلنس کا نچلا لفظ، بیلنس کا اونچا لفظ |
| آؤٹ پٹ خانہ | مطلب |
|---|---|
| 0 | حالت: 1 احاطہ شدہ، 2 احاطہ شدہ نہیں، 3 32 سے زیادہ کھاتے، 4 کسی مجموعے میں اوورفلو |
| 1 | n |
| 2 تا 6 | جڑ کے ہیش کے پہلے 20 بائٹ، پانچ بگ-اینڈین الفاظ کی صورت میں |
| 7 | غیر مستعمل؛ Rust کا panic یہاں 0xdeadbeef لکھتا ہے |
ذخائر کا عدد آؤٹ پٹ میں نہیں بلکہ عوامی حصے میں ہے، اور اس کی دو وجوہ ہیں۔ جگہ نہیں ہے: حالت، تعداد اور 160 بٹ کی جڑ خانے بھر دیتے ہیں۔ اور یہ دعویٰ ثبوت کے وجود سے پہلے بیان کر دیتا ہے: پروگرام کا ڈیپلائے “ذخائر R، اسنیپ شاٹ S” شائع کرتا ہے، اور پھر کال یا تو ثابت کرتی ہے کہ بیلنس R کے اندر سما جاتے ہیں یا حالت 2 لوٹاتی ہے۔
ہیش، بالکل درست صورت میں:
leaf = SHA-256( be32(0) ‖ id (16 bytes) ‖ be64(balance) ) 28 bytes
node = SHA-256( be32(1) ‖ left hash ‖ be64(left sum) ‖ right hash ‖ be64(right sum) ) 84 bytes
empty = leaf with id 0 and balance 0
درخت میں ہمیشہ 32 پتّے ہوتے ہیں۔ کھاتے اسے بائیں جانب سے بھرتے ہیں اور باقی جگہ خالی پتّے بھرتے ہیں۔ شروع کا 0 اور 1 اس بات کو یقینی بناتے ہیں کہ کوئی پتّا کبھی نوڈ کے طور پر نہ پڑھا جائے۔
بائٹ کی ترتیب۔ SHA-256 شروع سے آخر تک بگ-اینڈین ہے، اور SHA256 سسٹم کال اپنا 64 بائٹ کا بلاک سولہ بگ-اینڈین الفاظ کی صورت میں لیتی ہے۔ اس لیے یہ پروگرام شناخت کو چار بگ-اینڈین الفاظ کے طور پر پڑھتا ہے اور جڑ کو بگ-اینڈین الفاظ کے طور پر شائع کرتا ہے: hex میں چھپا ہوا آؤٹ پٹ 2 جڑ کے پہلے آٹھ hex ہندسے ہیں۔ یہ Keccak پروگرام کے برعکس طریقہ ہے، کیونکہ دونوں ہیش الٹی بائٹ ترتیب پر متعین ہیں۔
3. گیسٹ
my-guests/solvency/src/main.rs، مکمل:
#![no_std]
#![no_main]
use guest_sdk::{halt, read_input, read_public, sha256_compress, write_output};
/// The tree always has 32 leaves. Accounts fill it from the left; the rest are empty leaves.
const LEAVES: usize = 32;
const SOLVENT: u32 = 1;
const INSOLVENT: u32 = 2;
const TOO_MANY: u32 = 3;
const OVERFLOW: u32 = 4;
const LEAF_TAG: u32 = 0;
const NODE_TAG: u32 = 1;
/// SHA-256's initial state (FIPS 180-4 §5.3.3).
const IV: [u32; 8] = [
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
];
#[derive(Clone, Copy)]
struct Node {
hash: [u32; 8],
sum: u64,
}
/// SHA-256 of the 28 bytes `be32(0) ‖ id (16 bytes) ‖ be64(balance)`. The message, its `0x80`
/// terminator and its bit length fit one 64-byte block, so a leaf is one compression.
fn leaf(id: &[u32; 4], balance: u64) -> Node {
let mut buf = [0u32; 24];
buf[0] = LEAF_TAG;
buf[1..5].copy_from_slice(id);
buf[5] = (balance >> 32) as u32;
buf[6] = balance as u32;
buf[7] = 0x8000_0000;
buf[15] = 28 * 8;
buf[16..].copy_from_slice(&IV);
sha256_compress(&mut buf);
let mut hash = [0u32; 8];
hash.copy_from_slice(&buf[16..]);
Node { hash, sum: balance }
}
/// SHA-256 of the 84 bytes `be32(1) ‖ left hash ‖ be64(left sum) ‖ right hash ‖ be64(right sum)`:
/// two compressions. `None` when the two sums do not fit a u64.
fn parent(l: &Node, r: &Node) -> Option<Node> {
let sum = l.sum.checked_add(r.sum)?;
let mut buf = [0u32; 24];
buf[16..].copy_from_slice(&IV);
// Block 1: words 0..16 of the message.
buf[0] = NODE_TAG;
buf[1..9].copy_from_slice(&l.hash);
buf[9] = (l.sum >> 32) as u32;
buf[10] = l.sum as u32;
buf[11..16].copy_from_slice(&r.hash[..5]);
sha256_compress(&mut buf);
// Block 2: the last five words, the terminator, zeros, the bit length.
buf[..3].copy_from_slice(&r.hash[5..]);
buf[3] = (r.sum >> 32) as u32;
buf[4] = r.sum as u32;
buf[5] = 0x8000_0000;
buf[6..15].fill(0);
buf[15] = 84 * 8;
sha256_compress(&mut buf);
let mut hash = [0u32; 8];
hash.copy_from_slice(&buf[16..]);
Some(Node { hash, sum })
}
/// Public segment, fixed at deploy: [reserves low word, reserves high word, snapshot label].
/// Private input: [n, then n accounts of (id: 4 words, balance low, balance high)].
/// Outputs: [status, n, root (first 5 words), 0].
#[no_mangle]
pub extern "C" fn main() -> ! {
let reserves = read_public(0) as u64 | (read_public(1) as u64) << 32;
let n = read_input(0) as usize;
if n > LEAVES {
write_output(0, TOO_MANY);
halt();
}
let empty = leaf(&[0; 4], 0);
let mut row = [empty; LEAVES];
for (i, slot) in row.iter_mut().enumerate().take(n) {
let at = 1 + 6 * i as u32;
let id = [read_input(at), read_input(at + 1), read_input(at + 2), read_input(at + 3)];
let balance = read_input(at + 4) as u64 | (read_input(at + 5) as u64) << 32;
*slot = leaf(&id, balance);
}
// Fold the row in place, a level at a time, until one node is left.
let mut width = LEAVES;
while width > 1 {
width /= 2;
for i in 0..width {
match parent(&row[2 * i], &row[2 * i + 1]) {
Some(p) => row[i] = p,
None => {
write_output(0, OVERFLOW);
halt();
}
}
}
}
let root = row[0];
write_output(0, if root.sum <= reserves { SOLVENT } else { INSOLVENT });
write_output(1, n as u32);
for k in 0..5 {
write_output(2 + k as u32, root.hash[k]);
}
halt();
}
پیڈنگ ہاتھ سے لکھی گئی ہے۔ guest_sdk::sha256 کوئی بھی بائٹ سٹرنگ لیتا ہے اور اسے ایک ایک بائٹ کر کے نقل کرتا ہے۔ یہاں ہر پیغام معلوم لمبائی کے پورے الفاظ پر مشتمل ہے، اس لیے پروگرام 16 الفاظ کا بلاک براہِ راست بھرتا ہے: پیغام کے الفاظ، پھر 0x80000000، صفر، اور آخری لفظ میں بٹ کی لمبائی۔ ایک پتّا ایک کمپریشن ہے۔ نوڈ کے 84 بائٹ دوسرے بلاک میں چلے جاتے ہیں، اس لیے ایک نوڈ دو کمپریشن ہے۔
بیلنس u64 ہیں اور مجموعے جانچے جاتے ہیں۔ بیلنس منفی نہیں ہو سکتا کیونکہ اس قسم میں منفی قدریں ہیں ہی نہیں، اور اس سے کُل کو گھٹانے کا دوسرا کلاسیکی طریقہ ختم ہو جاتا ہے۔ checked_add اوورفلو کو لپٹے ہوئے مجموعے کے بجائے حالت 4 میں بدل دیتا ہے۔
دیوالیہ نتیجہ بھی ایک نتیجہ ہے۔ حالت 2 ایک عام اختتام ہے جس میں جڑ شائع ہوتی ہے۔ امانت دار ایسے بیلنسوں کے لیے جو ذخائر کے عدد سے بڑھ جائیں حالت 1 کی رسید حاصل نہیں کر سکتا، اور حالت 2 کی رسید ٹھیک اسی بات کا ثبوت ہے۔
4. میزبان کی جانب
solvency.py صرف Python کی معیاری لائبریری استعمال کرتا ہے:
solvency.py setup <accounts.csv> <reserves> <snapshot label> writes public.txt, prints the root
solvency.py witness <accounts.csv> prints the private words
solvency.py path <accounts.csv> <row> prints that account's inclusion proof (JSON)
solvency.py verify <proof.json> <root prefix hex> checks a proof against a receipt's root
اس میں موجود دو ہیش وہ پوری تفصیل ہیں جس کی صارف کو ضرورت ہے:
def leaf(ident: bytes, balance: int):
return hashlib.sha256(struct.pack(">I", 0) + ident + struct.pack(">Q", balance)).digest(), balance
def parent(l, r):
h = hashlib.sha256(struct.pack(">I", 1) + l[0] + struct.pack(">Q", l[1]) + r[0] + struct.pack(">Q", r[1]))
return h.digest(), l[1] + r[1]
ڈیمو میں demo-accounts.csv کے اندر بارہ کھاتے ہیں، ہر سطر میں ایک id,balance، اور بیلنس 10⁻⁸ کی اکائیوں میں ہیں (وہ درستی جو zUSD جیسا برج شدہ ٹوکن استعمال کرتا ہے)۔ ان کا کُل 100,215.185678 ہے۔ امانت دار 101,000 کے ذخائر کا دعویٰ کرتا ہے:
$ python3 solvency.py setup demo-accounts.csv 10100000000000 20260930
root 46b78564d60f75bdc9552d8ad1c4aadf411354054be3ffb80337b8549471a82c
root prefix 46b78564d60f75bdc9552d8ad1c4aadf41135405
root words 1186432356 3591337405 3377802634 3519326943 1091785733
liabilities 10021518567800
wrote public.txt
$ cat public.txt
2531887104 2351 20260930
2351 × 2³² + 2531887104 کا حاصل 10,100,000,000,000 ہے۔ liabilities والی سطر امانت دار کا اپنا منظر ہے۔ یہ کبھی شائع نہیں ہوتی۔
شناختیں منفرد اور ناقابلِ قیاس ہونی چاہییں۔ اگر ایک جیسے بیلنس والے دو صارفین کو ایک ہی پتّا دیا جائے تو امانت دار دونوں کے لیے ایک ہی واجب شمار کر سکتا ہے۔ ایسی شناخت جسے صرف اس کا صارف اپنی پہچان سکے اس کا سدِباب کرتی ہے، اور ایسی شناخت جس کا قیاس نہ کیا جا سکے اس صارف کو روکتی ہے جو ہمسایہ پتّے کا ہیش دیکھ کر ہمسائے کے بیلنس کے اندازے آزمانا چاہے۔ ڈیمو ایک ہیش کے پہلے 16 بائٹ استعمال کرتا ہے۔ حقیقی تنصیب شناخت کو صارف کے کھاتے اور ہر اسنیپ شاٹ کے الگ nonce سے اخذ کرے گی اور صارف کو دکھائے گی۔
5. بلڈ اور رن
$ rand-guest build my-guests/solvency --max-words 65535
994 words against a cap of 65535 (fits); 0 ecall(s) with a non-static a7
OK
wrote my-guests/solvency/image.bin and its .sha256 (994 words, hc 5559791a05bd9269bf7fc4e893c05e8b21defe5ef966d831b49ea463fb4552d3, program id 697412b5db65647164c21b27e4b4feb0b5f0b9fce2381157cd0786bfecf1769f)
$ cd my-guests/solvency
$ python3 solvency.py witness demo-accounts.csv > witness.txt
$ rand-guest run image.bin --public $(cat public.txt) --input $(cat witness.txt) --tier 14
out[0] = 1
out[1] = 12
out[2] = 1186432356
out[3] = 3591337405
out[4] = 3377802634
out[5] = 3519326943
out[6] = 1091785733
out[7] = 0
cycles 7492
tier 14
tier 14: fits (cycles 7762 of 16383, Poseidon2 permutations 270 of 2048)
حالت 1، بارہ کھاتے، اور جڑ کے وہی پانچ الفاظ جو اسکرپٹ نے چھاپے تھے۔ وٹنس 73 الفاظ کا ہے: تعداد، اور ہر کھاتے کے چھ۔
ذخائر کا عدد 100 اکائیوں تک گھٹانے پر (--public 100 0 1) وہی کھاتے out[0] = 2 دیتے ہیں۔ 33 کی تعداد out[0] = 3 دیتی ہے۔ ایسے دو کھاتے جن کے بیلنس مل کر 2⁶⁴ سے بڑھ جائیں out[0] = 4 دیتے ہیں۔
6. بجٹ
| 12 کھاتے | 32 کھاتے | |
|---|---|---|
| نجی الفاظ | 73 | 193 |
| سائیکل | 7,492 | 10,681 |
| SHA-256 کمپریشن | 75 | 95 |
| درجہ | 14 | 14 |
کمپریشن کی تعداد یوں ہے: n پتّے، ایک خالی پتّا (ایک بار نکال کر نقل کیا جاتا ہے)، اور 31 نوڈز میں سے ہر ایک کے دو۔ ایک کال زیادہ سے زیادہ 128 کمپریشن استعمال کر سکتی ہے، اور درجہ 14 وہ بلند ترین درجہ ہے جو کال استعمال کر سکتی ہے، اس لیے اس ڈیزائن میں 32 کھاتے اس حد کے قریب ہیں جو ایک کال ثابت کر سکتی ہے۔ 64 پتّوں کے درخت کو 190 کمپریشن درکار ہیں اور وہ نہیں سماتا۔
یہ ایک نمائشی حجم ہے۔ اس سے آگے جانے کا مطلب ہے درخت کو کئی کالوں میں تقسیم کرنا اور ہر ذیلی درخت کی جڑ اور مجموعے کا commitment ایک آخری کال تک لے جانا، وہی طریقہ جو پروگرام لکھیں بجٹ سے بڑے کسی بھی کام کے لیے بیان کرتا ہے۔ یہ مثال ایسا نہیں کرتی۔
چین 18 سے ایک کمپریشن کی قیمت 64 گیس ہے، جبکہ عام سائیکل کی 1۔ والیٹ کسی رن کی درست گیس اور اس کی اعلان کردہ حد چھاپتا ہے:
gas: 12489 (declaring 16384, tier 14)
ہر قطار 1 گیس کی ہے اور ایک کمپریشن 63 مزید کا: 7,764 قطاریں جمع 75 × 63 برابر 12,489۔ گیس کا ایک تہائی سے زیادہ ہیشنگ پر صرف ہوتا ہے۔ (والیٹ rand-guest run سے دو قطاریں زیادہ گنتا ہے، اس ٹرانزیکشن بائنڈنگ کی وجہ سے جو چین 18 کال کے عوامی حصے میں شامل کرتی ہے۔)
7. صارف کی جانچ
امانت دار ہر صارف کو اس کا راستہ دیتا ہے: پانچوں سطحوں میں سے ہر ایک پر ہمسایہ ہیش اور ہمسایہ مجموعہ۔
$ python3 solvency.py path demo-accounts.csv 6 > proof6.json
$ head -12 proof6.json
{
"id": "f8f4e4a0c855aad0d0f9ae5bab108333",
"balance": 1820025000000,
"path": [
{
"hash": "e39eaaabec5cca1fe4c76ce656692be631a39e807876f93bdd7baf8b057d6997",
"sum": 6600000000,
"sibling_is_left": false
},
{
"hash": "4732f069886c966e6429ee9063f73429bf153eb2575cf2a28f00f27b7d0d89c6",
"sum": 31500000000,
صارف اپنی شناخت اور اپنے بیلنس سے جڑ دوبارہ نکالتا ہے اور اس کے پہلے 20 بائٹ کا موازنہ رسید کے آؤٹ پٹ 2 تا 6 سے کرتا ہے:
$ python3 solvency.py verify proof6.json 46b78564d60f75bdc9552d8ad1c4aadf41135405
root prefix 46b78564d60f75bdc9552d8ad1c4aadf41135405 MATCH
درخت میں موجود بیلنس سے ایک اکائی زیادہ بیلنس کا راستہ جڑ تک نہیں پہنچتا:
$ python3 solvency.py verify tampered.json 46b78564d60f75bdc9552d8ad1c4aadf41135405
root prefix e9a1b4cbe49e412214b97afe73348fa7c555fa7a DOES NOT MATCH
پوری جانچ یہی ہے کہ اوپر کے leaf اور parent فنکشن پانچ بار لگائے جائیں۔ جو صارف امانت دار کا اسکرپٹ نہیں چلانا چاہتا وہ اسے خود لکھ سکتا ہے۔
راستہ صارف کو اس کے ہمسایوں کے مجموعے دکھاتا ہے۔ اوپر والے راستے کا پہلا قدم ظاہر کرتا ہے کہ ہمسایہ پتّے میں 6,600,000,000 اکائیاں ہیں، اور ہر اوپری قدم کسی ذیلی درخت کا کُل ظاہر کرتا ہے۔ یہ سادہ مجموعی درخت کی فطرت میں شامل ہے۔ ہر اسنیپ شاٹ پر پتّوں کی ترتیب بدلنا اس چیز کو محدود کرتا ہے جو صارف وقت کے ساتھ جان سکتا ہے، اور مجموعوں کو مکمل طور پر چھپانے کے لیے سادہ اعداد کی جگہ commitments درکار ہیں، جو یہ مثال نہیں کرتی۔
8. ڈیپلائے
$ rand fee deploy 994 --public-words 3
0.1007 RAND
$ rand program deploy image.bin --public public.txt
program id: fce8474dfdf80b9733e04fb72d4d8d19c40ba5ab646b3d867322daf4b9b599c0 (994 words, hc 1a7959556992bd05e8c47fbf8b5ec0935efede2131d866f963a49eb4d35245fb, public input 3 words, digest 70d5ae8935d646f7a0dd426c30aaf68e9bc382534d8a6ced90e363e129403608)
proving the spend authorisation on this machine (tier 10; seconds)…
authorisation proved in 6.8s: tier 10, 1368908 bytes
proving the bundle (tier 14; about a minute and a half on a laptop)…
proved in 116.7s: tier 14, 1500710 bytes
submitted deploy 39e8f35e0bdc7bc105ce942dc492b52f7a5efbb682ab6ebecc17cb310a161ada
0 RAND out, 59.8545 RAND change, fee 0.1007 RAND, anchored at height 97831, proved in 116.7s (bundle) + 6.8s (auth)
پروگرام کی شناخت ذخائر کے عدد اور اسنیپ شاٹ کے لیبل کو کوڈ کے ساتھ پابند کرتی ہے۔ نیا اسنیپ شاٹ ایک نیا ڈیپلائے ہے، جس کی قیمت تقریباً ایک RAND کا دسواں حصہ ہے، اور اس کی شناخت نئے دعوے کا عوامی بیان ہے۔
9. کال
$ rand call fce8474dfdf80b9733e04fb72d4d8d19c40ba5ab646b3d867322daf4b9b599c0 \
$(sed 's/[0-9][0-9]*/--input &/g' witness.txt)
proving the call locally (73 inputs stay private, over the program's 3-word public input)…
gas: 12489 (declaring 16384, tier 14)
fee 0.007487437 RAND (incl. two price steps of headroom)
proved in 122.9s: tier 14, 1911152 bytes, outputs [1, 12, 1186432356, 3591337405, 3377802634, 3519326943, 1091785733, 0]
proving the spend authorisation on this machine (tier 10; seconds)…
authorisation proved in 6.8s: tier 10, 1375371 bytes
proving the bundle (tier 14; about a minute and a half on a laptop)…
proved in 111.9s: tier 14, 1500198 bytes
submitted call 5d276bf7cb65cfcd2244ffd05baceaf6cb8082aeed6129a5e87e8737b3374e17
0 RAND out, 59.709221126 RAND change, fee 0.007487437 RAND, anchored at height 98336, proved in 111.9s (bundle) + 6.8s (auth)
{
"h_in": "b151f38fbbefd08c9f36e65da89f016ba7fc0ccdb52bddda6544e3d86372d331",
"h_pub": "70d5ae8935d646f7a0dd426c30aaf68e9bc382534d8a6ced90e363e129403608",
"height": 98574,
"index": 0,
"outputs": [
1,
12,
1186432356,
3591337405,
3377802634,
3519326943,
1091785733,
0
],
"program": "fce8474dfdf80b9733e04fb72d4d8d19c40ba5ab646b3d867322daf4b9b599c0",
"tier": 14,
"tx": "5d276bf7cb65cfcd2244ffd05baceaf6cb8082aeed6129a5e87e8737b3374e17"
}
input transcript published; open it with `rand open-call 5d276bf7cb65cfcd2244ffd05baceaf6cb8082aeed6129a5e87e8737b3374e17`
حالت 1، بارہ کھاتے، اور hex میں جڑ 46b78564 d60f75bd c9552d8a d1c4aadf 41135405۔ ٹرانزیکشن میں کہیں بھی نہ کوئی بیلنس بیان ہوا ہے نہ کُل رقم۔
یہ tier-14 کال ہے، اس لیے کال پروف سست حصہ ہے: 123 s، پھر خرچ کی اجازت کے لیے 7 s اور بنڈل کے لیے 112 s، کل ملا کر پانچ منٹ، اور زیادہ سے زیادہ میموری 6.6 GB۔ پروف 1,911,152 بائٹس کا ہے۔ اس میں سے تقریباً 0.4 MB حصہ SHA-256 ٹیبل کا ہے۔
10. خود جانچیں
- دعویٰ۔ پروگرام id پر
rand_getProgramPublicریزرو کی رقم اور لیبل واپس کرتا ہے۔ کسٹوڈین کے پاس واقعی اتنا ریزرو ہے یا نہیں، یہ اس پروف کے دائرے سے باہر ہے: یہ آن چین بیلنس، آڈیٹر کے خط، یا برج شدہ اثاثے کی صورت میں خود چین کےrand_getTokenSupplyسے ثابت ہوتا ہے۔ - کوڈ۔
my-guests/solvencyکو اسی circuits کمٹ پر دوبارہ بنائیں اورhcکا پروگرام کےcode_hashسے موازنہ کریں۔ - رسید۔ اسٹیٹس
1، سلاٹ 7 کی قدر3735928559نہ ہو، اورprogramاس id کے برابر ہو۔ آؤٹ پٹ 2 تا 6 وہ روٹ ہیں جس سے ہر صارف اپنی جانچ کا موازنہ کرتا ہے۔ - آپ کا اپنا لیف، جیسا کہ سیکشن 7 میں ہے۔
کوئی بھی ڈیمو اکاؤنٹس کے ساتھ یہ کال دہرا سکتا ہے، یا کوئی بیلنس بدل کر روٹ کو بدلتے دیکھ سکتا ہے۔
پروف آپ کو کیا نہیں دیتا
- خود ریزرو۔ پروف ایک عدد کے مقابلے میں واجبات کا ہے۔ اس عدد کے لیے الگ ثبوت درکار ہے۔
- صارفین کے بغیر مکمل ہونا۔ جو اکاؤنٹ کسٹوڈین نے چھوڑ دیا ہو، اس کا پتا صرف وہی صارف لگا سکتا ہے جس کا وہ اکاؤنٹ ہے۔ جتنے زیادہ صارفین جانچیں گے، اتنی ہی کم گنجائش رہے گی۔
- ایسا وقت جو ریزرو کے وقت سے مطابقت رکھتا ہو۔ کسٹوڈین اسنیپ شاٹ کے ایک گھنٹے کے لیے فنڈز ادھار لے سکتا ہے۔ غیر اعلانیہ اوقات پر بار بار لیے گئے اسنیپ شاٹ اس گنجائش کو کم کر دیتے ہیں۔
- پوشیدہ پڑوسی۔ کسی صارف کا راستہ ساتھی شاخوں کے مجموعے ظاہر کرتا ہے (سیکشن 7)۔
- ایک کال میں 32 سے زیادہ اکاؤنٹس۔ دیکھیں بجٹ۔