---
title: "مرکل پیٹریشیا ٹرائی"
description: "مرکل پیٹریشیا ٹرائی کا تعارف۔"
lang: ur
sidebarDepth: 2
---

[ایتھیریم](/) کی حالت (تمام اکاؤنٹس، بیلنسز، اور سمارٹ کنٹریکٹس کا مجموعہ)، ڈیٹا سٹرکچر کے ایک خاص ورژن میں انکوڈ کی جاتی ہے جسے کمپیوٹر سائنس میں عام طور پر مرکل ٹری کے نام سے جانا جاتا ہے۔ یہ ساخت علمِ تشفیر میں بہت سی ایپلی کیشنز کے لیے مفید ہے کیونکہ یہ ٹری میں الجھے ہوئے ڈیٹا کے تمام انفرادی ٹکڑوں کے درمیان ایک قابلِ تصدیق تعلق پیدا کرتی ہے، جس کے نتیجے میں ایک واحد **روٹ** (root) ویلیو حاصل ہوتی ہے جسے ڈیٹا کے بارے میں چیزیں ثابت کرنے کے لیے استعمال کیا جا سکتا ہے۔

ایتھیریم کا ڈیٹا سٹرکچر ایک 'ترمیم شدہ مرکل پیٹریشیا ٹرائی' ہے، اس کا نام اس لیے رکھا گیا ہے کیونکہ یہ <span dir="ltr">PATRICIA (the Practical Algorithm To Retrieve Information Coded in Alphanumeric)</span> کی کچھ خصوصیات مستعار لیتا ہے، اور اس لیے کہ اسے ان آئٹمز کی موثر ڈیٹا بازیافت (re**trie**val) کے لیے ڈیزائن کیا گیا ہے جو ایتھیریم کی حالت پر مشتمل ہیں۔

ایک مرکل پیٹریشیا ٹرائی حتمی اور تشفیری طور پر قابلِ تصدیق ہے: حالت کا روٹ بنانے کا واحد طریقہ اسے حالت کے ہر انفرادی ٹکڑے سے شمار کرنا ہے، اور دو حالتیں جو ایک جیسی ہیں انہیں روٹ ہیش اور ان ہیشز کا موازنہ کر کے آسانی سے ثابت کیا جا سکتا ہے جو اس تک لے گئے (_ایک مرکل ثبوت_)۔ اس کے برعکس، ایک ہی روٹ ہیش کے ساتھ دو مختلف حالتیں بنانے کا کوئی طریقہ نہیں ہے، اور مختلف اقدار کے ساتھ حالت میں ترمیم کرنے کی کوئی بھی کوشش ایک مختلف حالت کے روٹ ہیش کا نتیجہ دے گی۔ نظریاتی طور پر، یہ ساخت داخل کرنے (inserts)، تلاش کرنے (lookups) اور حذف کرنے (deletes) کے لیے `O(log(n))` کارکردگی کا 'ہولی گریل' (holy grail) فراہم کرتی ہے۔

مستقبل قریب میں، ایتھیریم کا ایک [ورکل ٹری (Verkle Tree)](/roadmap/verkle-trees) ساخت میں منتقل ہونے کا ارادہ ہے، جو مستقبل میں پروٹوکول کی بہتری کے لیے بہت سے نئے امکانات کھولے گا۔

## شرائط {#prerequisites}

اس صفحے کو بہتر طور پر سمجھنے کے لیے، [ہیشز](https://en.wikipedia.org/wiki/Hash_function)، [مرکل ٹریز](https://en.wikipedia.org/wiki/Merkle_tree)، [ٹرائیز](https://en.wikipedia.org/wiki/Trie) اور [سلسلہ بندی](https://en.wikipedia.org/wiki/Serialization) کا بنیادی علم ہونا مددگار ثابت ہوگا۔ یہ مضمون ایک بنیادی [ریڈکس ٹری (radix tree)](https://en.wikipedia.org/wiki/Radix_tree) کی تفصیل سے شروع ہوتا ہے، پھر بتدریج ایتھیریم کے زیادہ بہتر ڈیٹا سٹرکچر کے لیے ضروری ترامیم متعارف کراتا ہے۔

## بنیادی ریڈکس ٹرائیز {#basic-radix-tries}

ایک بنیادی ریڈکس ٹرائی میں، ہر نوڈ اس طرح نظر آتا ہے:

```
[i_0, i_1 ... i_n, value]
```

جہاں `i_0 ... i_n` حروف تہجی کی علامتوں (اکثر بائنری یا ہیکس) کی نمائندگی کرتے ہیں، `value` نوڈ پر ٹرمینل ویلیو ہے، اور `i_0, i_1 ... i_n` سلاٹس میں اقدار یا تو `NULL` ہیں یا دوسرے نوڈز کے پوائنٹرز (ہمارے معاملے میں، ہیشز) ہیں۔ یہ ایک بنیادی `(key, value)` سٹور بناتا ہے۔

فرض کریں کہ آپ کلید-قدر (key-value) کے جوڑوں کے سیٹ پر ایک ترتیب کو برقرار رکھنے کے لیے ریڈکس ٹری ڈیٹا سٹرکچر استعمال کرنا چاہتے ہیں۔ ٹرائی میں کلید `dog` پر میپ کی گئی موجودہ قدر تلاش کرنے کے لیے، آپ پہلے `dog` کو حروف تہجی میں تبدیل کریں گے (جس سے `64 6f 67` حاصل ہوگا)، اور پھر اس راستے پر چلتے ہوئے ٹرائی میں نیچے جائیں گے جب تک کہ آپ کو قدر نہ مل جائے۔ یعنی، آپ ٹرائی کا روٹ نوڈ تلاش کرنے کے لیے ایک فلیٹ کلید/قدر DB میں روٹ ہیش کو تلاش کرنے سے شروع کرتے ہیں۔ اسے دوسرے نوڈز کی طرف اشارہ کرنے والی کلیدوں کی ایک صف (array) کے طور پر دکھایا جاتا ہے۔ آپ اشاریہ `6` پر موجود قدر کو بطور کلید استعمال کریں گے اور اسے فلیٹ کلید/قدر DB میں تلاش کریں گے تاکہ ایک سطح نیچے کا نوڈ حاصل کیا جا سکے۔ پھر اگلی قدر تلاش کرنے کے لیے اشاریہ `4` کا انتخاب کریں، پھر اشاریہ `6` کا انتخاب کریں، اور اسی طرح، یہاں تک کہ، ایک بار جب آپ نے راستے کی پیروی کر لی: `root -> 6 -> 4 -> 6 -> 15 -> 6 -> 7`، آپ نوڈ کی قدر تلاش کریں گے اور نتیجہ واپس کریں گے۔

'ٹرائی' اور بنیادی فلیٹ کلید/قدر 'DB' میں کچھ تلاش کرنے کے درمیان فرق ہے۔ وہ دونوں کلید/قدر کے انتظامات کی وضاحت کرتے ہیں، لیکن بنیادی DB کلید کی روایتی 1 قدمی تلاش کر سکتا ہے۔ ٹرائی میں کلید تلاش کرنے کے لیے اوپر بیان کردہ حتمی قدر تک پہنچنے کے لیے متعدد بنیادی DB تلاشوں کی ضرورت ہوتی ہے۔ ابہام کو ختم کرنے کے لیے آئیے مؤخر الذکر کو `path` کے طور پر حوالہ دیں۔

ریڈکس ٹرائیز کے لیے اپ ڈیٹ اور ڈیلیٹ آپریشنز کی وضاحت اس طرح کی جا سکتی ہے:

```python
    def update(node_hash, path, value):
        curnode = db.get(node_hash) if node_hash else [NULL] * 17
        newnode = curnode.copy()
        if path == "":
            newnode[-1] = value
        else:
            newindex = update(curnode[path[0]], path[1:], value)
            newnode[path[0]] = newindex
        db.put(hash(newnode), newnode)
        return hash(newnode)

    def delete(node_hash, path):
        if node_hash is NULL:
            return NULL
        else:
            curnode = db.get(node_hash)
            newnode = curnode.copy()
            if path == "":
                newnode[-1] = NULL
            else:
                newindex = delete(curnode[path[0]], path[1:])
                newnode[path[0]] = newindex

            if all(x is NULL for x in newnode):
                return NULL
            else:
                db.put(hash(newnode), newnode)
                return hash(newnode)
```

ایک "مرکل" ریڈکس ٹری حتمی طور پر تیار کردہ تشفیری ہیش ڈائجسٹس کا استعمال کرتے ہوئے نوڈز کو جوڑ کر بنایا جاتا ہے۔ یہ مواد کی ایڈریسنگ (کلید/قدر DB `key == keccak256(rlp(value))` میں) ذخیرہ شدہ ڈیٹا کی تشفیری سالمیت کی ضمانت فراہم کرتی ہے۔ اگر کسی دیے گئے ٹرائی کا روٹ ہیش عوامی طور پر جانا جاتا ہے، تو بنیادی لیف (leaf) ڈیٹا تک رسائی رکھنے والا کوئی بھی شخص یہ ثبوت بنا سکتا ہے کہ ٹرائی میں ایک مخصوص راستے پر ایک دی گئی قدر شامل ہے، ہر اس نوڈ کے ہیشز فراہم کر کے جو ایک مخصوص قدر کو ٹری کے روٹ سے جوڑتے ہیں۔

ایک حملہ آور کے لیے ایسے `(path, value)` جوڑے کا ثبوت فراہم کرنا ناممکن ہے جو موجود نہیں ہے کیونکہ روٹ ہیش بالآخر اس کے نیچے موجود تمام ہیشز پر مبنی ہوتا ہے۔ کوئی بھی بنیادی ترمیم روٹ ہیش کو بدل دے گی۔ آپ ہیش کو ڈیٹا کے بارے میں ساختی معلومات کی ایک کمپریسڈ نمائندگی کے طور پر سوچ سکتے ہیں، جو ہیشنگ فنکشن کے پری امیج (pre-image) تحفظ کے ذریعے محفوظ ہے۔

ہم ریڈکس ٹری کی ایک ایٹمی اکائی (مثلاً، ایک واحد ہیکس کریکٹر، یا <span dir="ltr">4 bit</span> بائنری نمبر) کو "نبل" (nibble) کہیں گے۔ ایک وقت میں ایک نبل کے راستے کو عبور کرتے ہوئے، جیسا کہ اوپر بیان کیا گیا ہے، نوڈز زیادہ سے زیادہ <span dir="ltr">16</span> بچوں کا حوالہ دے سکتے ہیں لیکن ان میں ایک `value` عنصر شامل ہوتا ہے۔ لہذا، ہم انہیں <span dir="ltr">17</span> کی لمبائی والی صف کے طور پر پیش کرتے ہیں۔ ہم ان 17-عنصری صفوں کو "برانچ نوڈز" (branch nodes) کہتے ہیں۔

## مرکل پیٹریشیا ٹرائی {#merkle-patricia-trees}

ریڈکس ٹرائیز کی ایک بڑی حد ہے: وہ غیر موثر ہیں۔ اگر آپ ایک `(path, value)` بائنڈنگ کو ذخیرہ کرنا چاہتے ہیں جہاں راستہ، جیسا کہ ایتھیریم میں ہے، <span dir="ltr">64</span> کریکٹرز لمبا ہے (`bytes32` میں نبلز کی تعداد)، تو ہمیں فی کریکٹر ایک سطح کو ذخیرہ کرنے کے لیے ایک کلو بائٹ سے زیادہ اضافی جگہ کی ضرورت ہوگی، اور ہر تلاش یا حذف کرنے میں پورے <span dir="ltr">64</span> مراحل لگیں گے۔ ذیل میں متعارف کرائی گئی پیٹریشیا ٹرائی اس مسئلے کو حل کرتی ہے۔

### بہتری (Optimization) {#optimization}

مرکل پیٹریشیا ٹرائی میں ایک نوڈ درج ذیل میں سے ایک ہوتا ہے:

1.  `NULL` (خالی سٹرنگ کے طور پر دکھایا گیا ہے)
2.  `branch` ایک 17-آئٹم نوڈ `[ v0 ... v15, vt ]`
3.  `leaf` ایک 2-آئٹم نوڈ `[ encodedPath, value ]`
4.  `extension` ایک 2-آئٹم نوڈ `[ encodedPath, key ]`

<span dir="ltr">64</span> کریکٹر کے راستوں کے ساتھ یہ ناگزیر ہے کہ ٹرائی کی پہلی چند تہوں کو عبور کرنے کے بعد، آپ ایک ایسے نوڈ پر پہنچیں گے جہاں کم از کم راستے کے کچھ حصے کے لیے کوئی مختلف راستہ موجود نہیں ہے۔ راستے میں <span dir="ltr">15</span> تک بکھرے ہوئے `NULL` نوڈز بنانے سے بچنے کے لیے، ہم `[ encodedPath, key ]` کی شکل کا ایک `extension` نوڈ ترتیب دے کر نزول کو مختصر کرتے ہیں، جہاں `encodedPath` میں آگے بڑھنے کے لیے "جزوی راستہ" (partial path) شامل ہوتا ہے (نیچے بیان کردہ کمپیکٹ انکوڈنگ کا استعمال کرتے ہوئے)، اور `key` اگلی DB تلاش کے لیے ہے۔

ایک `leaf` نوڈ کے لیے، جسے `encodedPath` کے پہلے نبل میں ایک فلیگ کے ذریعے نشان زد کیا جا سکتا ہے، راستہ پچھلے تمام نوڈ کے راستے کے ٹکڑوں کو انکوڈ کرتا ہے اور ہم براہ راست `value` تلاش کر سکتے ہیں۔

تاہم، یہ مندرجہ بالا بہتری ابہام پیدا کرتی ہے۔

نبلز میں راستوں کو عبور کرتے وقت، ہمارے پاس عبور کرنے کے لیے نبلز کی طاق (odd) تعداد ہو سکتی ہے، لیکن چونکہ تمام ڈیٹا `bytes` فارمیٹ میں محفوظ کیا جاتا ہے۔ مثال کے طور پر، نبل `1`، اور نبلز `01` کے درمیان فرق کرنا ممکن نہیں ہے (دونوں کو `<01>` کے طور پر محفوظ کیا جانا چاہیے)۔ طاق لمبائی کی وضاحت کرنے کے لیے، جزوی راستے کے شروع میں ایک فلیگ لگایا جاتا ہے۔

### تفصیلات: اختیاری ٹرمینیٹر کے ساتھ ہیکس ترتیب کی کمپیکٹ انکوڈنگ {#specification}

جیسا کہ اوپر بیان کیا گیا ہے، _طاق بمقابلہ جفت باقی جزوی راستے کی لمبائی_ اور _لیف بمقابلہ ایکسٹینشن نوڈ_ دونوں کی فلیگنگ کسی بھی 2-آئٹم نوڈ کے جزوی راستے کے پہلے نبل میں رہتی ہے۔ ان کا نتیجہ درج ذیل ہے:

| ہیکس کریکٹر | بٹس | نوڈ کی قسم جزوی | راستے کی لمبائی |
| -------- | ---- | ------------------ | ----------- |
| 0        | 0000 | ایکسٹینشن          | جفت        |
| 1        | 0001 | ایکسٹینشن          | طاق         |
| 2        | 0010 | ٹرمینیٹنگ (لیف) | جفت        |
| 3        | 0011 | ٹرمینیٹنگ (لیف) | طاق         |

جفت باقی راستے کی لمبائی (`0` یا `2`) کے لیے، ایک اور `0` "پیڈنگ" (padding) نبل ہمیشہ پیروی کرے گا۔

```python
    def compact_encode(hexarray):
        term = 1 if hexarray[-1] == 16 else 0
        if term:
            hexarray = hexarray[:-1]
        oddlen = len(hexarray) % 2
        flags = 2 * term + oddlen
        if oddlen:
            hexarray = [flags] + hexarray
        else:
            hexarray = [flags] + [0] + hexarray
        # ہیکس ایرے کی اب ایک جفت لمبائی ہے جس کا پہلا نبل فلیگز ہے۔
        o = ""
        for i in range(0, len(hexarray), 2):
            o += chr(16 * hexarray[i] + hexarray[i + 1])
        return o
```

مثالیں:

```python
    > [1, 2, 3, 4, 5, ...]
    '11 23 45'
    > [0, 1, 2, 3, 4, 5, ...]
    '00 01 23 45'
    > [0, f, 1, c, b, 8, 10]
    '20 0f 1c b8'
    > [f, 1, c, b, 8, 10]
    '3f 1c b8'
```

مرکل پیٹریشیا ٹرائی میں نوڈ حاصل کرنے کے لیے توسیعی کوڈ یہ ہے:

```python
    def get_helper(node_hash, path):
        if path == []:
            return node_hash
        if node_hash == "":
            return ""
        curnode = rlp.decode(node_hash if len(node_hash) < 32 else db.get(node_hash))
        if len(curnode) == 2:
            (k2, v2) = curnode
            k2 = compact_decode(k2)
            if k2 == path[: len(k2)]:
                return get(v2, path[len(k2) :])
            else:
                return ""
        elif len(curnode) == 17:
            return get_helper(curnode[path[0]], path[1:])

    def get(node_hash, path):
        path2 = []
        for i in range(len(path)):
            path2.push(int(ord(path[i]) / 16))
            path2.push(ord(path[i]) % 16)
        path2.push(16)
        return get_helper(node_hash, path2)
```

### مثال ٹرائی {#example-trie}

فرض کریں کہ ہم ایک ٹرائی چاہتے ہیں جس میں چار راستے/قدر کے جوڑے `('do', 'verb')`، `('dog', 'puppy')`، `('doge', 'coins')`، `('horse', 'stallion')` شامل ہوں۔

سب سے پہلے، ہم راستوں اور اقدار دونوں کو `bytes` میں تبدیل کرتے ہیں۔ ذیل میں، _راستوں_ کے لیے اصل بائٹ کی نمائندگی `<>` سے ظاہر کی گئی ہے، حالانکہ _اقدار_ کو اب بھی سٹرنگز کے طور پر دکھایا گیا ہے، جنہیں `''` سے ظاہر کیا گیا ہے، تاکہ آسانی سے سمجھا جا سکے (وہ بھی، دراصل `bytes` ہوں گے):

```
<64 6f> : 'verb'
    <64 6f 67> : 'puppy'
    <64 6f 67 65> : 'coins'
    <68 6f 72 73 65> : 'stallion'
```

اب، ہم بنیادی DB میں درج ذیل کلید/قدر کے جوڑوں کے ساتھ ایسی ٹرائی بناتے ہیں:

```
rootHash: [ <16>, hashA ]
    hashA:    [ <>, <>, <>, <>, hashB, <>, <>, <>, [ <20 6f 72 73 65>, 'stallion' ], <>, <>, <>, <>, <>, <>, <>, <> ]
    hashB:    [ <00 6f>, hashC ]
    hashC:    [ <>, <>, <>, <>, <>, <>, hashD, <>, <>, <>, <>, <>, <>, <>, <>, <>, 'verb' ]
    hashD:    [ <17>, [ <>, <>, <>, <>, <>, <>, [ <35>, 'coins' ], <>, <>, <>, <>, <>, <>, <>, <>, <>, 'puppy' ] ]
```

جب ایک نوڈ کا حوالہ دوسرے نوڈ کے اندر دیا جاتا ہے، تو جو شامل ہوتا ہے وہ `keccak256(rlp.encode(node))` ہے، اگر `len(rlp.encode(node)) >= 32` ورنہ `node` جہاں `rlp.encode` [RLP](/developers/docs/data-structures-and-encoding/rlp) انکوڈنگ فنکشن ہے۔

نوٹ کریں کہ ٹرائی کو اپ ڈیٹ کرتے وقت، کسی کو کلید/قدر کے جوڑے `(keccak256(x), x)` کو ایک مستقل لک اپ ٹیبل میں ذخیرہ کرنے کی ضرورت ہوتی ہے _اگر_ نئے بنائے گئے نوڈ کی لمبائی <span dir="ltr">= 32</span> ہو۔ تاہم، اگر نوڈ اس سے چھوٹا ہے، تو کسی کو کچھ بھی ذخیرہ کرنے کی ضرورت نہیں ہے، کیونکہ فنکشن <span dir="ltr">f(x) = x</span> قابلِ واپسی (reversible) ہے۔

## ایتھیریم میں ٹرائیز {#tries-in-ethereum}

ایتھیریم کی عمل درآمد کی تہہ میں تمام مرکل ٹرائیز ایک مرکل پیٹریشیا ٹرائی کا استعمال کرتی ہیں۔

ایک بلاک ہیڈر سے ان میں سے <span dir="ltr">3</span> ٹرائیز کے <span dir="ltr">3</span> روٹس ہوتے ہیں۔

1.  <span dir="ltr">stateRoot</span>
2.  <span dir="ltr">transactionsRoot</span>
3.  <span dir="ltr">receiptsRoot</span>

### حالت کی ٹرائی {#state-trie}

ایک عالمی حالت کی ٹرائی ہے، اور جب بھی کوئی کلائنٹ کسی بلاک پر کارروائی کرتا ہے تو اسے اپ ڈیٹ کیا جاتا ہے۔ اس میں، ایک `path` ہمیشہ: `keccak256(ethereumAddress)` ہوتا ہے اور ایک `value` ہمیشہ: `rlp(ethereumAccount)` ہوتا ہے۔ خاص طور پر ایک ایتھیریم `account` `[nonce,balance,storageRoot,codeHash]` کی <span dir="ltr">4</span> آئٹم کی صف ہے۔ اس مقام پر، یہ بات قابل غور ہے کہ یہ `storageRoot` ایک اور پیٹریشیا ٹرائی کا روٹ ہے:

### ذخیرہ ٹرائی {#storage-trie}

ذخیرہ ٹرائی وہ جگہ ہے جہاں _تمام_ کنٹریکٹ کا ڈیٹا رہتا ہے۔ ہر اکاؤنٹ کے لیے ایک الگ ذخیرہ ٹرائی ہوتی ہے۔ کسی دیے گئے پتے پر مخصوص سٹوریج پوزیشنز پر اقدار بازیافت کرنے کے لیے سٹوریج کا پتہ، سٹوریج میں ذخیرہ شدہ ڈیٹا کی انٹیجر پوزیشن، اور بلاک ID درکار ہوتے ہیں۔ پھر انہیں جے سن آر پی سی API میں بیان کردہ `eth_getStorageAt` میں دلائل (arguments) کے طور پر پاس کیا جا سکتا ہے، مثلاً، پتے `0x295a70b2de5e3953354a6a8344e616ed314d7251` کے لیے سٹوریج سلاٹ <span dir="ltr">0</span> میں ڈیٹا بازیافت کرنے کے لیے:

```bash
curl -X POST --data '{"jsonrpc":"2.0", "method": "eth_getStorageAt", "params": ["0x295a70b2de5e3953354a6a8344e616ed314d7251", "0x0", "latest"], "id": 1}' localhost:8545

{"jsonrpc":"2.0","id":1,"result":"0x00000000000000000000000000000000000000000000000000000000000004d2"}

```

سٹوریج میں دیگر عناصر کو بازیافت کرنا قدرے زیادہ پیچیدہ ہے کیونکہ ذخیرہ ٹرائی میں پوزیشن کا پہلے حساب لگانا ضروری ہے۔ پوزیشن کا حساب پتے اور سٹوریج پوزیشن کے `keccak256` ہیش کے طور پر لگایا جاتا ہے، دونوں کو بائیں طرف صفر کے ساتھ <span dir="ltr">32 bytes</span> کی لمبائی تک پیڈ (padded) کیا جاتا ہے۔ مثال کے طور پر، پتے `0x391694e7e0b0cce554cb130d723a9d27458f9298` کے لیے سٹوریج سلاٹ <span dir="ltr">1</span> میں ڈیٹا کی پوزیشن یہ ہے:

```python
keccak256(decodeHex("000000000000000000000000391694e7e0b0cce554cb130d723a9d27458f9298" + "0000000000000000000000000000000000000000000000000000000000000001"))
```

ایک گو ایتھیریم (geth) کنسول میں، اس کا حساب اس طرح لگایا جا سکتا ہے:

```
> var key = "000000000000000000000000391694e7e0b0cce554cb130d723a9d27458f9298" + "0000000000000000000000000000000000000000000000000000000000000001"
undefined
> web3.sha3(key, {"encoding": "hex"})
"0x6661e9d6d8b923d5bbaab1b96e1dd51ff6ea2a93520fdc9eb75d059238b8c5e9"
```

لہذا `path` `keccak256(<6661e9d6d8b923d5bbaab1b96e1dd51ff6ea2a93520fdc9eb75d059238b8c5e9>)` ہے۔ اسے اب پہلے کی طرح ذخیرہ ٹرائی سے ڈیٹا بازیافت کرنے کے لیے استعمال کیا جا سکتا ہے:

```bash
curl -X POST --data '{"jsonrpc":"2.0", "method": "eth_getStorageAt", "params": ["0x295a70b2de5e3953354a6a8344e616ed314d7251", "0x6661e9d6d8b923d5bbaab1b96e1dd51ff6ea2a93520fdc9eb75d059238b8c5e9", "latest"], "id": 1}' localhost:8545

{"jsonrpc":"2.0","id":1,"result":"0x000000000000000000000000000000000000000000000000000000000000162e"}
```

نوٹ: ایک ایتھیریم اکاؤنٹ کے لیے `storageRoot` پہلے سے طے شدہ طور پر خالی ہوتا ہے اگر یہ کنٹریکٹ اکاؤنٹ نہیں ہے۔

### ٹرانزیکشنز ٹرائی {#transaction-trie}

ہر بلاک کے لیے ایک الگ ٹرانزیکشنز ٹرائی ہوتی ہے، جو دوبارہ `(key, value)` جوڑوں کو ذخیرہ کرتی ہے۔ یہاں ایک راستہ یہ ہے: `rlp(transactionIndex)` جو اس کلید کی نمائندگی کرتا ہے جو اس قدر سے مطابقت رکھتی ہے جس کا تعین اس سے ہوتا ہے:

```python
if legacyTx:
  value = rlp(tx)
else:
  value = TxType | encode(tx)
```

اس بارے میں مزید معلومات [<span dir="ltr">EIP-2718</span>](https://eips.ethereum.org/EIPS/eip-2718) دستاویزات میں مل سکتی ہیں۔

### رسیدوں کی ٹرائی {#receipts-trie}

ہر بلاک کی اپنی رسیدوں کی ٹرائی ہوتی ہے۔ یہاں ایک `path` یہ ہے: `rlp(transactionIndex)`۔ `transactionIndex` اس بلاک کے اندر اس کا اشاریہ ہے جس میں اسے شامل کیا گیا تھا۔ رسیدوں کی ٹرائی کو کبھی اپ ڈیٹ نہیں کیا جاتا ہے۔ ٹرانزیکشنز ٹرائی کی طرح، موجودہ اور پرانی (legacy) رسیدیں ہوتی ہیں۔ رسیدوں کی ٹرائی میں کسی مخصوص رسید کو تلاش کرنے کے لیے، اس کے بلاک میں ٹرانزیکشن کا اشاریہ، رسید کا پے لوڈ اور ٹرانزیکشن کی قسم درکار ہوتی ہے۔ واپس کی گئی رسید `Receipt` قسم کی ہو سکتی ہے جسے `TransactionType` اور `ReceiptPayload` کے ملاپ کے طور پر بیان کیا گیا ہے یا یہ `LegacyReceipt` قسم کی ہو سکتی ہے جسے `rlp([status, cumulativeGasUsed, logsBloom, logs])` کے طور پر بیان کیا گیا ہے۔

اس بارے میں مزید معلومات [<span dir="ltr">EIP-2718</span>](https://eips.ethereum.org/EIPS/eip-2718) دستاویزات میں مل سکتی ہیں۔

## مزید مطالعہ {#further-reading}

- [ترمیم شدہ مرکل پیٹریشیا ٹرائی — ایتھیریم حالت کو کیسے محفوظ کرتا ہے](https://medium.com/codechain/modified-merkle-patricia-trie-how-ethereum-saves-a-state-e6d7555078dd)
- [ایتھیریم میں مرکلنگ](https://blog.ethereum.org/2015/11/15/merkling-in-ethereum)
- [ایتھیریم ٹرائی کو سمجھنا](https://easythereentropy.wordpress.com/2014/06/04/understanding-the-ethereum-trie/)