மெர்க்கல் பாட்ரிசியா ட்ரை
பக்கம் கடைசியாகப் புதுப்பிக்கப்பட்டது: 26 பிப்ரவரி, 2026
Ethereum இன் நிலை (அனைத்து கணக்குகள், நிலுவைகள் மற்றும் ஸ்மார்ட் ஒப்பந்தங்களின் ஒட்டுமொத்த தொகுப்பு), கணினி அறிவியலில் பொதுவாக மெர்க்கல் ட்ரீ (Merkle Tree) என்று அழைக்கப்படும் தரவு கட்டமைப்பின் சிறப்புப் பதிப்பாக குறியாக்கம் செய்யப்பட்டுள்ளது. இந்த கட்டமைப்பு கிரிப்டோகிராஃபியில் பல பயன்பாடுகளுக்கு பயனுள்ளதாக இருக்கும், ஏனெனில் இது மரத்தில் உள்ள அனைத்து தனிப்பட்ட தரவுத் துண்டுகளுக்கும் இடையே சரிபார்க்கக்கூடிய உறவை உருவாக்குகிறது, இதன் விளைவாக தரவைப் பற்றிய விஷயங்களை நிரூபிக்கப் பயன்படுத்தக்கூடிய ஒற்றை ரூட் (root) மதிப்பு கிடைக்கிறது.
Ethereum இன் தரவு கட்டமைப்பு ஒரு 'மாற்றியமைக்கப்பட்ட மெர்க்கல்-பாட்ரிசியா ட்ரை (modified Merkle-Patricia Trie)' ஆகும், இது PATRICIA (the Practical Algorithm To Retrieve Information Coded in Alphanumeric) இன் சில அம்சங்களை கடன் வாங்குவதாலும், Ethereum நிலையை உள்ளடக்கிய உருப்படிகளின் திறமையான தரவு மீட்டெடுப்பிற்காக (retrieval) வடிவமைக்கப்பட்டுள்ளதாலும் இவ்வாறு பெயரிடப்பட்டது.
ஒரு மெர்க்கல்-பாட்ரிசியா ட்ரை தீர்மானிக்கக்கூடியது மற்றும் கிரிப்டோகிராஃபிக் முறையில் சரிபார்க்கக்கூடியது: ஒரு நிலை ரூட்டை (state root) உருவாக்குவதற்கான ஒரே வழி, நிலையின் ஒவ்வொரு தனிப்பட்ட பகுதியிலிருந்தும் அதைக் கணக்கிடுவதாகும், மேலும் ஒரே மாதிரியான இரண்டு நிலைகளை ரூட் ஹாஷ் மற்றும் அதற்கு வழிவகுத்த ஹாஷ்களை ஒப்பிடுவதன் மூலம் எளிதாக நிரூபிக்க முடியும் (ஒரு மெர்க்கல் சான்று). மாறாக, ஒரே ரூட் ஹாஷுடன் இரண்டு வெவ்வேறு நிலைகளை உருவாக்க எந்த வழியும் இல்லை, மேலும் வெவ்வேறு மதிப்புகளுடன் நிலையை மாற்றியமைக்கும் எந்தவொரு முயற்சியும் வேறுபட்ட நிலை ரூட் ஹாஷை விளைவிக்கும். கோட்பாட்டளவில், இந்த கட்டமைப்பு செருகுதல்கள், தேடல்கள் மற்றும் நீக்குதல்களுக்கு O(log(n)) செயல்திறனின் 'புனித கிரெயிலை (holy grail)' வழங்குகிறது.
எதிர்காலத்தில், Ethereum ஒரு Verkle Tree கட்டமைப்பிற்கு மாற திட்டமிட்டுள்ளது, இது எதிர்கால நெறிமுறை மேம்பாடுகளுக்கு பல புதிய சாத்தியங்களைத் திறக்கும்.
முன்நிபந்தனைகள்
இந்தப் பக்கத்தை நன்கு புரிந்துகொள்ள, ஹாஷ்கள் (hashes) (opens in a new tab), மெர்க்கல் மரங்கள் (Merkle trees) (opens in a new tab), ட்ரைஸ் (tries) (opens in a new tab) மற்றும் தொடராக்கம் (serialization) (opens in a new tab) பற்றிய அடிப்படை அறிவு இருப்பது உதவியாக இருக்கும். இந்தக் கட்டுரை ஒரு அடிப்படை ராடிக்ஸ் மரத்தின் (radix tree) (opens in a new tab) விளக்கத்துடன் தொடங்குகிறது, பின்னர் Ethereum இன் மிகவும் உகந்த தரவு கட்டமைப்பிற்குத் தேவையான மாற்றங்களை படிப்படியாக அறிமுகப்படுத்துகிறது.
அடிப்படை ராடிக்ஸ் ட்ரைஸ்
ஒரு அடிப்படை ராடிக்ஸ் ட்ரையில், ஒவ்வொரு முனையும் (node) பின்வருமாறு இருக்கும்:
1 [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 இல் ரூட் ஹாஷைத் தேடுவதன் மூலம் தொடங்குகிறீர்கள். இது மற்ற முனைகளைச் சுட்டிக்காட்டும் விசைகளின் வரிசையாகக் குறிக்கப்படுகிறது. குறியீட்டு 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] * 173 newnode = curnode.copy()4 if path == "":5 newnode[-1] = value6 else:7 newindex = update(curnode[path[0]], path[1:], value)8 newnode[path[0]] = newindex9 db.put(hash(newnode), newnode)10 return hash(newnode)1112 def delete(node_hash, path):13 if node_hash is NULL:14 return NULL15 else:16 curnode = db.get(node_hash)17 newnode = curnode.copy()18 if path == "":19 newnode[-1] = NULL20 else:21 newindex = delete(curnode[path[0]], path[1:])22 newnode[path[0]] = newindex2324 if all(x is NULL for x in newnode):25 return NULL26 else:27 db.put(hash(newnode), newnode)28 return hash(newnode)அனைத்தையும் காட்டுஒரு "மெர்க்கல்" ராடிக்ஸ் மரம் தீர்மானிக்கக்கூடிய வகையில் உருவாக்கப்பட்ட கிரிப்டோகிராஃபிக் ஹாஷ் டைஜெஸ்ட்களைப் பயன்படுத்தி முனைகளை இணைப்பதன் மூலம் கட்டப்பட்டுள்ளது. இந்த உள்ளடக்க-முகவரியிடல் (விசை/மதிப்பு DB இல் key == keccak256(rlp(value))) சேமிக்கப்பட்ட தரவின் கிரிப்டோகிராஃபிக் ஒருமைப்பாடு உத்தரவாதத்தை வழங்குகிறது. கொடுக்கப்பட்ட ட்ரையின் ரூட் ஹாஷ் பொதுவில் தெரிந்தால், அடிப்படை இலைத் தரவை அணுகக்கூடிய எவரும், மரத்தின் ரூட்டுடன் ஒரு குறிப்பிட்ட மதிப்பை இணைக்கும் ஒவ்வொரு முனையின் ஹாஷ்களையும் வழங்குவதன் மூலம், ட்ரை ஒரு குறிப்பிட்ட பாதையில் கொடுக்கப்பட்ட மதிப்பை உள்ளடக்கியுள்ளது என்பதற்கான ஆதாரத்தை உருவாக்க முடியும்.
ரூட் ஹாஷ் இறுதியில் அதன் கீழே உள்ள அனைத்து ஹாஷ்களையும் அடிப்படையாகக் கொண்டிருப்பதால், இல்லாத (path, value) ஜோடிக்கான ஆதாரத்தை தாக்குபவர் வழங்குவது சாத்தியமற்றது. எந்தவொரு அடிப்படை மாற்றமும் ரூட் ஹாஷை மாற்றும். ஹாஷிங் செயல்பாட்டின் முன்-படப் பாதுகாப்பால் (pre-image protection) பாதுகாக்கப்பட்ட தரவைப் பற்றிய கட்டமைப்புத் தகவலின் சுருக்கப்பட்ட பிரதிநிதித்துவமாக ஹாஷை நீங்கள் நினைக்கலாம்.
ராடிக்ஸ் மரத்தின் அணு அலகு (எ.கா., ஒற்றை ஹெக்ஸ் எழுத்து அல்லது 4 பிட் பைனரி எண்) "நிப்பிள் (nibble)" என்று குறிப்பிடுவோம். மேலே விவரிக்கப்பட்டுள்ளபடி, ஒரு நேரத்தில் ஒரு நிப்பிள் பாதையைக் கடக்கும்போது, முனைகள் அதிகபட்சமாக 16 குழந்தைகளைக் குறிக்கலாம் ஆனால் ஒரு value உறுப்பை உள்ளடக்கியிருக்கும். எனவே, அவற்றை 17 நீளமுள்ள வரிசையாகக் குறிக்கிறோம். இந்த 17-உறுப்பு வரிசைகளை "கிளை முனைகள் (branch nodes)" என்று அழைக்கிறோம்.
மெர்க்கல் பாட்ரிசியா ட்ரை
ராடிக்ஸ் ட்ரைஸ் ஒரு முக்கிய வரம்பைக் கொண்டுள்ளது: அவை திறனற்றவை. Ethereum ஐப் போல, பாதை 64 எழுத்துக்கள் நீளமாக (bytes32 இல் உள்ள நிப்பிள்களின் எண்ணிக்கை) இருக்கும் ஒரு (path, value) பிணைப்பை நீங்கள் சேமிக்க விரும்பினால், ஒரு எழுத்துக்கு ஒரு நிலையைச் சேமிக்க ஒரு கிலோபைட்டுக்கும் அதிகமான கூடுதல் இடம் தேவைப்படும், மேலும் ஒவ்வொரு தேடலும் அல்லது நீக்குதலும் முழு 64 படிகளை எடுக்கும். பின்வருவனவற்றில் அறிமுகப்படுத்தப்பட்ட பாட்ரிசியா ட்ரை இந்த சிக்கலை தீர்க்கிறது.
உகப்பாக்கம்
மெர்க்கல் பாட்ரிசியா ட்ரையில் உள்ள ஒரு முனை பின்வருவனவற்றில் ஒன்றாகும்:
NULL(வெற்று சரமாகக் குறிக்கப்படுகிறது)branchஒரு 17-உருப்படி முனை[ v0 ... v15, vt ]leafஒரு 2-உருப்படி முனை[ encodedPath, value ]extensionஒரு 2-உருப்படி முனை[ encodedPath, key ]
64 எழுத்து பாதைகளுடன், ட்ரையின் முதல் சில அடுக்குகளைக் கடந்த பிறகு, குறைந்தபட்சம் ஒரு பகுதிக்காவது வேறுபட்ட பாதை இல்லாத ஒரு முனையை நீங்கள் அடைவீர்கள் என்பது தவிர்க்க முடியாதது. பாதையில் 15 சிதறிய NULL முனைகளை உருவாக்குவதைத் தவிர்க்க, [ encodedPath, key ] வடிவத்தின் extension முனையை அமைப்பதன் மூலம் இறங்குதலைக் குறுக்குவழி செய்கிறோம், அங்கு encodedPath முன்னோக்கித் தவிர்ப்பதற்கான "பகுதி பாதையை" கொண்டுள்ளது (கீழே விவரிக்கப்பட்டுள்ள சுருக்கமான குறியாக்கத்தைப் பயன்படுத்தி), மற்றும் key அடுத்த DB தேடலுக்கானது.
encodedPath இன் முதல் நிப்பிளில் ஒரு கொடியால் குறிக்கப்படக்கூடிய leaf முனைக்கு, பாதை முந்தைய அனைத்து முனையின் பாதை துண்டுகளையும் குறியாக்குகிறது மற்றும் நாம் value ஐ நேரடியாகப் பார்க்கலாம்.
இருப்பினும், மேலே உள்ள இந்த உகப்பாக்கம் தெளிவின்மையை அறிமுகப்படுத்துகிறது.
நிப்பிள்களில் பாதைகளைக் கடக்கும்போது, நாம் கடக்க ஒற்றைப்படை எண்ணிக்கையிலான நிப்பிள்களைப் பெறலாம், ஆனால் எல்லா தரவும் bytes வடிவத்தில் சேமிக்கப்படுவதால். எடுத்துக்காட்டாக, நிப்பிள் 1 மற்றும் நிப்பிள்கள் 01 ஆகியவற்றுக்கு இடையே வேறுபாடு காண்பது சாத்தியமில்லை (இரண்டும் <01> ஆக சேமிக்கப்பட வேண்டும்). ஒற்றைப்படை நீளத்தைக் குறிப்பிட, பகுதி பாதை ஒரு கொடியுடன் முன்னொட்டப்பட்டுள்ளது.
விவரக்குறிப்பு: விருப்பமான டெர்மினேட்டருடன் ஹெக்ஸ் வரிசையின் சுருக்கமான குறியாக்கம்
மேலே விவரிக்கப்பட்டுள்ளபடி ஒற்றைப்படை மற்றும் இரட்டைப்படை மீதமுள்ள பகுதி பாதை நீளம் மற்றும் இலை மற்றும் நீட்டிப்பு முனை ஆகிய இரண்டின் கொடியிடல் எந்த 2-உருப்படி முனையின் பகுதி பாதையின் முதல் நிப்பிளில் உள்ளது. அவை பின்வருவனவற்றை விளைவிக்கின்றன:
| ஹெக்ஸ் எழுத்து | பிட்கள் | முனை வகை பகுதி | பாதை நீளம் |
|---|---|---|---|
| 0 | 0000 | நீட்டிப்பு (extension) | இரட்டைப்படை |
| 1 | 0001 | நீட்டிப்பு (extension) | ஒற்றைப்படை |
| 2 | 0010 | முடித்தல் (இலை) | இரட்டைப்படை |
| 3 | 0011 | முடித்தல் (இலை) | ஒற்றைப்படை |
இரட்டைப்படை மீதமுள்ள பாதை நீளத்திற்கு (0 அல்லது 2), மற்றொரு 0 "பேடிங் (padding)" நிப்பிள் எப்போதும் தொடரும்.
1 def compact_encode(hexarray):2 term = 1 if hexarray[-1] == 16 else 03 if term:4 hexarray = hexarray[:-1]5 oddlen = len(hexarray) % 26 flags = 2 * term + oddlen7 if oddlen:8 hexarray = [flags] + hexarray9 else:10 hexarray = [flags] + [0] + hexarray11 # hexarray இப்போது இரட்டைப்படை நீளத்தைக் கொண்டுள்ளது, அதன் முதல் நிப்பிள் கொடிகளாகும்.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'மெர்க்கல் பாட்ரிசியா ட்ரையில் ஒரு முனையைப் பெறுவதற்கான நீட்டிக்கப்பட்ட குறியீடு இங்கே:
1 def get_helper(node_hash, path):2 if path == []:3 return node_hash4 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) = curnode9 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:])1617 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> : 'verb'2 <64 6f 67> : 'puppy'3 <64 6f 67 65> : 'coins'4 <68 6f 72 73 65> : 'stallion'இப்போது, அடிப்படை DB இல் பின்வரும் விசை/மதிப்பு ஜோடிகளுடன் அத்தகைய ட்ரையை உருவாக்குகிறோம்:
1 rootHash: [ <16>, hashA ]2 hashA: [ <>, <>, <>, <>, hashB, <>, <>, <>, [ <20 6f 72 73 65>, 'stallion' ], <>, <>, <>, <>, <>, <>, <>, <> ]3 hashB: [ <00 6f>, hashC ]4 hashC: [ <>, <>, <>, <>, <>, <>, hashD, <>, <>, <>, <>, <>, <>, <>, <>, <>, 'verb' ]5 hashD: [ <17>, [ <>, <>, <>, <>, <>, <>, [ <35>, 'coins' ], <>, <>, <>, <>, <>, <>, <>, <>, <>, 'puppy' ] ]ஒரு முனை மற்றொரு முனையின் உள்ளே குறிப்பிடப்படும்போது, len(rlp.encode(node)) >= 32 ஆக இருந்தால் keccak256(rlp.encode(node)) சேர்க்கப்படும், இல்லையெனில் node சேர்க்கப்படும், இங்கு rlp.encode என்பது RLP குறியாக்கச் செயல்பாடாகும்.
ஒரு ட்ரையைப் புதுப்பிக்கும்போது, புதிதாக உருவாக்கப்பட்ட முனையின் நீளம் >= 32 ஆக இருந்தால், விசை/மதிப்பு ஜோடியை (keccak256(x), x) ஒரு நிலையான தேடல் அட்டவணையில் சேமிக்க வேண்டும் என்பதை நினைவில் கொள்ளவும். இருப்பினும், முனை அதை விடக் குறைவாக இருந்தால், f(x) = x என்ற செயல்பாடு மீளக்கூடியது என்பதால், எதையும் சேமிக்க வேண்டியதில்லை.
Ethereum இல் ட்ரைஸ்
Ethereum இன் செயலாக்க அடுக்கில் உள்ள அனைத்து மெர்க்கல் ட்ரைஸ்களும் மெர்க்கல் பாட்ரிசியா ட்ரையைப் பயன்படுத்துகின்றன.
ஒரு தொகுதி தலைப்பிலிருந்து (block header) இந்த 3 ட்ரைஸ்களிலிருந்து 3 ரூட்கள் உள்ளன.
- stateRoot
- transactionsRoot
- receiptsRoot
நிலை ட்ரை (State Trie)
ஒரு உலகளாவிய நிலை ட்ரை (global state trie) உள்ளது, மேலும் ஒவ்வொரு முறையும் ஒரு கிளையன்ட் ஒரு தொகுதியைச் செயலாக்கும்போது அது புதுப்பிக்கப்படும். இதில், ஒரு path எப்போதும்: keccak256(ethereumAddress) மற்றும் ஒரு value எப்போதும்: rlp(ethereumAccount). இன்னும் குறிப்பாக ஒரு Ethereum account என்பது [nonce,balance,storageRoot,codeHash] இன் 4 உருப்படி வரிசையாகும். இந்த கட்டத்தில், இந்த storageRoot மற்றொரு பாட்ரிசியா ட்ரையின் ரூட் என்பதைக் கவனத்தில் கொள்ள வேண்டும்:
சேமிப்பக ட்ரை (Storage Trie)
சேமிப்பக ட்ரை என்பது அனைத்து ஒப்பந்தத் தரவுகளும் வாழும் இடமாகும். ஒவ்வொரு கணக்கிற்கும் தனித்தனி சேமிப்பக ட்ரை உள்ளது. கொடுக்கப்பட்ட முகவரியில் குறிப்பிட்ட சேமிப்பக நிலைகளில் மதிப்புகளை மீட்டெடுக்க, சேமிப்பக முகவரி, சேமிப்பகத்தில் சேமிக்கப்பட்ட தரவின் முழு எண் நிலை மற்றும் தொகுதி ஐடி (block 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"))Geth கன்சோலில், இதை பின்வருமாறு கணக்கிடலாம்:
1> var key = "000000000000000000000000391694e7e0b0cce554cb130d723a9d27458f9298" + "0000000000000000000000000000000000000000000000000000000000000001"2undefined3> 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 அது ஒரு ஒப்பந்தக் கணக்காக இல்லாவிட்டால் இயல்பாகவே காலியாக இருக்கும்.
பரிவர்த்தனைகள் ட்ரை (Transactions Trie)
ஒவ்வொரு தொகுதிக்கும் தனித்தனி பரிவர்த்தனைகள் ட்ரை உள்ளது, மீண்டும் (key, value) ஜோடிகளைச் சேமிக்கிறது. இங்கு ஒரு பாதை: rlp(transactionIndex) இது பின்வருவனவற்றால் தீர்மானிக்கப்படும் மதிப்பிற்கு ஒத்த விசையைக் குறிக்கிறது:
1if legacyTx:2 value = rlp(tx)3else:4 value = TxType | encode(tx)இது பற்றிய கூடுதல் தகவல்களை EIP 2718 (opens in a new tab) ஆவணத்தில் காணலாம்.
ரசீதுகள் ட்ரை (Receipts Trie)
ஒவ்வொரு தொகுதியும் அதன் சொந்த ரசீதுகள் ட்ரையைக் கொண்டுள்ளது. இங்கு ஒரு path: rlp(transactionIndex). transactionIndex என்பது அது சேர்க்கப்பட்ட தொகுதிக்குள் அதன் குறியீடாகும். ரசீதுகள் ட்ரை ஒருபோதும் புதுப்பிக்கப்படாது. பரிவர்த்தனைகள் ட்ரையைப் போலவே, தற்போதைய மற்றும் மரபு ரசீதுகள் உள்ளன. ரசீதுகள் ட்ரையில் ஒரு குறிப்பிட்ட ரசீதை வினவ, அதன் தொகுதியில் உள்ள பரிவர்த்தனையின் குறியீடு, ரசீது பேலோட் மற்றும் பரிவர்த்தனை வகை ஆகியவை தேவை. திரும்பப் பெறப்பட்ட ரசீது Receipt வகையாக இருக்கலாம், இது TransactionType மற்றும் ReceiptPayload ஆகியவற்றின் இணைப்பாக வரையறுக்கப்படுகிறது அல்லது இது LegacyReceipt வகையாக இருக்கலாம், இது rlp([status, cumulativeGasUsed, logsBloom, logs]) என வரையறுக்கப்படுகிறது.
இது பற்றிய கூடுதல் தகவல்களை EIP 2718 (opens in a new tab) ஆவணத்தில் காணலாம்.