Би Go блокчэйн дээрээ блок болон гүйлгээг хэрхэн зохион бүтээсэн

Эцсийн эцэст зөвхөн мэдээллийн сан биш блокчэйнтэй болохын тулд бид төсөлдөө 3 чухал элементийг нэмэх хэрэгтэй:

  • Блокийн өгөгдлийн бүтэц, аргуудын тодорхойлолт
  • Өгөгдлийн бүтэц, гүйлгээний аргуудын тодорхойлолт
  • Блокчейн функцууд нь блокуудыг мэдээллийн санд хадгалж, хэш эсвэл өндрөөр нь (эсвэл өөр зүйлээр) олох боломжтой.

Би Go блокчэйн дээрээ блок болон гүйлгээг хэрхэн зохион бүтээсэн

Энэ бол аж үйлдвэрт зориулсан блокчейн тухай хоёр дахь нийтлэл, эхнийх юм энд.

Энэ цувралын өмнөх нийтлэлийн талаар уншигчид надаас асууж байсан асуултуудыг санаж байх хэрэгтэй: энэ тохиолдолд 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 гаралт нь зарим утгыг мөн байт кодыг хадгалдаг.

Одоо гүйлгээ нь өгөгдөл дээрээ ямар үйлдэл хийж болохыг харцгаая, i.e. Аргуудыг авч үзье.

Гүйлгээ үүсгэхийн тулд гүйлгээ.NewTransaction(txtype byte) *TX функцийг ашиглана уу.

AddTxIn(thattxhash []byte, txoutn int, code []byte) (*TxIn, error) арга нь гүйлгээнд оролт нэмдэг.

AddTxOut(value int, data []byte) (*TxOut, error) арга нь гүйлгээнд гаралтыг нэмдэг.

ToBytes() []байтын арга нь гүйлгээг байт зүсмэл болгон хувиргадаг.

Үүсгэсэн гүйлгээний хэшийг JavaScript програмуудаас үүсгэсэн гүйлгээний хэштэй нийцүүлэхийн тулд дотоод функцийн preByteHash(байт []байт) мөрийг Build() болон Check()-д ашигладаг.

Build() арга нь гүйлгээний хэшийг дараах байдлаар тохируулна: tx.TxHash = preByteHash(tx.ToBytes()).

ToJSON() мөрийн арга нь гүйлгээг JSON мөр болгон хувиргадаг.

FromJSON(өгөгдлийн []байт) алдааны арга нь байт зүсмэл хэлбэрээр дамжуулсан JSON форматаас гүйлгээг ачаална.

Check() bool арга нь гүйлгээний хэш талбараас үүссэн хэшийг энэ гүйлгээний үр дүнд олж авсан хэштэй харьцуулдаг (хэш талбарыг үл тоомсорлодог).

Гүйлгээг блокт нэмсэн: 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) *Блокчлон дахь өмнөх блокийн хэш болон үүсгэсэн блокийн тогтоосон өндрийг авдаг блок. Блокийн төрлийг мөн төрлийн багцын тогтмолоос тохируулна:

b.DataType = types.BLOCK_TYPE.

AddTx(tx *transaction.TX) арга нь блок руу гүйлгээг нэмдэг.

Build() арга нь блокийн талбарт утгуудыг ачаалж, одоогийн хэшийг үүсгэж тохируулдаг.

ToBytesHeader() []байтын арга нь блокийн толгой хэсгийг (гүйлгээгүйгээр) байт зүсмэл болгон хувиргадаг.

ToJSON() string арга нь блокийг JSON формат руу өгөгдлийн стринг хэлбэрээр хөрвүүлдэг.

FromJSON(өгөгдлийн []байт) алдааны арга нь JSON-с өгөгдлийг блокийн бүтцэд ачаалдаг.

Check() bool арга нь блок хэш үүсгэж, блок хэш талбарт заасантай харьцуулдаг.

GetTxsHash() мөрийн арга нь блок дахь бүх гүйлгээний нийт хэшийг буцаана.

GetMerkleRoot() арга нь блок дахь гүйлгээний Merkle модны үндсийг тодорхойлдог.

Sign(privk string) арга нь блок үүсгэгчийн хувийн түлхүүрээр блок дээр гарын үсэг зурдаг.

SetHeight(height int) арга нь блокийн бүтцийн талбарт блокийн өндрийг бичдэг.

GetHeight() int арга нь блокийн бүтцийн харгалзах талбарт заасан блокийн өндрийг буцаана.

ToGOBBytes() []байтын арга нь блокыг GOB форматаар кодлож, байт зүсмэл хэлбэрээр буцаана.

FromGOBBytes(өгөгдлийн []байт) алдааны арга нь GOB форматаар дамжуулсан байтын зүсмэлийн блокийн бүтцийг блокийн бүтцэд бичдэг.

GetHash() мөрийн арга нь өгөгдсөн блокийн хэшийг буцаана.

GetPrevHash() мөрийн арга нь өмнөх блокийн хэшийг буцаана.

SetPublicKey(pubk string) арга нь блок үүсгэгчийн нийтийн түлхүүрийг блок руу бичдэг.

Тиймээс, Block объектын аргуудыг ашиглан бид үүнийг сүлжээгээр дамжуулах, LevelDB мэдээллийн санд хадгалах формат руу хялбархан хөрвүүлэх боломжтой.

Блокчейн багцын функцууд нь блокчэйнд хадгалах үүрэгтэй: 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(hash string) алдааны функц нь одоогийн блокийн хэшийг BLOCK_HASH тогтмолоор заасан түлхүүрээр мэдээллийн санд бичдэг.

GetTargetBlockHash() (мөр, алдаа) функц нь мэдээллийн санд хадгалагдсан одоогийн блокийн хэшийг буцаана.

SetTargetBlockHeight(height int) алдааны функц нь BLOCK_HEIGHT тогтмолоор заасан түлхүүрээр зангилааны блокчейн өндрийн утгыг мэдээллийн санд бичдэг.

GetTargetBlockHeight() (int, алдаа) функц нь мэдээллийн санд хадгалагдсан өгөгдсөн зангилааны блокчейн өндрийг буцаана.

CheckBlock(block IBlock) bool функц нь энэ блокийг блокчэйнд нэмэхээс өмнө блокийн зөв эсэхийг шалгадаг.

AddBlock(block IBlock) алдааны функц нь блокчлонд блок нэмдэг.

Блокуудыг татаж авах, үзэх функцууд нь blockchain багцын explore.go файлд байдаг:

GetBlockByHash(hash string) (*block.Block, error) функц нь хоосон блок объект үүсгэж, өгөгдлийн сангаас түүнд хэш дамжуулагдсан блокыг ачаалж, түүнд заагч буцаана.

Genesis блок үүсгэх нь блокчейн багцын genesis.go файлаас Genesis() алдааны функцээр хийгддэг.

Дараагийн өгүүллээр үйлчлүүлэгчдийг WebSocket механизм ашиглан зангилаа руу холбох талаар ярих болно.

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх