لكي نصل في نهاية المطاف إلى blockchain وليس مجرد قاعدة بيانات، نحتاج إلى إضافة 3 عناصر مهمة لمشروعنا:
- وصف بنية بيانات الكتلة وطرقها
- وصف هيكل البيانات وطرق المعاملات
- وظائف Blockchain التي تحفظ الكتل في قاعدة بيانات وتجدها هناك من خلال التجزئة أو الارتفاع (أو أي شيء آخر).
هذه هي المقالة الثانية حول blockchain للصناعة، الأولى
تذكر الأسئلة التي طرحها علي القراء حول المقالة السابقة في هذه السلسلة، تجدر الإشارة إلى: في هذه الحالة، يتم استخدام قاعدة بيانات LevelDB لتخزين بيانات blockchain، ولكن لا شيء يمنعك من استخدام أي شيء آخر، على سبيل المثال، MySQL. الآن دعونا نلقي نظرة على هيكل هذه البيانات.
لنبدأ بالمعاملات:
وهنا بنية البيانات الخاصة به:
type TX struct {
DataType byte
TxHash string
TxType byte
Timestamp int64
INs []TxIn
OUTs []TxOut
}
type TxIn struct {
ThatTxHash string
TxOutN int
ByteCode string
}
type TxOut struct {
Value int
ByteCode string
}
يقوم TX بتخزين نوع البيانات (للمعاملة 2)، وتجزئة تلك المعاملة، ونوع المعاملة نفسها، والطابع الزمني، والمدخلات والمخرجات. تقوم مدخلات TxIn بتخزين تجزئة المعاملة التي تتم الإشارة إلى مخرجاتها، ورقم هذا الإخراج والرمز الثانوي، وتقوم مخرجات TxOut بتخزين بعض القيمة وكذلك الرمز الثانوي.
الآن دعونا نرى ما هي الإجراءات التي يمكن للمعاملة تنفيذها على بياناتها، أي. دعونا نلقي نظرة على الأساليب.
لإنشاء معاملة، استخدم الدالةTransaction.NewTransaction(txtype byte) *TX.
تضيف طريقة AddTxIn(thattxhash []byte, txoutn int, code []byte) (*TxIn, error) مدخلاً إلى المعاملة.
تضيف طريقة AddTxOut(value int, data []byte) (*TxOut, error) مخرجات إلى المعاملة.
تقوم طريقة ToBytes() []byte بتحويل المعاملة إلى شريحة بايت.
يتم استخدام سلسلة preByteHash (بايت [] بايت) للوظيفة الداخلية في Build () وCheck () لجعل تجزئة المعاملة التي تم إنشاؤها متوافقة مع تجزئة المعاملة التي تم إنشاؤها من تطبيقات JavaScript.
تقوم طريقة Build() بتعيين تجزئة المعاملة كما يلي: tx.TxHash = preByteHash(tx.ToBytes()).
تقوم طريقة سلسلة ToJSON() بتحويل المعاملة إلى سلسلة JSON.
تقوم طريقة الخطأ FromJSON(data []byte) بتحميل معاملة من تنسيق JSON الذي تم تمريره كشريحة بايت.
تقارن الطريقة المنطقية Check() التجزئة الناتجة من حقل تجزئة المعاملة مع التجزئة التي تم الحصول عليها نتيجة تجزئة هذه المعاملة (تجاهل حقل التجزئة).
تتم إضافة المعاملات إلى الكتلة:
بنية بيانات الكتلة أكثر ضخامة:
type Block struct {
DataType byte
BlockHeight int
Timestamp int64
HeaderSize int
PrevBlockHash string
SelfBlockHash string
TxsHash string
MerkleRoot string
CreatorPublicKey string
CreatorSig string
Version int
TxsN int
Txs []transaction.TX
}
يقوم DataType بتخزين نوع البيانات، وتستخدمه العقدة وتميز الكتلة عن المعاملة أو البيانات الأخرى. بالنسبة للكتلة، هذه القيمة هي 1.
يقوم BlockHeight بتخزين ارتفاع الكتلة.
الطابع الزمني الطابع الزمني.
HeaderSize هو حجم الكتلة بالبايت.
PrevBlockHash هو تجزئة الكتلة السابقة، وSelfBlockHash هو تجزئة الكتلة الحالية.
TxsHash هو تجزئة عامة للمعاملات.
MerkleRoot هو جذر شجرة Merkle.
علاوة على ذلك، يوجد في الحقول المفتاح العام لمنشئ الكتلة، وتوقيع المنشئ، وإصدار الكتلة، وعدد المعاملات في الكتلة، وهذه المعاملات نفسها.
دعونا نلقي نظرة على أساليبه:
لإنشاء كتلة، استخدم وظيفة block.NewBlock(): NewBlock(prevBlockHash string, height int) *Block، الذي يأخذ تجزئة الكتلة السابقة والارتفاع المحدد للكتلة التي تم إنشاؤها في blockchain. يتم أيضًا تعيين نوع الكتلة من ثابت حزمة الأنواع:
b.DataType = types.BLOCK_TYPE.
تضيف طريقة AddTx(tx *transaction.TX) معاملة إلى الكتلة.
تقوم طريقة Build () بتحميل القيم في حقول الكتلة وإنشاء التجزئة الحالية وتعيينها.
تقوم طريقة ToBytesHeader() []byte بتحويل رأس الكتلة (بدون معاملات) إلى شريحة بايت.
تقوم طريقة سلسلة ToJSON() بتحويل الكتلة إلى تنسيق JSON في تمثيل سلسلة للبيانات.
تقوم طريقة الخطأ FromJSON(data []byte) بتحميل البيانات من JSON إلى بنية الكتلة.
تقوم طريقة Check() bool بإنشاء تجزئة كتلة ومقارنتها مع تلك المحددة في حقل تجزئة الكتلة.
تقوم طريقة سلسلة GetTxsHash() بإرجاع إجمالي التجزئة لجميع المعاملات في الكتلة.
تحدد طريقة GetMerkleRoot() جذر شجرة Merkle للمعاملات في الكتلة.
تقوم طريقة Sign (سلسلة خاصة) بتوقيع الكتلة باستخدام المفتاح الخاص لمنشئ الكتلة.
تكتب طريقة SetHeight(height int) ارتفاع الكتلة في حقل بنية الكتلة.
تقوم طريقة GetHeight() int بإرجاع ارتفاع الكتلة كما هو محدد في الحقل المقابل لبنية الكتلة.
يقوم أسلوب ToGOBBytes() []byte بتشفير كتلة بتنسيق GOB وإرجاعها كشريحة بايت.
تقوم طريقة الخطأ FromGOBBytes(data []byte) بكتابة بيانات الكتلة إلى بنية الكتلة من شريحة البايت التي تم تمريرها بتنسيق GOB.
تقوم طريقة سلسلة GetHash () بإرجاع تجزئة الكتلة المحددة.
تقوم طريقة السلسلة GetPrevHash() بإرجاع تجزئة الكتلة السابقة.
تكتب طريقة SetPublicKey (سلسلة pubk) المفتاح العام لمنشئ الكتلة إلى الكتلة.
وبالتالي، باستخدام أساليب كائن Block، يمكننا بسهولة تحويله إلى تنسيق للإرسال عبر الشبكة وحفظه في قاعدة بيانات LevelDB.
وظائف حزمة blockchain مسؤولة عن الحفظ في blockchain:
للقيام بذلك، يجب أن تقوم الكتلة بتنفيذ واجهة IBlock:
type IGOBBytes interface {
ToGOBBytes() []byte
FromGOBBytes(data []byte) error
}
type IBlock interface {
IGOBBytes
GetHash() string
GetPrevHash() string
GetHeight() int
Check() bool
}
يتم إنشاء اتصال قاعدة البيانات مرة واحدة عند تهيئة الحزمة في الدالة init():
db, err = leveldb.OpenFile(BLOCKCHAIN_DB_DEBUG, nil).
CloseDB() عبارة عن غلاف لـ db.Cloce() - يتم استدعاؤه بعد العمل مع وظائف الحزمة لإغلاق الاتصال بقاعدة البيانات.
تقوم وظيفة الخطأ SetTargetBlockHash (سلسلة التجزئة) بكتابة تجزئة الكتلة الحالية باستخدام المفتاح المحدد بواسطة ثابت BLOCK_HASH إلى قاعدة البيانات.
تقوم الدالة GetTargetBlockHash() (سلسلة، خطأ) بإرجاع تجزئة الكتلة الحالية المخزنة في قاعدة البيانات.
تكتب وظيفة الخطأ SetTargetBlockHeight(height int) إلى قاعدة البيانات قيمة ارتفاع blockchain للعقدة مع المفتاح المحدد بواسطة ثابت BLOCK_HEIGHT.
تقوم الدالة GetTargetBlockHeight() (int، error) بإرجاع ارتفاع blockchain لعقدة معينة، مخزنة في قاعدة البيانات.
تقوم وظيفة CheckBlock(block IBlock) المنطقية بالتحقق من صحة الكتلة قبل إضافة هذه الكتلة إلى blockchain.
تضيف وظيفة الخطأ AddBlock(block IBlock) كتلة إلى blockchain.
توجد وظائف استرداد الكتل وعرضها في ملف explore.go الخاص بحزمة blockchain:
تقوم وظيفة GetBlockByHash (سلسلة التجزئة) (*block.Block، خطأ) بإنشاء كائن كتلة فارغ، وتحميل كتلة إليه من قاعدة البيانات، وتم تمرير التجزئة إليه، وإرجاع مؤشر إليه.
يتم إنشاء كتلة التكوين بواسطة وظيفة الخطأ Genesis() من ملف Genesis.go الخاص بحزمة blockchain.
ستتحدث المقالة التالية عن توصيل العملاء بالعقدة باستخدام آلية WebSocket.
المصدر: www.habr.com