మెర్కిల్ ప్యాట్రిసియా ట్రై
ఎథీరియం యొక్క స్థితి (అన్ని ఖాతాలు, నిల్వలు మరియు స్మార్ట్ కాంట్రాక్ట్ల మొత్తం), కంప్యూటర్ సైన్స్లో సాధారణంగా మెర్కిల్ వృక్షం (Merkle Tree) అని పిలువబడే డేటా నిర్మాణం యొక్క ప్రత్యేక వెర్షన్గా ఎన్కోడ్ చేయబడుతుంది. గూఢలిపి శాస్త్రంలో అనేక అనువర్తనాలకు ఈ నిర్మాణం ఉపయోగపడుతుంది, ఎందుకంటే ఇది వృక్షంలో చిక్కుకున్న అన్ని వ్యక్తిగత డేటా ముక్కల మధ్య ధృవీకరించదగిన సంబంధాన్ని సృష్టిస్తుంది, దీని ఫలితంగా డేటా గురించి విషయాలను నిరూపించడానికి ఉపయోగపడే ఒకే రూట్ (root) విలువ ఏర్పడుతుంది.
ఎథీరియం యొక్క డేటా నిర్మాణం ఒక 'సవరించిన మెర్కిల్ ప్యాట్రిసియా ట్రై', దీనికి ఆ పేరు ఎందుకు వచ్చిందంటే ఇది PATRICIA (the Practical Algorithm To Retrieve Information Coded in Alphanumeric) యొక్క కొన్ని లక్షణాలను తీసుకుంటుంది మరియు ఎథీరియం స్థితిని కలిగి ఉన్న అంశాల యొక్క సమర్థవంతమైన డేటా పునరుద్ధరణ (retrieval) కోసం ఇది రూపొందించబడింది.
మెర్కిల్ ప్యాట్రిసియా ట్రై అనేది నిర్ణయాత్మకమైనది మరియు గూఢలిపి శాస్త్రపరంగా ధృవీకరించదగినది: స్థితి రూట్ను రూపొందించడానికి ఏకైక మార్గం స్థితి యొక్క ప్రతి వ్యక్తిగత భాగం నుండి దానిని లెక్కించడం, మరియు ఒకేలా ఉన్న రెండు స్థితులను రూట్ హాష్ మరియు దానికి దారితీసిన హాష్లను పోల్చడం ద్వారా సులభంగా నిరూపించవచ్చు (ఒక మెర్కిల్ ప్రూఫ్). దీనికి విరుద్ధంగా, ఒకే రూట్ హాష్తో రెండు వేర్వేరు స్థితులను సృష్టించడానికి మార్గం లేదు, మరియు వేర్వేరు విలువల ద్వారా స్థితిని సవరించడానికి చేసే ఏ ప్రయత్నమైనా వేరొక స్థితి రూట్ హాష్కు దారి తీస్తుంది. సైద్ధాంతికంగా, ఈ నిర్మాణం చొప్పించడం, వెతకడం మరియు తొలగించడం కోసం O(log(n)) సామర్థ్యం యొక్క 'అత్యుత్తమ పరిష్కారాన్ని (holy grail)' అందిస్తుంది.
సమీప భవిష్యత్తులో, ఎథీరియం వెర్కిల్ వృక్షం (Verkle Tree) నిర్మాణానికి మారాలని యోచిస్తోంది, ఇది భవిష్యత్తులో ప్రోటోకాల్ మెరుగుదలల కోసం అనేక కొత్త అవకాశాలను తెరుస్తుంది.
ముందస్తు అవసరాలు
ఈ పేజీని బాగా అర్థం చేసుకోవడానికి, హాష్లు (opens in a new tab), మెర్కిల్ వృక్షాలు (opens in a new tab), ట్రైలు (opens in a new tab) మరియు శ్రేణీకరణ (opens in a new tab) గురించి ప్రాథమిక జ్ఞానం కలిగి ఉండటం సహాయకరంగా ఉంటుంది. ఈ కథనం ప్రాథమిక రాడిక్స్ వృక్షం (radix tree) (opens in a new tab) యొక్క వివరణతో ప్రారంభమవుతుంది, ఆపై ఎథీరియం యొక్క మరింత ఆప్టిమైజ్ చేయబడిన డేటా నిర్మాణానికి అవసరమైన మార్పులను క్రమంగా పరిచయం చేస్తుంది.
ప్రాథమిక రాడిక్స్ ట్రైలు
ప్రాథమిక రాడిక్స్ ట్రైలో, ప్రతి నోడ్ ఈ క్రింది విధంగా కనిపిస్తుంది:
[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 గా సూచిద్దాం.
రాడిక్స్ ట్రైల కోసం నవీకరణ మరియు తొలగింపు కార్యకలాపాలను ఈ క్రింది విధంగా నిర్వచించవచ్చు:
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)) లో) నిల్వ చేయబడిన డేటా యొక్క గూఢలిపి సమగ్రత హామీని అందిస్తుంది. ఇచ్చిన ట్రై యొక్క రూట్ హాష్ పబ్లిక్గా తెలిస్తే, అంతర్లీన లీఫ్ డేటాకు ప్రాప్యత ఉన్న ఎవరైనా వృక్షం రూట్కు నిర్దిష్ట విలువను చేర్చే ప్రతి నోడ్ యొక్క హాష్లను అందించడం ద్వారా ట్రై నిర్దిష్ట మార్గంలో ఇచ్చిన విలువను కలిగి ఉందని రుజువును నిర్మించవచ్చు.
ఉనికిలో లేని (path, value) జత యొక్క రుజువును దాడి చేసే వ్యక్తి అందించడం అసాధ్యం ఎందుకంటే రూట్ హాష్ అంతిమంగా దాని క్రింద ఉన్న అన్ని హాష్లపై ఆధారపడి ఉంటుంది. ఏదైనా అంతర్లీన మార్పు రూట్ హాష్ను మారుస్తుంది. హాషింగ్ ఫంక్షన్ యొక్క ప్రీ-ఇమేజ్ రక్షణ ద్వారా సురక్షితం చేయబడిన డేటా గురించిన నిర్మాణ సమాచారం యొక్క కుదించబడిన ప్రాతినిధ్యంగా మీరు హాష్ను భావించవచ్చు.
రాడిక్స్ వృక్షం యొక్క పరమాణు యూనిట్ను (ఉదా., ఒకే హెక్స్ అక్షరం లేదా 4 బిట్ బైనరీ సంఖ్య) మనం "నిబుల్ (nibble)" అని పిలుస్తాము. పైన వివరించిన విధంగా ఒకేసారి ఒక నిబుల్ మార్గంలో ప్రయాణిస్తున్నప్పుడు, నోడ్లు గరిష్టంగా 16 పిల్లలను సూచించగలవు కానీ value మూలకాన్ని కలిగి ఉంటాయి. అందువల్ల, మేము వాటిని 17 పొడవు గల శ్రేణిగా సూచిస్తాము. ఈ 17-మూలకాల శ్రేణులను మనం "బ్రాంచ్ నోడ్స్ (branch nodes)" అని పిలుస్తాము.
మెర్కిల్ ప్యాట్రిసియా ట్రై
రాడిక్స్ ట్రైలకు ఒక ప్రధాన పరిమితి ఉంది: అవి అసమర్థమైనవి. ఎథీరియంలో వలె మార్గం 64 అక్షరాల పొడవు (bytes32 లోని నిబుల్స్ సంఖ్య) ఉన్న ఒక (path, value) బైండింగ్ను మీరు నిల్వ చేయాలనుకుంటే, ఒక్కో అక్షరానికి ఒక స్థాయిని నిల్వ చేయడానికి మనకు కిలోబైట్ కంటే ఎక్కువ అదనపు స్థలం అవసరం, మరియు ప్రతి వెతుకులాట లేదా తొలగింపు పూర్తి 64 దశలను తీసుకుంటుంది. క్రింద పరిచయం చేయబడిన ప్యాట్రిసియా ట్రై ఈ సమస్యను పరిష్కరిస్తుంది.
ఆప్టిమైజేషన్
మెర్కిల్ ప్యాట్రిసియా ట్రైలోని నోడ్ కింది వాటిలో ఒకటి:
NULL(ఖాళీ స్ట్రింగ్గా సూచించబడుతుంది)branch17-అంశాల నోడ్[ v0 ... v15, vt ]leaf2-అంశాల నోడ్[ encodedPath, value ]extension2-అంశాల నోడ్[ encodedPath, key ]
64 అక్షరాల మార్గాలతో, ట్రై యొక్క మొదటి కొన్ని పొరలను దాటిన తర్వాత, కనీసం కొంత దూరం వరకు ఎటువంటి భిన్నమైన మార్గం లేని నోడ్ను మీరు చేరుకోవడం అనివార్యం. మార్గంలో 15 వరకు అరుదైన NULL నోడ్లను సృష్టించడాన్ని నివారించడానికి, మేము [ encodedPath, key ] రూపంలో extension నోడ్ను సెటప్ చేయడం ద్వారా అవరోహణను షార్ట్కట్ చేస్తాము, ఇక్కడ encodedPath ముందుకు దాటవేయడానికి "పాక్షిక మార్గాన్ని" కలిగి ఉంటుంది (క్రింద వివరించిన కాంపాక్ట్ ఎన్కోడింగ్ని ఉపయోగించి), మరియు key తదుపరి DB వెతుకులాట కోసం ఉంటుంది.
encodedPath యొక్క మొదటి నిబుల్లో ఫ్లాగ్ ద్వారా గుర్తించబడే leaf నోడ్ కోసం, మార్గం మునుపటి నోడ్ యొక్క అన్ని మార్గ శకలాలను ఎన్కోడ్ చేస్తుంది మరియు మనం నేరుగా value ని వెతకవచ్చు.
అయితే, పైన పేర్కొన్న ఆప్టిమైజేషన్ అస్పష్టతను పరిచయం చేస్తుంది.
నిబుల్స్లో మార్గాలను ప్రయాణిస్తున్నప్పుడు, మనం ప్రయాణించడానికి బేసి సంఖ్యలో నిబుల్స్ను కలిగి ఉండవచ్చు, కానీ మొత్తం డేటా bytes ఆకృతిలో నిల్వ చేయబడుతుంది కాబట్టి. ఉదాహరణకు, నిబుల్ 1 మరియు నిబుల్స్ 01 మధ్య తేడాను గుర్తించడం సాధ్యం కాదు (రెండూ <01> గా నిల్వ చేయబడాలి). బేసి పొడవును పేర్కొనడానికి, పాక్షిక మార్గానికి ఫ్లాగ్ ముందుగా జోడించబడుతుంది.
స్పెసిఫికేషన్: ఐచ్ఛిక టెర్మినేటర్తో హెక్స్ క్రమం యొక్క కాంపాక్ట్ ఎన్కోడింగ్
పైన వివరించిన విధంగా బేసి వర్సెస్ సరి మిగిలిన పాక్షిక మార్గం పొడవు మరియు లీఫ్ వర్సెస్ ఎక్స్టెన్షన్ నోడ్ రెండింటి ఫ్లాగింగ్ ఏదైనా 2-అంశాల నోడ్ యొక్క పాక్షిక మార్గం యొక్క మొదటి నిబుల్లో ఉంటుంది. అవి కింది వాటికి దారితీస్తాయి:
| హెక్స్ అక్షరం | బిట్స్ | నోడ్ రకం పాక్షికం | మార్గం పొడవు |
|---|---|---|---|
| 0 | 0000 | ఎక్స్టెన్షన్ | సరి |
| 1 | 0001 | ఎక్స్టెన్షన్ | బేసి |
| 2 | 0010 | టెర్మినేటింగ్ (లీఫ్) | సరి |
| 3 | 0011 | టెర్మినేటింగ్ (లీఫ్) | బేసి |
సరి మిగిలిన మార్గం పొడవు కోసం (0 లేదా 2), మరొక 0 "ప్యాడింగ్" నిబుల్ ఎల్లప్పుడూ అనుసరిస్తుంది.
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
ఉదాహరణలు:
> [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'
మెర్కిల్ ప్యాట్రిసియా ట్రైలో నోడ్ను పొందడానికి విస్తరించిన కోడ్ ఇక్కడ ఉంది:
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)
ఉదాహరణ ట్రై
నాలుగు మార్గం/విలువ జతలు ('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 ఎన్కోడింగ్ ఫంక్షన్.
ట్రైని నవీకరిస్తున్నప్పుడు, కొత్తగా సృష్టించబడిన నోడ్ పొడవు >= 32 అయితే నిరంతర వెతుకులాట పట్టికలో కీ/విలువ జత (keccak256(x), x) ని నిల్వ చేయాలని గమనించండి. అయితే, నోడ్ అంతకంటే తక్కువగా ఉంటే, ఫంక్షన్ f(x) = x రివర్సిబుల్ కాబట్టి దేనినీ నిల్వ చేయాల్సిన అవసరం లేదు.
ఎథీరియంలో ట్రైలు
ఎథీరియం యొక్క అమలు పొరలోని అన్ని మెర్కిల్ ట్రైలు మెర్కిల్ ప్యాట్రిసియా ట్రైని ఉపయోగిస్తాయి.
బ్లాక్ శీర్షిక నుండి ఈ 3 ట్రైల నుండి 3 రూట్లు ఉంటాయి.
- stateRoot
- transactionsRoot
- receiptsRoot
స్థితి ట్రై
ఒక గ్లోబల్ స్థితి ట్రై ఉంది, మరియు క్లయింట్ బ్లాక్ను ప్రాసెస్ చేసిన ప్రతిసారీ ఇది నవీకరించబడుతుంది. దీనిలో, path ఎల్లప్పుడూ: keccak256(ethereumAddress) మరియు value ఎల్లప్పుడూ: rlp(ethereumAccount). మరింత నిర్దిష్టంగా ఎథీరియం 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లోని డేటా స్థానం:
keccak256(decodeHex("000000000000000000000000391694e7e0b0cce554cb130d723a9d27458f9298" + "0000000000000000000000000000000000000000000000000000000000000001"))
గో ఇథీరియం (గెత్) కన్సోల్లో, దీన్ని ఈ క్రింది విధంగా లెక్కించవచ్చు:
> var key = "000000000000000000000000391694e7e0b0cce554cb130d723a9d27458f9298" + "0000000000000000000000000000000000000000000000000000000000000001"
undefined
> web3.sha3(key, {"encoding": "hex"})
"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"}
గమనిక: ఎథీరియం ఖాతా కాంట్రాక్ట్ ఖాతా కాకపోతే దాని కోసం storageRoot అప్రమేయంగా ఖాళీగా ఉంటుంది.
లావాదేవీల ట్రై
ప్రతి బ్లాక్కు ప్రత్యేక లావాదేవీల ట్రై ఉంటుంది, ఇది మళ్లీ (key, value) జతలను నిల్వ చేస్తుంది. ఇక్కడ ఒక మార్గం: rlp(transactionIndex) ఇది దీని ద్వారా నిర్ణయించబడిన విలువకు అనుగుణంగా ఉండే కీని సూచిస్తుంది:
if legacyTx:
value = rlp(tx)
else:
value = TxType | encode(tx)
దీనిపై మరింత సమాచారం EIP-2718 (opens in a new tab) డాక్యుమెంటేషన్లో కనుగొనవచ్చు.
రశీదుల ట్రై
ప్రతి బ్లాక్కు దాని స్వంత రశీదుల ట్రై ఉంటుంది. ఇక్కడ path అనేది: rlp(transactionIndex). transactionIndex అనేది అది చేర్చబడిన బ్లాక్లోని దాని సూచిక. రశీదుల ట్రై ఎప్పుడూ నవీకరించబడదు. లావాదేవీల ట్రై మాదిరిగానే, ప్రస్తుత మరియు పాత (legacy) రశీదులు ఉంటాయి. రశీదుల ట్రైలో నిర్దిష్ట రశీదును ప్రశ్నించడానికి, దాని బ్లాక్లోని లావాదేవీ యొక్క సూచిక, రశీదు పేలోడ్ మరియు లావాదేవీ రకం అవసరం. తిరిగి వచ్చిన రశీదు Receipt రకానికి చెందినది కావచ్చు, ఇది TransactionType మరియు ReceiptPayload ల కలయికగా నిర్వచించబడింది లేదా ఇది rlp([status, cumulativeGasUsed, logsBloom, logs]) గా నిర్వచించబడిన LegacyReceipt రకానికి చెందినది కావచ్చు.
దీనిపై మరింత సమాచారం EIP-2718 (opens in a new tab) డాక్యుమెంటేషన్లో కనుగొనవచ్చు.