सिंपल सिरीअलाइझ
पृष्ठ अखेरचे अद्यतन: १ फेब्रुवारी, २०२६
सिंपल सिरीअलाइझ (SSZ) ही बीकन चेनवर वापरली जाणारी सिरीअलायझेशन पद्धत आहे. हे, पीअर डिस्कव्हरी प्रोटोकॉल वगळता, कन्सेंसस लेयरवर सर्वत्र एक्झिक्यूशन लेयरवर वापरल्या जाणार्या RLP सिरीअलायझेशनची जागा घेते. RLP सिरीअलायझेशनबद्दल अधिक जाणून घेण्यासाठी, रिकर्सिव्ह-लेंग्थ प्रीफिक्स (RLP) पहा. SSZ डिटर्मिनिस्टिक असण्यासाठी आणि कार्यक्षमतेने मर्केलाइझ करण्यासाठी डिझाइन केलेले आहे. SSZ मध्ये दोन घटक आहेत असे मानले जाऊ शकते: एक सिरीअलायझेशन स्कीम आणि एक मर्केलायझेशन स्कीम जी सिरीअलाइझ केलेल्या डेटा स्ट्रक्चरसह कार्यक्षमतेने काम करण्यासाठी डिझाइन केलेली आहे.
SSZ कसे काम करते?
सिरीअलायझेशन
SSZ ही एक सिरीअलायझेशन स्कीम आहे जी स्वयं-वर्णन करणारी नाही - उलट ती एका स्कीमावर अवलंबून असते जी आगाऊ माहित असणे आवश्यक आहे. SSZ सिरीअलायझेशनचे ध्येय म्हणजे कोणत्याही जटिलतेच्या ऑब्जेक्ट्सना बाइट्सच्या स्ट्रिंगच्या रूपात दर्शवणे. "बेसिक टाइप्स" साठी ही एक अतिशय सोपी प्रक्रिया आहे. घटकाला फक्त हेक्साडेसिमल बाइट्समध्ये रूपांतरित केले जाते. बेसिक टाइप्समध्ये यांचा समावेश आहे:
- अनसाईन्ड इंटिजर्स
- बूलियन्स
जटिल "कंपोझिट" प्रकारांसाठी, सिरीअलायझेशन अधिक क्लिष्ट आहे कारण कंपोझिट प्रकारात अनेक घटक असतात जे भिन्न प्रकार किंवा भिन्न आकाराचे किंवा दोन्ही असू शकतात. जेव्हा या सर्व ऑब्जेक्ट्सची लांबी निश्चित असते (म्हणजे, घटकांचा आकार त्यांच्या वास्तविक मूल्यांकडे दुर्लक्ष करून नेहमी स्थिर असतो) तेव्हा सिरीअलायझेशन म्हणजे कंपोझिट प्रकारातील प्रत्येक घटकाचे लिट्ल-एंडियन बाईटस्ट्रिंगमध्ये रूपांतरण करणे होय. हे बाईटस्ट्रिंग्स एकत्र जोडले जातात. सिरीअलाइझ केलेल्या ऑब्जेक्टमध्ये निश्चित-लांबीच्या घटकांचे बाईटलिस्ट रिप्रेझेंटेशन त्याच क्रमाने असते ज्या क्रमाने ते डीसिरीअलाइझ केलेल्या ऑब्जेक्टमध्ये दिसतात.
व्हेरिएबल लांबीच्या प्रकारांसाठी, सिरीअलाइझ केलेल्या ऑब्जेक्टमधील त्या घटकाच्या स्थितीत प्रत्यक्ष डेटाला "ऑफसेट" मूल्याने बदलले जाते. प्रत्यक्ष डेटा सिरीअलाइझ केलेल्या ऑब्जेक्टच्या शेवटी एका हीपमध्ये जोडला जातो. ऑफसेट व्हॅल्यू हीपमधील प्रत्यक्ष डेटाच्या सुरूवातीसाठी इंडेक्स आहे, जो संबंधित बाइट्ससाठी पॉईंटर म्हणून काम करतो.
खालील उदाहरण स्पष्ट करते की निश्चित आणि व्हेरिएबल-लांबीच्या दोन्ही घटकांसह कंटेनरसाठी ऑफसेटिंग कसे कार्य करते:
12 struct Dummy {34 number1: u64,5 number2: u64,6 vector: Vec<u8>,7 number3: u648 }910 dummy = Dummy{1112 number1: 37,13 number2: 55,14 vector: vec![1,2,3,4],15 number3: 22,16 }1718 serialized = ssz.serialize(dummy)19सर्व दाखवाserialized ची रचना खालीलप्रमाणे असेल (येथे फक्त 4 बिट्सपर्यंत पॅड केलेले आहे, प्रत्यक्षात 32 बिट्सपर्यंत पॅड केलेले आहे आणि स्पष्टतेसाठी int रिप्रेझेंटेशन ठेवले आहे):
1[37, 0, 0, 0, 55, 0, 0, 0, 16, 0, 0, 0, 22, 0, 0, 0, 1, 2, 3, 4]2------------ ----------- ----------- ----------- ----------3 | | | | |4 नंबर1 नंबर2 वेक्टरसाठी नंबर 3 वेक्टरचे5 ऑफसेट मूल्य6स्पष्टतेसाठी ओळींमध्ये विभागलेले:
1[2 37, 0, 0, 0, # `number1` चे लिट्ल-एंडियन एन्कोडिंग.3 55, 0, 0, 0, # `number2` चे लिट्ल-एंडियन एन्कोडिंग.4 16, 0, 0, 0, # `vector` चे मूल्य कोठे सुरू होते हे दर्शवणारा "ऑफसेट" (लिट्ल-एंडियन 16).5 22, 0, 0, 0, # `number3` चे लिट्ल-एंडियन एन्कोडिंग.6 1, 2, 3, 4, # `vector` मधील वास्तविक मूल्ये.7]हे अजूनही एक सरलीकरण आहे - वरील स्कीमाटिक्समधील इंटिजर्स आणि शून्य प्रत्यक्षात बाईटलिस्ट म्हणून संग्रहित केले जातील, याप्रमाणे:
1[2 10100101000000000000000000000000 # `number1` चे लिट्ल-एंडियन एन्कोडिंग3 10110111000000000000000000000000 # `number2` चे लिट्ल-एंडियन एन्कोडिंग.4 10010000000000000000000000000000 # `vector` चे मूल्य कोठे सुरू होते हे दर्शवणारा "ऑफसेट" (लिट्ल-एंडियन 16).5 10010110000000000000000000000000 # `number3` चे लिट्ल-एंडियन एन्कोडिंग.6 10000001100000101000001110000100 # `bytes` फील्डचे वास्तविक मूल्य.7]त्यामुळे व्हेरिएबल-लांबीच्या प्रकारांसाठी वास्तविक मूल्ये सिरीअलाइझ केलेल्या ऑब्जेक्टच्या शेवटी एका हीपमध्ये संग्रहित केली जातात आणि त्यांचे ऑफसेट फील्डच्या क्रमबद्ध सूचीमध्ये त्यांच्या योग्य स्थानांवर संग्रहित केले जातात.
BitList प्रकारासारखी काही विशेष प्रकरणे देखील आहेत ज्यांना विशिष्ट हाताळणीची आवश्यकता असते, ज्यासाठी सिरीअलायझेशन दरम्यान लांबी कॅप जोडणे आणि डीसिरीअलायझेशन दरम्यान काढून टाकणे आवश्यक असते. संपूर्ण तपशील SSZ स्पेकopens in a new tab मध्ये उपलब्ध आहेत.
डीसिरीअलायझेशन
या ऑब्जेक्टला डीसिरीअलाइझ करण्यासाठी स्कीमा आवश्यक आहे. स्कीमा सिरीअलाइझ केलेल्या डेटाचा अचूक लेआउट परिभाषित करतो जेणेकरून प्रत्येक विशिष्ट घटक बाइट्सच्या ब्लॉबमधून काही अर्थपूर्ण ऑब्जेक्टमध्ये डीसिरीअलाइझ केला जाऊ शकतो, ज्यामध्ये घटकांचा योग्य प्रकार, मूल्य, आकार आणि स्थान असेल. स्कीमाच डीसिरीअलायझरला सांगते की कोणती मूल्ये वास्तविक मूल्ये आहेत आणि कोणती ऑफसेट आहेत. जेव्हा एखादे ऑब्जेक्ट सिरीअलाइझ केले जाते तेव्हा सर्व फील्ड नावे अदृश्य होतात, परंतु स्कीमानुसार डीसिरीअलायझेशनवर पुन्हा इन्स्टंटिएट केली जातात.
यावरील इंटरॅक्टिव्ह स्पष्टीकरणासाठी ssz.devopens in a new tab पहा.
मर्केलायझेशन
या SSZ सिरीअलाइझ केलेल्या ऑब्जेक्टला नंतर मर्केलाइझ केले जाऊ शकते - म्हणजेच त्याच डेटाच्या मर्केल-ट्री रिप्रेझेंटेशनमध्ये रूपांतरित केले जाऊ शकते. प्रथम, सिरीअलाइझ केलेल्या ऑब्जेक्टमधील 32-बाइट चंक्सची संख्या निश्चित केली जाते. ही ट्रीची "लीव्हज" (पाने) आहेत. लीव्हजची एकूण संख्या 2 च्या घातांकात असणे आवश्यक आहे जेणेकरून लीव्हज एकत्र हॅश केल्यावर शेवटी एकच हॅश-ट्री-रूट तयार होईल. जर नैसर्गिकरित्या असे नसेल, तर 32 बाइट शून्य असलेली अतिरिक्त लीव्हज जोडली जातात. रेखाचित्रानुसार:
1 हॅश ट्री रूट2 / \3 / \4 / \5 / \6 लीव्हज 1 आणि 2 चा हॅश लीव्हज 3 आणि 4 चा हॅश7 / \ / \8 / \ / \9 / \ / \10 लीफ1 लीफ2 लीफ3 लीफ4सर्व दाखवाअशी काही प्रकरणे देखील आहेत जिथे ट्रीची लीव्हज वरील उदाहरणाप्रमाणे नैसर्गिकरित्या समान रीतीने वितरीत होत नाहीत. उदाहरणार्थ, लीफ 4 हे अनेक घटकांसह एक कंटेनर असू शकते ज्यासाठी मर्केल ट्रीमध्ये अतिरिक्त "डेप्थ" (खोली) जोडण्याची आवश्यकता असते, ज्यामुळे एक असमान ट्री तयार होते.
या ट्री घटकांना लीफ X, नोड X इत्यादी म्हणून संबोधण्याऐवजी, आपण त्यांना सामान्यीकृत इंडेक्स देऊ शकतो, ज्याची सुरुवात रूट = 1 पासून होते आणि प्रत्येक स्तरावर डावीकडून उजवीकडे मोजणी केली जाते. हा वर स्पष्ट केलेला सामान्यीकृत इंडेक्स आहे. सिरीअलाइझ केलेल्या सूचीतील प्रत्येक घटकाचा एक सामान्यीकृत इंडेक्स 2**depth + idx च्या बरोबर असतो, जिथे idx हे सिरीअलाइझ केलेल्या ऑब्जेक्टमधील त्याचे शून्य-इंडेक्स केलेले स्थान आहे आणि डेप्थ (खोली) मर्केल ट्रीमधील स्तरांची संख्या आहे, जी घटकांच्या (लीव्हज) संख्येचा बेस-टू लॉगरिथम म्हणून निर्धारित केली जाऊ शकते.
सामान्यीकृत इंडेक्स
सामान्यीकृत इंडेक्स हा एक इंटिजर आहे जो बायनरी मर्केल ट्रीमधील नोडचे प्रतिनिधित्व करतो जिथे प्रत्येक नोडचा सामान्यीकृत इंडेक्स 2 ** depth + index in row असतो.
1 1 --डेप्थ = 0 2**0 + 0 = 12 2 3 --डेप्थ = 1 2**1 + 0 = 2, 2**1+1 = 33 4 5 6 7 --डेप्थ = 2 2**2 + 0 = 4, 2**2 + 1 = 5...4हे रिप्रेझेंटेशन मर्केल ट्रीमधील डेटाच्या प्रत्येक भागासाठी एक नोड इंडेक्स देते.
मल्टीप्रूफ्स
एका विशिष्ट घटकाचे प्रतिनिधित्व करणाऱ्या सामान्यीकृत इंडेक्सची सूची प्रदान केल्याने आम्हाला ते हॅश-ट्री-रूट विरुद्ध सत्यापित करण्याची परवानगी मिळते. हे रूट म्हणजे वास्तवाची आपली स्वीकारलेली आवृत्ती आहे. आपल्याला प्रदान केलेला कोणताही डेटा त्या वास्तवाविरुद्ध मर्केल ट्रीमध्ये योग्य ठिकाणी (त्याच्या सामान्यीकृत इंडेक्सद्वारे निर्धारित) घालून आणि रूट स्थिर राहतो हे पाहून सत्यापित केला जाऊ शकतो. येथेopens in a new tab स्पेक्समध्ये अशी फंक्शन्स आहेत जी सामान्यीकृत इंडेक्सच्या विशिष्ट सेटमधील सामग्री सत्यापित करण्यासाठी आवश्यक असलेल्या नोड्सचा किमान संच कसा मोजावा हे दर्शवतात.
उदाहरणार्थ, खालील ट्रीमधील इंडेक्स 9 मधील डेटा सत्यापित करण्यासाठी, आम्हाला इंडेक्स 8, 9, 5, 3, 1 वरील डेटाचा हॅश आवश्यक आहे. (8,9) चा हॅश (4) च्या हॅशच्या बरोबर असावा, जो 5 सोबत हॅश होऊन 2 तयार करतो, जो 3 सोबत हॅश होऊन ट्री रूट 1 तयार करतो. जर 9 साठी चुकीचा डेटा प्रदान केला गेला, तर रूट बदलेल - आम्ही हे ओळखू आणि ब्रांच सत्यापित करण्यात अयशस्वी होऊ.
1* = प्रूफ तयार करण्यासाठी आवश्यक डेटा23 1*4 2 3*5 4 5* 6 768* 9* 10 11 12 13 14 157