ฉันออกแบบบล็อกและธุรกรรมใน Go blockchain ของฉันอย่างไร

เพื่อท้ายที่สุดแล้วจะได้บล็อกเชนและไม่ใช่แค่ฐานข้อมูล เราจำเป็นต้องเพิ่มองค์ประกอบที่สำคัญ 3 ประการในโครงการของเรา:

  • คำอธิบายโครงสร้างข้อมูลบล็อกและวิธีการ
  • คำอธิบายโครงสร้างข้อมูลและวิธีการธุรกรรม
  • ฟังก์ชั่นบล็อกเชนที่บันทึกบล็อกในฐานข้อมูลและค้นหาบล็อกเหล่านั้นด้วยแฮชหรือความสูง (หรืออย่างอื่น)

ฉันออกแบบบล็อกและธุรกรรมใน Go blockchain ของฉันอย่างไร

นี่เป็นบทความที่สองเกี่ยวกับบล็อคเชนสำหรับอุตสาหกรรมบทความแรก ที่นี่.

ควรสังเกตการจำคำถามที่ผู้อ่านถามฉันเกี่ยวกับบทความก่อนหน้าในชุดนี้: ในกรณีนี้ ฐานข้อมูล LevelDB ใช้เพื่อจัดเก็บข้อมูลบล็อกเชน แต่ไม่มีสิ่งใดขัดขวางไม่ให้คุณใช้งานฐานข้อมูลอื่น เช่น 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(value int, data []byte) (*TxOut, error) จะเพิ่มเอาต์พุตให้กับธุรกรรม

เมธอด ToBytes() []byte เปลี่ยนธุรกรรมเป็นชิ้นไบต์

ฟังก์ชันภายในสตริง 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 string, height int) *Block ซึ่งรับแฮชของบล็อกก่อนหน้าและความสูงที่ตั้งไว้สำหรับบล็อกที่สร้างขึ้นในบล็อกเชน ประเภทบล็อกยังได้รับการตั้งค่าจากค่าคงที่ของแพ็คเกจประเภท:

b.DataType = types.BLOCK_TYPE.

วิธีการ AddTx(tx *transaction.TX) จะเพิ่มธุรกรรมลงในบล็อก

เมธอด Build() โหลดค่าลงในเขตข้อมูลของบล็อกและสร้างและตั้งค่าแฮชปัจจุบัน

เมธอด ToBytesHeader() []byte จะแปลงส่วนหัวของบล็อก (โดยไม่มีธุรกรรม) ให้เป็นชิ้นไบต์

วิธีการสตริง ToJSON() แปลงบล็อกเป็นรูปแบบ JSON ในการแสดงสตริงของข้อมูล

วิธีการผิดพลาด FromJSON(data []byte) จะโหลดข้อมูลจาก JSON ลงในโครงสร้างบล็อก

เมธอด Check() บูลจะสร้างแฮชของบล็อกและเปรียบเทียบกับวิธีที่ระบุในฟิลด์แฮชของบล็อก

วิธีการสตริง GetTxsHash() ส่งกลับค่าแฮชรวมของธุรกรรมทั้งหมดในบล็อก

เมธอด GetMerkleRoot() ระบุรากของแผนผัง Merkle สำหรับธุรกรรมในบล็อก

วิธีการ Sign(privk string) ลงนามบล็อกด้วยคีย์ส่วนตัวของผู้สร้างบล็อก

เมธอด SetHeight(height int) เขียนความสูงของบล็อกลงในฟิลด์โครงสร้างบล็อก

GetHeight() int วิธีการส่งกลับความสูงของบล็อกตามที่ระบุไว้ในฟิลด์ที่สอดคล้องกันของโครงสร้างบล็อก

วิธี ToGOBBytes() [] ไบต์เข้ารหัสบล็อกในรูปแบบ GOB และส่งกลับเป็นชิ้นไบต์

วิธีการผิดพลาด FromGOBBytes(data []byte) จะเขียนข้อมูลบล็อกไปยังโครงสร้างบล็อกจากชิ้นไบต์ที่ส่งผ่านในรูปแบบ GOB

GetHash() วิธีการสตริงส่งกลับค่าแฮชของบล็อกที่กำหนด

วิธีการสตริง GetPrevHash() ส่งกลับแฮชของบล็อกก่อนหน้า

เมธอด SetPublicKey(pubk string) เขียนคีย์สาธารณะของผู้สร้างบล็อกลงในบล็อก

ดังนั้นเราจึงสามารถแปลงเป็นรูปแบบสำหรับการส่งผ่านเครือข่ายและบันทึกลงในฐานข้อมูล LevelDB ได้อย่างง่ายดายโดยใช้วิธีการของวัตถุ Block

ฟังก์ชั่นของแพ็คเกจบล็อคเชนมีหน้าที่บันทึกลงในบล็อคเชน: 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() เป็น wrapper สำหรับ db.Cloce() - เรียกหลังจากทำงานกับฟังก์ชันแพ็คเกจเพื่อปิดการเชื่อมต่อกับฐานข้อมูล

ฟังก์ชันข้อผิดพลาด SetTargetBlockHash(hash string) เขียนแฮชของบล็อกปัจจุบันด้วยคีย์ที่ระบุโดยค่าคงที่ BLOCK_HASH ไปยังฐานข้อมูล

ฟังก์ชัน GetTargetBlockHash() (สตริง ข้อผิดพลาด) ส่งกลับแฮชของบล็อกปัจจุบันที่จัดเก็บไว้ในฐานข้อมูล

ฟังก์ชันข้อผิดพลาด SetTargetBlockHeight(height int) เขียนไปยังฐานข้อมูลค่าของความสูงของ blockchain สำหรับโหนดด้วยคีย์ที่ระบุโดยค่าคงที่ BLOCK_HEIGHT

ฟังก์ชัน GetTargetBlockHeight() (int, error) ส่งกลับความสูงของ blockchain สำหรับโหนดที่กำหนดซึ่งจัดเก็บไว้ในฐานข้อมูล

ฟังก์ชันบูล CheckBlock(block IBlock) จะตรวจสอบความถูกต้องของบล็อกก่อนที่จะเพิ่มบล็อกนี้ลงใน blockchain

ฟังก์ชันข้อผิดพลาด AddBlock(block IBlock) จะเพิ่มบล็อกให้กับ blockchain

ฟังก์ชั่นสำหรับการดึงและดูบล็อคอยู่ในไฟล์ explore.go ของแพ็คเกจบล็อคเชน:

ฟังก์ชัน GetBlockByHash(hash string) (*block.Block, error) จะสร้างวัตถุบล็อกว่าง โหลดบล็อกจากฐานข้อมูลลงไป จากนั้นแฮชที่ถูกส่งผ่านไป และส่งกลับตัวชี้ไปที่วัตถุนั้น

การสร้างบล็อกการกำเนิดจะดำเนินการโดยฟังก์ชันข้อผิดพลาด Genesis() จากไฟล์ genesis.go ของแพ็คเกจบล็อกเชน

บทความถัดไปจะพูดถึงการเชื่อมต่อกับโหนดไคลเอนต์โดยใช้กลไก WebSocket

ที่มา: will.com

เพิ่มความคิดเห็น