Selleks, et lõpuks saaksime plokiahela, mitte ainult andmebaasi, peame oma projekti lisama kolm olulist elementi:
- Ploki andmestruktuuri ja meetodite kirjeldus
- Andmestruktuuri ja tehingumeetodite kirjeldus
- Blockchaini funktsioonid, mis salvestavad plokid andmebaasi ja leiavad need sealt räsi või kõrguse (või millegi muu) järgi.
See on teine artikkel tööstusele mõeldud plokiahela kohta, esimene
Meenutades küsimusi, mida lugejad mulle selle sarja eelmise artikli kohta esitasid, tuleb märkida: antud juhul kasutatakse plokiahela andmete salvestamiseks LevelDB andmebaasi, kuid miski ei takista teil kasutada mõnda muud, näiteks MySQL-i. Vaatame nüüd nende andmete struktuuri.
Alustame tehingutega:
Siin on selle andmestruktuur:
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 salvestab andmetüübi (tehingu 2 jaoks), selle tehingu räsi, tehingu enda tüübi, ajatempli ning sisendid ja väljundid. TxIn sisendid salvestavad selle tehingu räsi, mille väljundile viidatakse, selle väljundi numbri ja baitkoodi ning TxOut väljundid salvestavad mingi väärtuse ja ka baitkoodi.
Nüüd vaatame, milliseid toiminguid saab tehing oma andmetega teha, s.t. Vaatame meetodeid.
Tehingu loomiseks kasutage tehingu.NewTransaction(txtype byte) *TX funktsiooni.
Meetod AddTxIn(thattxhash []bait, txoutn int, kood []bait) (*TxIn, error) lisab tehingule sisendi.
Meetod AddTxOut(väärtus int, data []bait) (*TxOut, error) lisab tehingule väljundi.
Meetod ToBytes() []byte muudab tehingu baidilõikeks.
Sisefunktsiooni stringi preByteHash(baitid []bait) kasutatakse funktsioonides Build() ja Check(), et genereeritud tehinguräsi ühilduks JavaScripti rakendustest genereeritud tehinguräsidega.
Meetod Build() määrab tehingu räsi järgmiselt: tx.TxHash = preByteHash(tx.ToBytes()).
Stringimeetod ToJSON() teisendab tehingu JSON-stringiks.
Tõrkemeetod FromJSON(data []byte) laadib tehingu JSON-vormingust, mis edastatakse baidilõikena.
Meetod Check() võrdleb tehingu räsiväljalt saadud räsi selle tehingu räsimise tulemusel saadud räsiga (räsivälja ignoreerimine).
Tehingud lisatakse plokki:
Plokkide andmestruktuur on mahukam:
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 salvestab andmetüübi, sõlm kasutab seda ja eristab plokki tehingust või muudest andmetest. Ploki puhul on see väärtus 1.
BlockHeight salvestab ploki kõrguse.
Ajatempli ajatempel.
HeaderSize on ploki suurus baitides.
PrevBlockHash on eelmise ploki räsi ja SelfBlockHash on praeguse ploki räsi.
TxsHash on üldine tehingute räsi.
MerkleRoot on Merkle puu juur.
Edasi on väljadel ploki looja avalik võti, looja allkiri, ploki versioon, tehingute arv plokis ja need tehingud ise.
Vaatame selle meetodeid:
Ploki loomiseks kasuta funktsiooni block.NewBlock(): NewBlock(prevBlockHash string, height int) *Block, mis võtab plokiahelas eelmise ploki räsi ja loodud ploki kõrguse. Ploki tüüp määratakse ka tüübipaketi konstandist:
b.DataType = types.BLOCK_TYPE.
AddTx(tx *transaction.TX) meetod lisab plokki tehingu.
Meetod Build() laadib väärtused ploki väljadele ning genereerib ja määrab selle praeguse räsi.
Meetod ToBytesHeader() []byte teisendab ploki päise (ilma tehinguteta) baidilõiguks.
Stringimeetod ToJSON() teisendab ploki JSON-vormingusse andmete stringi esituses.
Tõrkemeetod FromJSON(data []byte) laadib andmed JSON-ist plokistruktuuri.
Check() bool-meetod genereerib ploki räsi ja võrdleb seda ploki räsiväljal määratud räsiga.
Stringimeetod GetTxsHash() tagastab kõigi ploki tehingute koguräsi.
Meetod GetMerkleRoot() määrab plokis tehtavate tehingute jaoks Merkle'i puu juure.
Sign(privk string) meetod allkirjastab ploki ploki looja privaatvõtmega.
SetHeight(height int) meetod kirjutab ploki kõrguse ploki struktuuri väljale.
GetHeight() int meetod tagastab ploki kõrguse, mis on määratud ploki struktuuri vastaval väljal.
Meetod ToGOBBytes() []byte kodeerib ploki GOB-vormingus ja tagastab selle baidilõikena.
Tõrkemeetod FromGOBBytes(data []byte) kirjutab plokiandmed plokistruktuuri läbitud baidilõigust GOB-vormingus.
Stringi meetod GetHash() tagastab antud ploki räsi.
Stringi meetod GetPrevHash() tagastab eelmise ploki räsi.
SetPublicKey(pubk string) meetod kirjutab ploki looja avaliku võtme plokki.
Seega, kasutades Block-objekti meetodeid, saame selle hõlpsalt teisendada vormingusse võrgu kaudu edastamiseks ja LevelDB andmebaasi salvestamiseks.
Plokiahela paketi funktsioonid vastutavad plokiahelasse salvestamise eest:
Selleks peab plokk rakendama IBlocki liidest:
type IGOBBytes interface {
ToGOBBytes() []byte
FromGOBBytes(data []byte) error
}
type IBlock interface {
IGOBBytes
GetHash() string
GetPrevHash() string
GetHeight() int
Check() bool
}
Andmebaasiühendus luuakse üks kord, kui pakett initsialiseeritakse funktsioonis init():
db, err = leveldb.OpenFile(BLOCKCHAIN_DB_DEBUG, nil).
CloseDB() on db.Cloce() ümbris – kutsutakse välja pärast paketifunktsioonidega töötamist, et sulgeda ühendus andmebaasiga.
Veafunktsioon SetTargetBlockHash(hash string) kirjutab praeguse ploki räsi konstandi BLOCK_HASH määratud võtmega andmebaasi.
Funktsioon GetTargetBlockHash() (string, viga) tagastab praeguse andmebaasi salvestatud ploki räsi.
Veafunktsioon SetTargetBlockHeight(height int) kirjutab andmebaasi sõlme plokiahela kõrguse väärtuse konstandiga BLOCK_HEIGHT määratud võtmega.
Funktsioon GetTargetBlockHeight() (int, error) tagastab antud sõlme plokiahela kõrguse, mis on salvestatud andmebaasi.
Tõhendusfunktsioon CheckBlock(block IBlock) kontrollib ploki õigsust enne selle ploki plokiahelasse lisamist.
AddBlock(block IBlock) tõrkefunktsioon lisab plokiahelasse ploki.
Plokkide allalaadimise ja vaatamise funktsioonid on plokiahela paketi explore.go failis:
Funktsioon GetBlockByHash(hash string) (*block.Block, error) loob tühja plokiobjekti, laeb sellesse andmebaasist ploki, mille räsi talle edastati ja tagastab sellele osuti.
Genesis-ploki loomine toimub veafunktsiooni Genesis() abil plokiahela paketi genesis.go failist.
Järgmises artiklis räägitakse klientide ühendamisest sõlmega WebSocketi mehhanismi abil.
Allikas: www.habr.com