เพื่อท้ายที่สุดแล้วจะได้บล็อกเชนและไม่ใช่แค่ฐานข้อมูล เราจำเป็นต้องเพิ่มองค์ประกอบที่สำคัญ 3 ประการในโครงการของเรา:
- คำอธิบายโครงสร้างข้อมูลบล็อกและวิธีการ
- คำอธิบายโครงสร้างข้อมูลและวิธีการธุรกรรม
- ฟังก์ชั่นบล็อกเชนที่บันทึกบล็อกในฐานข้อมูลและค้นหาบล็อกเหล่านั้นด้วยแฮชหรือความสูง (หรืออย่างอื่น)
นี่เป็นบทความที่สองเกี่ยวกับบล็อคเชนสำหรับอุตสาหกรรมบทความแรก
ควรสังเกตการจำคำถามที่ผู้อ่านถามฉันเกี่ยวกับบทความก่อนหน้าในชุดนี้: ในกรณีนี้ ฐานข้อมูล LevelDB ใช้เพื่อจัดเก็บข้อมูลบล็อกเชน แต่ไม่มีสิ่งใดขัดขวางไม่ให้คุณใช้งานฐานข้อมูลอื่น เช่น 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(bytes []byte) ถูกใช้ใน 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 ซึ่งรับแฮชของบล็อกก่อนหน้าและความสูงที่ตั้งไว้สำหรับบล็อกที่สร้างขึ้นในบล็อกเชน ประเภทบล็อกยังได้รับการตั้งค่าจากค่าคงที่ของแพ็คเกจประเภท:
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
ฟังก์ชั่นของแพ็คเกจบล็อคเชนมีหน้าที่บันทึกลงในบล็อคเชน:
เมื่อต้องการทำเช่นนี้ บล็อกต้องใช้อินเทอร์เฟซ 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