Go blockchain-də blokları və əməliyyatları necə tərtib etdim

Nəhayət, təkcə verilənlər bazası deyil, blokçeynlə başa çatmaq üçün layihəmizə 3 vacib element əlavə etməliyik:

  • Blok məlumat strukturunun və metodlarının təsviri
  • Məlumat strukturunun və əməliyyat üsullarının təsviri
  • Blokları verilənlər bazasında saxlayan və hash və ya hündürlüyünə (və ya başqa bir şeyə) görə orada tapan Blockchain funksiyaları.

Go blockchain-də blokları və əməliyyatları necə tərtib etdim

Bu, sənaye üçün blokçeyn haqqında ikinci məqalə, birincisidir burada.

Oxucuların bu seriyanın əvvəlki məqaləsi ilə bağlı mənə verdiyi sualları xatırlayaraq, qeyd etmək lazımdır: bu halda LevelDB verilənlər bazası blokçeyn məlumatlarını saxlamaq üçün istifadə olunur, lakin heç bir başqa, məsələn, MySQL-dən istifadə etməyə heç nə mane olmur. İndi bu məlumatların strukturuna baxaq.

Əməliyyatlardan başlayaq: github.com/Rusldv/bcstartup/blob/master/transaction/builder.go

Budur onun məlumat strukturu:

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 məlumat növünü (2-ci əməliyyat üçün), həmin əməliyyatın hashını, əməliyyatın özünün növünü, vaxt damğasını, giriş və çıxışları saxlayır. TxIn girişləri çıxışına istinad edilən əməliyyatın hashını, bu çıxışın və bayt kodunun sayını, TxOut çıxışları isə bəzi dəyəri və həmçinin bayt kodunu saxlayır.

İndi bir əməliyyatın öz məlumatlarında hansı hərəkətləri yerinə yetirə biləcəyinə baxaq, yəni. Metodlara baxaq.

Tranzaksiya yaratmaq üçün tranzaksiyadan istifadə edin.NewTransaction(txtype byte) *TX funksiyası.

AddTxIn(thattxhash []byte, txoutn int, code []byte) (*TxIn, error) metodu əməliyyata giriş əlavə edir.

AddTxOut(value int, data []byte) (*TxOut, error) metodu əməliyyata çıxış əlavə edir.

ToBytes() []bayt metodu əməliyyatı bayt diliminə çevirir.

Daxili funksiya preByteHash(bayt []bayt) sətirindən Build() və Check() funksiyalarında yaradılan tranzaksiya heşini JavaScript proqramlarından yaradılan tranzaksiya heşləri ilə uyğunlaşdırmaq üçün istifadə olunur.

Build() metodu əməliyyat hashını aşağıdakı kimi təyin edir: tx.TxHash = preByteHash(tx.ToBytes()).

ToJSON() sətir metodu əməliyyatı JSON sətirinə çevirir.

FromJSON(data []bayt) xətası metodu bayt dilimi kimi ötürülən JSON formatından tranzaksiyanı yükləyir.

Check() bool metodu tranzaksiya heş sahəsindən əldə edilən hashı bu tranzaksiyanın heşinqi (hesh sahəsinə məhəl qoymayaraq) nəticəsində əldə edilən hash ilə müqayisə edir.

Əməliyyatlar bloka əlavə olunur: github.com/Rusldv/bcstartup/blob/master/block/builder.go

Blok məlumat strukturu daha həcmlidir:

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 məlumat növünü saxlayır, node ondan istifadə edir və bloku əməliyyatdan və ya digər məlumatlardan fərqləndirir. Blok üçün bu dəyər 1-dir.

BlockHeight blokun hündürlüyünü saxlayır.
Vaxt möhürü vaxt damğası.
HeaderSize baytdakı blok ölçüsüdür.
PrevBlockHash əvvəlki blokun, SelfBlockHash isə cari blokun hashıdır.
TxsHash əməliyyatların ümumi hashıdır.
MerkleRoot Merkle ağacının köküdür.

Daha sonra sahələrdə blokun yaradıcısının açıq açarı, yaradıcının imzası, blokun versiyası, blokdakı əməliyyatların sayı və bu əməliyyatların özləri var.

Onun üsullarına nəzər salaq:
Blok yaratmaq üçün block.NewBlock() funksiyasından istifadə edin: NewBlock(prevBlockHash string, height int) *Blok, əvvəlki blokun hashini və blokçeynində yaradılmış blok üçün təyin olunmuş hündürlüyü götürür. Blok növü də növlər paketi sabitindən təyin olunur:

b.DataType = types.BLOCK_TYPE.

AddTx(tx *transaction.TX) metodu bloka əməliyyat əlavə edir.

Build () metodu dəyərləri blokun sahələrinə yükləyir və cari hashını yaradır və təyin edir.

ToBytesHeader() []bayt metodu blok başlığını (əməliyyatlar olmadan) bayt diliminə çevirir.

ToJSON() sətir metodu verilənlərin sətir təsvirində bloku JSON formatına çevirir.

FromJSON(data []bayt) xətası metodu verilənləri JSON-dan blok strukturuna yükləyir.

Check() bool metodu blok hash yaradır və onu blok hash sahəsində göstərilənlə müqayisə edir.

GetTxsHash() sətir metodu blokdakı bütün əməliyyatların ümumi hashını qaytarır.

GetMerkleRoot() metodu blokdakı əməliyyatlar üçün Merkle ağacının kökünü təyin edir.

Sign(privk string) metodu blok yaradıcısının şəxsi açarı ilə bloku imzalayır.

SetHeight(height int) metodu blokun hündürlüyünü blok strukturu sahəsinə yazır.

GetHeight() int metodu blok strukturunun müvafiq sahəsində göstərildiyi kimi blokun hündürlüyünü qaytarır.

ToGOBBytes() []bayt metodu bloku GOB formatında kodlayır və onu bayt dilimi kimi qaytarır.

FromGOBBytes(data []bayt) xətası metodu blok məlumatlarını blok strukturuna ötürülən bayt dilimindən GOB formatında yazır.

GetHash() sətir metodu verilmiş blokun hashını qaytarır.

GetPrevHash() sətir metodu əvvəlki blokun hashını qaytarır.

SetPublicKey(pubk string) metodu blok yaradıcısının açıq açarını bloka yazır.

Beləliklə, Block obyektinin metodlarından istifadə edərək, biz onu asanlıqla şəbəkə üzərindən ötürmək və LevelDB verilənlər bazasına saxlamaq üçün formata çevirə bilərik.

Blockchain paketinin funksiyaları blokçeynə qənaət etməkdən məsuldur: github.com/Rusldv/bcstartup/tree/master/blockchain

Bunun üçün blok IBlock interfeysini həyata keçirməlidir:

type IGOBBytes interface {
	ToGOBBytes() []byte
	FromGOBBytes(data []byte) error
}

type IBlock interface {
	IGOBBytes
	GetHash() string
	GetPrevHash() string
	GetHeight() int
	Check() bool

}

Paket init() funksiyasında işə salındıqda verilənlər bazası bağlantısı bir dəfə yaradılır:

db, err = leveldb.OpenFile(BLOCKCHAIN_DB_DEBUG, nil).

CloseDB() db.Cloce() üçün sarğıdır - verilənlər bazası ilə əlaqəni bağlamaq üçün paket funksiyaları ilə işlədikdən sonra çağırılır.

SetTargetBlockHash(hash string) xətası funksiyası BLOCK_HASH sabiti ilə müəyyən edilmiş açarla cari blokun hashını verilənlər bazasına yazır.

GetTargetBlockHash() (sətir, xəta) funksiyası verilənlər bazasında saxlanılan cari blokun hashını qaytarır.

SetTargetBlockHeight(height int) xətası funksiyası verilənlər bazasına BLOCK_HEIGHT sabiti ilə müəyyən edilmiş açarla qovşaq üçün blokçeyn hündürlüyünün dəyərini yazır.

GetTargetBlockHeight() (int, səhv) funksiyası verilənlər bazasında saxlanılan verilmiş qovşaq üçün blokçeynin hündürlüyünü qaytarır.

CheckBlock(block IBlock) bool funksiyası bu bloku blockchain-ə əlavə etməzdən əvvəl blokun düzgünlüyünü yoxlayır.

AddBlock(block IBlock) xətası funksiyası blokçeynə blok əlavə edir.

Blokların axtarışı və baxılması funksiyaları blockchain paketinin explore.go faylındadır:

GetBlockByHash(hash string) (*block.Block, error) funksiyası boş blok obyekti yaradır, ona hashı ötürülən verilənlər bazasından blok yükləyir və ona göstərici qaytarır.

Genesis blokunun yaradılması blokçeyn paketinin genesis.go faylından Genesis() xəta funksiyası ilə həyata keçirilir.

Növbəti məqalədə WebSocket mexanizmindən istifadə edərək müştəri qovşağına qoşulmaq haqqında danışılacaq.

Mənbə: www.habr.com

Добавить комментарий