كيف صممت الكتل والمعاملات على بلوكشين Go الخاص بي

من أجل إنتاج blockchain في نهاية المطاف ، وليس فقط قاعدة بيانات ، نحتاج إلى إضافة 3 عناصر مهمة لمشروعنا:

  • وصف هيكل البيانات وطرق الحظر
  • وصف هيكل البيانات وطرق المعاملات
  • وظائف Blockchain التي تحفظ الكتل في قاعدة البيانات وتجدها هناك من خلال التجزئة أو الارتفاع (أو أي شيء آخر).

صورة

هذه هي المقالة الثانية حول blockchain للصناعة ، الأول هنا .

تذكر الأسئلة التي طرحها عليّ القراء في المقالة السابقة من هذه السلسلة ، وتجدر الإشارة إلى ذلك: في هذه الحالة ، يتم استخدام قاعدة بيانات LevelDB لتخزين بيانات blockchain ، ولكنها لا تتداخل مع استخدام أي دولة أخرى ، قل نفس MySQL. والآن سوف نفهم هيكل هذه البيانات.

لنبدأ بالمعاملات: github.com/Rusldv/bcstartup/blob/master/transaction/builder.go

إليك هيكل البيانات:

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 (قيمة int ، data [] بايت) (* TxOut ، خطأ) الإخراج إلى المعاملة.

يحول أسلوب البايت ToBytes () [] معاملة إلى شريحة بايت.

يتم استخدام سلسلة preByteHash (bytes [] byte) للوظيفة الداخلية في Build () و Check () لتوافق تجزئة المعاملات التي تم إنشاؤها مع تجزئات المعاملات التي تم إنشاؤها من تطبيقات JavaScript.

يعين أسلوب Build () تجزئة المعاملة كما يلي: tx.TxHash = preByteHash (tx.ToBytes ()).

تحول طريقة ToJSON () لسلسلة تحويل إلى سلسلة JSON.

تقوم طريقة خطأ FromJSON (data [] byte) بتحميل معاملة من تنسيق JSON الذي تم إرساله كشريحة بايت.

يقارن الأسلوب المنطقي Check () التجزئة التي تم تلقيها من حقل التجزئة للمعاملة بالتجزئة التي تم الحصول عليها نتيجة لتجزئة هذه المعاملة (باستثناء حقل التجزئة).

تتم إضافة المعاملات إلى الكتلة: github.com/Rusldv/bcstartup/blob/master/block/builder.go

تكون بنية بيانات الكتلة أكبر:

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 ، الارتفاع int) * كتلة ، والتي تأخذ تجزئة الكتلة السابقة ومجموعة الارتفاع للكتلة التي تم إنشاؤها في blockchain. يتم تعيين نوع الكتلة من ثابت حزمة الأنواع أيضًا:
b.DataType = types.BLOCK_TYPE.


يضيف أسلوب AddTx (tx * transaction.TX) معاملة إلى الكتلة.

تقوم طريقة Build () بتحميل القيم في حقول الكتلة وإنشاء وتعيين التجزئة الحالية الخاصة بها.

يترجم أسلوب بايت ToBytesHeader () [] رأس كتلة (بدون معاملات) إلى شريحة بايت.

تترجم طريقة ToJSON () للسلسلة الكتلة إلى تنسيق JSON في تمثيل السلسلة للبيانات.

طريقة خطأ FromJSON (data [] byte) تحمّل البيانات من JSON في بنية الكتلة.

الأسلوب المنطقي Check () ينشئ تجزئة كتلة ويقارنها مع تلك المحددة في حقل تجزئة الكتلة.

إرجاع أسلوب سلسلة GetTxsHash () التجزئة الشائعة لكافة المعاملات في الكتلة.

يعين الأسلوب GetMerkleRoot () جذر شجرة Merkle للمعاملات في الكتلة.

يوقع أسلوب التوقيع (سلسلة خاصة) الكتلة باستخدام المفتاح الخاص لمنشئ الكتلة.

يكتب أسلوب SetHeight (الارتفاع int) ارتفاع الكتلة إلى حقل بنية الكتلة.

ترجع طريقة GetHeight () int ارتفاع الكتلة كما هو موضح في الحقل المقابل لهيكل الكتلة.

يقوم أسلوب البايت ToGOBBytes () [] بتشفير الكتلة في تنسيق GOB وإعادتها كشريحة بايت.

يكتب أسلوب خطأ FromGOBBytes (data [] byte) بيانات الكتلة إلى بنية الكتلة من شريحة البايت المرسلة بتنسيق GOB.

إرجاع سلسلة الأسلوب GetHash () تجزئة هذه الكتلة.

إرجاع سلسلة الأسلوب GetPrevHash () تجزئة الكتلة السابقة.

يكتب الأسلوب SetPublicKey (سلسلة pubk) المفتاح العام لمنشئ الكتلة إلى الكتلة.

وبالتالي ، باستخدام طرق كائن الكتلة ، يمكننا بسهولة تحويله إلى تنسيق للإرسال عبر الشبكة وحفظه في قاعدة بيانات LevelDB.

وظائف حزمة blockchain مسؤولة عن الحفظ في blockchain: github.com/Rusldv/bcstartup/tree/master/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 (الارتفاع 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.

All Articles