ప్రధాన కంటెంట్‌కి స్కిప్ చేయండి
Change page

మెర్కిల్ ప్యాట్రిసియా ట్రై

పేజీ చివరి అప్‌డేట్: 26 ఫిబ్రవరి, 2026

Ethereum స్థితి (అన్ని ఖాతాలు, బ్యాలెన్స్‌లు మరియు స్మార్ట్ కాంట్రాక్ట్‌ల మొత్తం), సాధారణంగా కంప్యూటర్ సైన్స్‌లో మెర్కిల్ ట్రీగా పిలువబడే డేటా స్ట్రక్చర్ యొక్క ప్రత్యేక వెర్షన్‌గా ఎన్‌కోడ్ చేయబడింది. ఈ నిర్మాణం క్రిప్టోగ్రఫీలోని అనేక అనువర్తనాలకు ఉపయోగపడుతుంది, ఎందుకంటే ఇది ట్రీలో చిక్కుకున్న అన్ని వ్యక్తిగత డేటా భాగాల మధ్య ధృవీకరించదగిన సంబంధాన్ని సృష్టిస్తుంది, దీని ఫలితంగా డేటాకు సంబంధించిన విషయాలను నిరూపించడానికి ఒకే రూట్ విలువ ఉపయోగించబడుతుంది.

Ethereum యొక్క డేటా నిర్మాణం ఒక 'మాడిఫైడ్ మెర్కిల్-ప్యాట్రిసియా ట్రై'. దీనికి ఆ పేరు వచ్చింది ఎందుకంటే ఇది PATRICIA (ప్రాక్టికల్ అల్గారిథం టు రిట్రైవ్ ఇన్ఫర్మేషన్ కోడెడ్ ఇన్ ఆల్ఫాన్యూమరిక్) నుండి కొన్ని ఫీచర్లను తీసుకుంటుంది మరియు ఇది Ethereum స్టేట్‌ను కలిగి ఉన్న ఐటెమ్‌ల యొక్క సమర్థవంతమైన డేటా రీట్రైవల్ కోసం రూపొందించబడింది.

ఒక మెర్కిల్-ప్యాట్రిసియా ట్రై డిటర్మినిస్టిక్ మరియు క్రిప్టోగ్రాఫికల్‌గా వెరిఫై చేయదగినది: స్థితి యొక్క ప్రతి వ్యక్తిగత భాగం నుండి గణించడం ద్వారా మాత్రమే స్టేట్ రూట్‌ను జనరేట్ చేయగలము, మరియు ఒకేలా ఉండే రెండు స్థితులను, రూట్ హ్యాష్ మరియు దానికి దారితీసిన హ్యాష్‌లను పోల్చడం ద్వారా సులభంగా నిరూపించవచ్చు (ఒక మెర్కిల్ ప్రూఫ్). దీనికి విరుద్ధంగా, ఒకే రూట్ హాష్‌తో రెండు వేర్వేరు స్థితులను సృష్టించడానికి మార్గం లేదు మరియు విభిన్న విలువలతో స్థితిని సవరించే ఏ ప్రయత్నమైనా వేరే స్టేట్ రూట్ హాష్‌కి దారి తీస్తుంది. సిద్ధాంతపరంగా, ఈ నిర్మాణం ఇన్‌సర్ట్‌లు, లుకప్‌లు మరియు డిలీట్‌ల కోసం O(log(n)) సామర్థ్యానికి 'హోలీ గ్రెయిల్' అందిస్తుంది.

సమీప భవిష్యత్తులో, Ethereum ఒక Verkle Tree నిర్మాణానికి మైగ్రేట్ అవ్వాలని యోచిస్తోంది, ఇది భవిష్యత్తు ప్రోటోకాల్ మెరుగుదలల కోసం అనేక కొత్త అవకాశాలను తెరుస్తుంది.

అవసరాలు

ఈ పేజీని బాగా అర్థం చేసుకోవడానికి, హ్యాష్‌లు (opens in a new tab), మెర్కిల్ ట్రీలు (opens in a new tab), ట్రైలు (opens in a new tab) మరియు సీరియలైజేషన్ (opens in a new tab) గురించి ప్రాథమిక జ్ఞానం కలిగి ఉండటం సహాయపడుతుంది. ఈ వ్యాసం ప్రాథమిక రాడిక్స్ ట్రీ (opens in a new tab) వివరణతో మొదలవుతుంది, ఆపై Ethereum యొక్క మరింత ఆప్టిమైజ్ చేయబడిన డేటా నిర్మాణం కోసం అవసరమైన మార్పులను క్రమంగా పరిచయం చేస్తుంది.

ప్రాథమిక రాడిక్స్ ట్రైలు

ప్రాథమిక రాడిక్స్ ట్రైలో, ప్రతి నోడ్ క్రింది విధంగా కనిపిస్తుంది:

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

ఇక్కడ i_0 ... i_n వర్ణమాల యొక్క చిహ్నాలను సూచిస్తాయి (తరచుగా బైనరీ లేదా హెక్స్), value అనేది నోడ్ వద్ద టెర్మినల్ విలువ, మరియు i_0, i_1 ... లోని విలువలు i_n స్లాట్‌లు NULL లేదా ఇతర నోడ్‌లకు పాయింటర్‌లు (మా విషయంలో, హ్యాష్‌లు). ఇది ఒక ప్రాథమిక (key, value) స్టోర్‌ను ఏర్పరుస్తుంది.

కీ విలువ జతల సెట్‌పై ఆర్డర్‌ను కొనసాగించడం కోసం మీరు రాడిక్స్ ట్రీ డేటా స్ట్రక్చర్‌ని ఉపయోగించాలనుకుంటున్నారని చెప్పండి. ట్రైలో dog కీకి ప్రస్తుతం మ్యాప్ చేయబడిన విలువను కనుగొనడానికి, మీరు మొదట dogను వర్ణమాలలోని అక్షరాలుగా మార్చాలి (ఇది 64 6f 67 ఇస్తుంది), ఆపై మీరు విలువను కనుగొనే వరకు ఆ మార్గాన్ని అనుసరించి ట్రైలో క్రిందికి వెళ్ళాలి. అంటే, మీరు ట్రై యొక్క రూట్ నోడ్‌ను కనుగొనడానికి ఫ్లాట్ కీ/విలువ DBలో రూట్ హాష్‌ని చూడటం ద్వారా ప్రారంభించండి. ఇది ఇతర నోడ్‌లను సూచించే కీల శ్రేణిగా సూచించబడుతుంది. మీరు ఇండెక్స్ 6 వద్ద ఉన్న విలువను కీగా ఉపయోగించి, ఒక లెవెల్ కింద ఉన్న నోడ్‌ను పొందడానికి ఫ్లాట్ కీ/విలువ DBలో దాన్ని వెతకాలి. ఆ తర్వాత తదుపరి విలువను చూడటానికి ఇండెక్స్ 4 ను ఎంచుకోండి, ఆపై ఇండెక్స్ 6ను ఎంచుకోండి, అలా మీరు root -> 6 -> 4 -> 6 -> 15 -> 6 -> 7 మార్గాన్ని అనుసరించిన తర్వాత, మీరు నోడ్ యొక్క విలువను చూసి ఫలితాన్ని తిరిగి ఇస్తారు.

'ట్రై' మరియు అంతర్లీన ఫ్లాట్ కీ/విలువ 'DB'లో ఏదైనా చూడటం మధ్య వ్యత్యాసం ఉంది. అవి రెండూ కీ/విలువ ఏర్పాట్లను నిర్వచించాయి, అయితే అంతర్లీనంగా ఉన్న DB కీ యొక్క సాంప్రదాయ 1 స్టెప్ లుకప్ చేయగలదు. ట్రైలో కీని వెతకడానికి పైన వివరించిన తుది విలువను పొందడానికి బహుళ అంతర్లీన DB శోధనలు అవసరం. అస్పష్టతను తొలగించడానికి, రెండవదాన్ని ఒక pathగా సూచిద్దాం.

రాడిక్స్ ప్రయత్నాల కోసం నవీకరణ మరియు తొలగింపు కార్యకలాపాలను ఈ క్రింది విధంగా నిర్వచించవచ్చు:

1 def update(node_hash, path, value):
2 curnode = db.get(node_hash) if node_hash else [NULL] * 17
3 newnode = curnode.copy()
4 if path == "":
5 newnode[-1] = value
6 else:
7 newindex = update(curnode[path[0]], path[1:], value)
8 newnode[path[0]] = newindex
9 db.put(hash(newnode), newnode)
10 return hash(newnode)
11
12 def delete(node_hash, path):
13 if node_hash is NULL:
14 return NULL
15 else:
16 curnode = db.get(node_hash)
17 newnode = curnode.copy()
18 if path == "":
19 newnode[-1] = NULL
20 else:
21 newindex = delete(curnode[path[0]], path[1:])
22 newnode[path[0]] = newindex
23
24 if all(x is NULL for x in newnode):
25 return NULL
26 else:
27 db.put(hash(newnode), newnode)
28 return hash(newnode)
అన్నీ చూపించు

నిర్ణయాత్మకంగా రూపొందించిన క్రిప్టోగ్రాఫిక్ హాష్ డైజెస్ట్‌లను ఉపయోగించి నోడ్‌లను లింక్ చేయడం ద్వారా "మెర్కిల్" రాడిక్స్ ట్రీ నిర్మించబడింది. ఈ కంటెంట్-అడ్రెస్సింగ్ (కీ/విలువ DBలో key == keccak256(rlp(value))) నిల్వ చేయబడిన డేటా యొక్క క్రిప్టోగ్రాఫిక్ సమగ్రత హామీని అందిస్తుంది. ఇచ్చిన ట్రై యొక్క రూట్ హాష్ పబ్లిక్‌గా తెలిసినట్లయితే, అంతర్లీన లీఫ్ డేటాకు యాక్సెస్ ఉన్న ఎవరైనా చెట్టుకు నిర్దిష్ట విలువను చేరే ప్రతి నోడ్ యొక్క హ్యాష్‌లను అందించడం ద్వారా నిర్దిష్ట మార్గంలో ఇచ్చిన విలువను ట్రైలో కలిగి ఉంటుందని రుజువును నిర్మించవచ్చు. రూట్.

ఒక అటాకర్ ఉనికిలో లేని (path, value) జతకు ప్రూఫ్ అందించడం అసాధ్యం, ఎందుకంటే రూట్ హ్యాష్ అంతిమంగా దాని కింద ఉన్న అన్ని హ్యాష్‌ల మీద ఆధారపడి ఉంటుంది. ఏదైనా అంతర్లీన సవరణ రూట్ హాష్‌ను మారుస్తుంది. హ్యాషింగ్ ఫంక్షన్ యొక్క ప్రీ-ఇమేజ్ ప్రొటెక్షన్ ద్వారా భద్రపరచబడిన డేటా గురించిన నిర్మాణాత్మక సమాచారం యొక్క సంపీడన ప్రాతినిధ్యంగా మీరు హాష్‌ని భావించవచ్చు.

మేము రాడిక్స్ ట్రీ యొక్క పరమాణు యూనిట్‌ను (ఉదా. ఒకే హెక్స్ అక్షరం లేదా 4 బిట్ బైనరీ సంఖ్య) "నిబుల్"గా సూచిస్తాము. పైన వివరించిన విధంగా, ఒకేసారి ఒక నిబుల్ చొప్పున మార్గాన్ని ట్రావర్స్ చేస్తున్నప్పుడు, నోడ్‌లు గరిష్టంగా 16 చైల్డ్‌లను సూచించగలవు కానీ ఒక value ఎలిమెంట్‌ను కూడా కలిగి ఉంటాయి. అందువల్ల, మేము వాటిని పొడవు 17 యొక్క శ్రేణిగా సూచిస్తాము. మేము ఈ 17-మూలకాల శ్రేణులను "బ్రాంచ్ నోడ్స్" అని పిలుస్తాము.

మెర్కిల్ ప్యాట్రిసియా ట్రై

రాడిక్స్ ప్రయత్నాలకు ఒక ప్రధాన పరిమితి ఉంది: అవి అసమర్థమైనవి. మీరు ఒక (path, value) బైండింగ్‌ను నిల్వ చేయాలనుకుంటే, ఇక్కడ Ethereumలో వలె పాత్ 64 అక్షరాల పొడవు ఉంటుంది (ఇది bytes32లోని నిబుల్స్ సంఖ్య), ప్రతి అక్షరానికి ఒక లెవెల్ నిల్వ చేయడానికి మనకు ఒక కిలోబైట్ కంటే ఎక్కువ అదనపు స్థలం అవసరం అవుతుంది, మరియు ప్రతి లుకప్ లేదా డిలీట్ పూర్తి 64 స్టెప్స్ తీసుకుంటుంది. కింది వాటిలో ప్రవేశపెట్టిన ప్యాట్రిసియా ట్రై ఈ సమస్యను పరిష్కరిస్తుంది.

ఆప్టిమైజేషన్

మెర్కిల్ ప్యాట్రిసియా ట్రైలో నోడ్ క్రింది వాటిలో ఒకటి:

  1. NULL (ఖాళీ స్ట్రింగ్‌గా సూచించబడుతుంది)
  2. branch ఒక 17-ఐటెమ్ నోడ్ [ v0 ... v15, vt ]
  3. leaf ఒక 2-ఐటెమ్ నోడ్ [ encodedPath, value ]
  4. extension ఒక 2-ఐటెమ్ నోడ్ [ encodedPath, key ]

64 క్యారెక్టర్ పాత్‌లతో, ట్రై యొక్క మొదటి కొన్ని లేయర్‌లను దాటిన తర్వాత, మీరు ఒక నోడ్‌కు చేరుకోవడం అనివార్యం. పాత్ వెంబడి 15 వరకు స్పార్స్ NULL నోడ్‌లను సృష్టించడాన్ని నివారించడానికి, మేము [ encodedPath, key ] రూపంలో ఒక extension నోడ్‌ను సెటప్ చేయడం ద్వారా డిసెంట్‌ను షార్ట్‌కట్ చేస్తాము, ఇక్కడ encodedPath అనేది ముందుకు వెళ్లడానికి "పార్షియల్ పాత్"ను (క్రింద వివరించిన కాంపాక్ట్ ఎన్‌కోడింగ్ ఉపయోగించి) కలిగి ఉంటుంది మరియు key అనేది తదుపరి DB లుకప్ కోసం.

ఒక leaf నోడ్ కోసం, దీనిని encodedPath యొక్క మొదటి నిబుల్‌లో ఒక ఫ్లాగ్ ద్వారా గుర్తించవచ్చు, ఈ పాత్ మునుపటి నోడ్ యొక్క అన్ని పాత్ ఫ్రాగ్మెంట్‌లను ఎన్‌కోడ్ చేస్తుంది మరియు మనం valueను నేరుగా చూడవచ్చు.

ఈ ఎగువ ఆప్టిమైజేషన్, అయితే, అస్పష్టతను పరిచయం చేస్తుంది.

నిబుల్స్‌లో పాత్‌లను ట్రావర్స్ చేస్తున్నప్పుడు, మనం ట్రావర్స్ చేయడానికి బేసి సంఖ్యలో నిబుల్స్‌తో ముగించవచ్చు, కానీ ఎందుకంటే మొత్తం డేటా bytes ఫార్మాట్‌లో నిల్వ చేయబడుతుంది. ఉదాహరణకు, నిబుల్ 1, మరియు నిబుల్స్ 01 (రెండూ <01> గా నిల్వ చేయబడాలి) మధ్య తేడాను గుర్తించడం సాధ్యం కాదు. బేసి పొడవును పేర్కొనడానికి, పాక్షిక మార్గం ఫ్లాగ్‌తో ప్రిఫిక్స్ చేయబడింది.

స్పెసిఫికేషన్: ఐచ్ఛిక టెర్మినేటర్‌తో హెక్స్ సీక్వెన్స్ యొక్క కాంపాక్ట్ ఎన్‌కోడింగ్

పైన వివరించిన విధంగా, మిగిలిన పాక్షిక పాత్ పొడవు బేసి vs. సరి మరియు లీఫ్ vs. ఎక్స్‌టెన్షన్ నోడ్ రెండింటి ఫ్లాగింగ్, ఏదైనా 2-ఐటెమ్ నోడ్ యొక్క పాక్షిక పాత్ యొక్క మొదటి నిబుల్‌లో ఉంటుంది. అవి క్రింది ఫలితాలకు దారితీస్తాయి:

హెక్స్ క్యారెక్టర్బిట్స్నోడ్ రకం పాక్షికంపాత్ పొడవు
00000ఎక్స్‌టెన్షన్సరి
10001ఎక్స్‌టెన్షన్బేసి
20010టెర్మినేటింగ్ (లీఫ్)సరి
30011టెర్మినేటింగ్ (లీఫ్)బేసి

సరి సంఖ్యలో మిగిలి ఉన్న పాత్ పొడవు (0 లేదా 2) కోసం, మరొక 0 "ప్యాడింగ్" నిబుల్ ఎల్లప్పుడూ అనుసరిస్తుంది.

1 def compact_encode(hexarray):
2 term = 1 if hexarray[-1] == 16 else 0
3 if term:
4 hexarray = hexarray[:-1]
5 oddlen = len(hexarray) % 2
6 flags = 2 * term + oddlen
7 if oddlen:
8 hexarray = [flags] + hexarray
9 else:
10 hexarray = [flags] + [0] + hexarray
11 # hexarray now has an even length whose first nibble is the flags.
12 o = ""
13 for i in range(0, len(hexarray), 2):
14 o += chr(16 * hexarray[i] + hexarray[i + 1])
15 return o
అన్నీ చూపించు

ఉదాహరణలు:

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

Merkle Patricia trieలో నోడ్‌ని పొందడానికి పొడిగించిన కోడ్ ఇక్కడ ఉంది:

1 def get_helper(node_hash, path):
2 if path == []:
3 return node_hash
4 if node_hash == "":
5 return ""
6 curnode = rlp.decode(node_hash if len(node_hash) < 32 else db.get(node_hash))
7 if len(curnode) == 2:
8 (k2, v2) = curnode
9 k2 = compact_decode(k2)
10 if k2 == path[: len(k2)]:
11 return get(v2, path[len(k2) :])
12 else:
13 return ""
14 elif len(curnode) == 17:
15 return get_helper(curnode[path[0]], path[1:])
16
17 def get(node_hash, path):
18 path2 = []
19 for i in range(len(path)):
20 path2.push(int(ord(path[i]) / 16))
21 path2.push(ord(path[i]) % 16)
22 path2.push(16)
23 return get_helper(node_hash, path2)
అన్నీ చూపించు

ఉదాహరణ ట్రై

మనం ('do', 'verb'), ('dog', 'puppy'), ('doge', 'coins'), ('horse', 'stallion') అనే నాలుగు పాత్/విలువ జతలను కలిగిన ఒక ట్రైని కోరుకుంటున్నామని అనుకుందాం.

మొదట, మనం పాత్‌లు మరియు విలువలు రెండింటినీ bytesగా మారుస్తాము. క్రింద, పాత్‌ల కోసం అసలు బైట్ రిప్రజెంటేషన్‌లు <> ద్వారా సూచించబడతాయి, అయితే విలువలు ఇప్పటికీ సులభంగా అర్థం చేసుకోవడానికి '' తో సూచించబడిన స్ట్రింగ్‌లుగా చూపబడతాయి (వాస్తవానికి అవి కూడా bytesగా ఉంటాయి):

1 <64 6f> : 'క్రియ'
2 <64 6f 67> : 'కుక్కపిల్ల'
3 <64 6f 67 65> : 'నాణేలు'
4 <68 6f 72 73 65> : 'స్టాలియన్'

ఇప్పుడు, మేము అంతర్లీన DBలో క్రింది కీ/విలువ జతలతో అటువంటి ప్రయత్నాన్ని రూపొందిస్తాము:

1 rootHash: [ <16>, hashA ]
2 hashA: [ <>, <>, <>, <>, hashB, <>, <>, <>, [ <20 6f 72 73 65>, 'స్టాలియన్' ], <>, <>, <>, <>, <>, <>, <>, <> ]
3 hashB: [ <00 6f>, hashC ]
4 hashC: [ <>, <>, <>, <>, <>, <>, hashD, <>, <>, <>, <>, <>, <>, <>, <>, <>, 'క్రియ' ]
5 hashD: [ <17>, [ <>, <>, <>, <>, <>, <>, [ <35>, 'నాణేలు' ], <>, <>, <>, <>, <>, <>, <>, <>, <>, 'కుక్కపిల్ల' ] ]

ఒక నోడ్‌ను మరొక నోడ్‌లో రిఫర్ చేసినప్పుడు, చేర్చబడేది keccak256(rlp.encode(node)), ఒకవేళ len(rlp.encode(node)) >= 32 అయితే, లేకపోతే node చేర్చబడుతుంది. ఇక్కడ rlp.encode అనేది RLP ఎన్‌కోడింగ్ ఫంక్షన్.

గమనిక: ఒక ట్రైని అప్‌డేట్ చేస్తున్నప్పుడు, కొత్తగా సృష్టించబడిన నోడ్ పొడవు >= 32 అయితే, (keccak256(x), x) కీ/విలువ జతను ఒక పర్సిస్టెంట్ లుకప్ టేబుల్‌లో నిల్వ చేయాలి. అయినప్పటికీ, నోడ్ దాని కంటే తక్కువగా ఉంటే, f(x) = x ఫంక్షన్ రివర్సబుల్ అయినందున, ఏదైనా నిల్వ చేయవలసిన అవసరం లేదు.

Ethereum లో ట్రైలు

Ethereum ఎగ్జిక్యూషన్ లేయర్‌లోని మెర్కిల్ ట్రై అంతా మెర్కిల్ ప్యాట్రిసియా ట్రైని ఉపయోగిస్తుంది.

బ్లాక్ హెడర్ నుండి ఈ ప్రయత్నాలలో 3 నుండి 3 మూలాలు ఉన్నాయి.

  1. రాష్ట్ర రూట్
  2. లావాదేవీలు రూట్
  3. రసీదులు రూట్

స్టేట్ ట్రై

ఒక గ్లోబల్ స్టేట్ ట్రై ఉంది మరియు క్లయింట్ బ్లాక్‌ను ప్రాసెస్ చేసిన ప్రతిసారీ ఇది నవీకరించబడుతుంది. దానిలో, ఒక path ఎల్లప్పుడూ: keccak256(ethereumAddress) మరియు ఒక value ఎల్లప్పుడూ: rlp(ethereumAccount). మరింత స్పష్టంగా, ఒక Ethereum account అనేది [nonce,balance,storageRoot,codeHash] యొక్క 4-ఐటెమ్ అర్రే. ఈ సమయంలో, ఈ storageRoot అనేది మరొక ప్యాట్రిసియా ట్రై యొక్క రూట్ అని గమనించడం ముఖ్యం:

స్టోరేజ్ ట్రై

స్టోరేజ్ ట్రైలోనే అన్ని కాంట్రాక్ట్ డేటా ఉంటుంది. ప్రతి ఖాతాకు ప్రత్యేక నిల్వ ప్రయత్నం ఉంది. ఇచ్చిన చిరునామాలో నిర్దిష్ట నిల్వ స్థానాల వద్ద విలువలను తిరిగి పొందడానికి నిల్వ చిరునామా, నిల్వలో నిల్వ చేయబడిన డేటా యొక్క పూర్ణాంక స్థానం మరియు బ్లాక్ ID అవసరం. వీటిని JSON-RPC APIలో నిర్వచించిన eth_getStorageAtకు ఆర్గ్యుమెంట్స్‌గా పాస్ చేయవచ్చు, ఉదా., 0x295a70b2de5e3953354a6a8344e616ed314d7251 అడ్రస్ కోసం స్టోరేజ్ స్లాట్ 0లో డేటాను తిరిగి పొందడానికి:

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 హ్యాష్‌గా పొజిషన్ లెక్కించబడుతుంది, రెండూ 32 బైట్ల పొడవుకు సున్నాలతో లెఫ్ట్-ప్యాడ్ చేయబడతాయి. ఉదాహరణకు, 0x391694e7e0b0cce554cb130d723a9d27458f9298 అడ్రస్ కోసం స్టోరేజ్ స్లాట్ 1లో డేటా యొక్క పొజిషన్:

1keccak256(decodeHex("000000000000000000000000391694e7e0b0cce554cb130d723a9d27458f9298" + "0000000000000000000000000000000000000000000000000000000000000001"))

గెత్ కన్సోల్‌లో, దీనిని ఈ క్రింది విధంగా లెక్కించవచ్చు:

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

అందువల్ల path అనేది keccak256(<6661e9d6d8b923d5bbaab1b96e1dd51ff6ea2a93520fdc9eb75d059238b8c5e9>). ఇది ఇప్పుడు మునుపటిలాగా స్టోరేజ్ ట్రై నుండి డేటాను తిరిగి పొందడానికి ఉపయోగించవచ్చు:

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"}

గమనిక: ఒక Ethereum అకౌంట్ కాంట్రాక్ట్ అకౌంట్ కాకపోతే, దాని storageRoot డిఫాల్ట్‌గా ఖాళీగా ఉంటుంది.

ట్రాన్సాక్షన్స్ ట్రై

ప్రతి బ్లాక్ కోసం ఒక ప్రత్యేక ట్రాన్సాక్షన్స్ ట్రై ఉంటుంది, ఇది మళ్లీ (key, value) జతలను నిల్వ చేస్తుంది. ఇక్కడ పాత్: rlp(transactionIndex), ఇది ఒక విలువకు అనుగుణమైన కీని సూచిస్తుంది, ఆ విలువ దీని ద్వారా నిర్ణయించబడుతుంది:

1if legacyTx:
2 value = rlp(tx)
3else:
4 value = TxType | encode(tx)

దీనిపై మరింత సమాచారం EIP 2718 (opens in a new tab) డాక్యుమెంటేషన్‌లో చూడవచ్చు.

రసీదుల ట్రై

ప్రతి బ్లాక్‌కి దాని స్వంత రసీదుల ప్రయత్నాలుంటాయి. ఇక్కడ path అనేది: rlp(transactionIndex). transactionIndex అనేది అది చేర్చబడిన బ్లాక్‌లోని దాని ఇండెక్స్. రసీదుల ప్రయత్నం ఎప్పుడూ నవీకరించబడదు. లావాదేవీల ప్రయత్నాల మాదిరిగానే, ప్రస్తుత మరియు లెగసీ రసీదులు ఉన్నాయి. రసీదుల ట్రైలో నిర్దిష్ట రసీదుని ప్రశ్నించడానికి, దాని బ్లాక్‌లో లావాదేవీ యొక్క సూచిక, రసీదు పేలోడ్ మరియు లావాదేవీ రకం అవసరం. తిరిగి వచ్చిన రసీదు Receipt రకానికి చెంది ఉండవచ్చు, ఇది TransactionType మరియు ReceiptPayload యొక్క కలయికగా నిర్వచించబడింది లేదా అది LegacyReceipt రకానికి చెంది ఉండవచ్చు, ఇది rlp([status, cumulativeGasUsed, logsBloom, logs])గా నిర్వచించబడింది.

దీనిపై మరింత సమాచారం EIP 2718 (opens in a new tab) డాక్యుమెంటేషన్‌లో చూడవచ్చు.

మరింత చదవడానికి

ఈ ఆర్టికల్ ఉపయోగపడిందా?