Kuna saaksime lÔpuks luua plokiahela, mitte lihtsalt andmebaasi, peame lisama oma projekti kolm olulist elementi:
- Andmestruktuuri ja blokimeetodite kirjeldus
- Tehingustruktuuri ja meetodite kirjeldus
- Plokiahela funktsioonid, mis salvestavad plokid andmebaasi ja leiavad need seal nende rÀsivÀÀrtuse vÔi kÔrguse (vÔi muul viisil) jÀrgi.

See on teine artikkel plokiahela kohta tööstuses, esimene .
KĂ€ies lĂ€bi kĂŒsimusi, mida lugejad kĂŒsisid eelneva artikli kohta, tuleb mĂ€rkida: plokiahela andmete salvestamiseks kasutatakse antud juhul LevelDB andmebaasi, kuid pole midagi, mis takistaks kasutada mĂ”nda muud, nĂ€iteks MySQL-i. NĂŒĂŒd vaatame nende andmete struktuuri.
Alustame tehingutest:
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-s hoitavad andmetĂŒĂŒbid (tehingu 2 jaoks), selle tehingu hash, tehingu tĂŒĂŒp, ajatempli kood ning sisendid ja vĂ€ljundid. Sisendid TxIn sisaldavad selle tehingu hash'i, millele viidatakse, selle vĂ€ljundi numbrit ja bytekoodi, samas kui vĂ€ljundid TxOut hoiavad mingit vÀÀrtust ja ka bytekoodi.
Vaadakem nĂŒĂŒd, milliseid toiminguid saab tehing oma andmetega teha, st uurime meetodeid.
Tehingu loomiseks kasutatakse funktsiooni transaction.NewTransaction(txtype byte) *TX.
Meetod AddTxIn(thattxhash []byte, txoutn int, code []byte) (*TxIn, error) lisab tehingule sisendi.
Meetod AddTxOut(value int, data []byte) (*TxOut, error) lisab tehingule vÀljundi.
Meetod ToBytes() []byte muudab tehingu byte-slice'iks.
Sisemine funktsioon preByteHash(bytes []byte) string rakendatakse Build() ja Check() funktsioonides, et tagada loodud tehingu hash'i ĂŒhilduvus JavaScript'i rakendustest genereeritud tehingu hash'idega.
Meetod Build() mÀÀrab tehingu hash'i jÀrgmiselt: tx.TxHash = preByteHash(tx.ToBytes()).
Meetod ToJSON() string muundab tehingu JSON stringiks.
Meetod FromJSON(data []byte) error laadib tehingu JSON-formaadist, mis on edastatud byte-slice'ina.
Meetod Check() bool vÔrreldab saadud hash'i tehingu hash'alalt tehingu hash'iga, mis saadakse selle tehingu hash'imise tulemusena (ilma hash'i alampunktita).
Tehingud lisatakse plokki:
Ploki andmestruktuur on suurem:
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 hoiab andmetĂŒĂŒpi, mille pĂ”hjal node eristab plokki tehingust vĂ”i muudest andmetest. Ploki puhul on see vÀÀrtus 1.
BlockHeight hoiab ploki kÔrgust.
Timestamp ajatemplit.
HeaderSize ploki suurust baitides.
PrevBlockHash on eelmise ploki hash ja SelfBlockHash on praegune.
TxsHash on tehingute koguhash.
MerkleRoot on Merkle puu juur.
Edasi, vÀlistes vÀljadest, on ploki looja avalik vÔti, looja allkiri, ploki versioon, tehingute arv plokis ja muidugi ise need tehingud.
Vaadakem tema meetodeid:
Ploki loomisel kasutatakse funktsiooni block.NewBlock(): NewBlock(prevBlockHash string, height int) *Block, mis vĂ”tab vastu eelmise ploki hash'i ja kĂ”rguse, mis on mÀÀratud loodud plokile plokiahelas. Samuti mÀÀratakse ploki tĂŒĂŒp paketist types konstantide abil:
b.DataType = types.BLOCK_TYPE.Meetod AddTx(tx *transaction.TX) lisab plokki tehingu.
Meetod Build() laadib ploki vÀljadele vÀÀrtused ja genereerib ning mÀÀrab selle hetke hash'i.
Meetod ToBytesHeader() []byte muundab ploki pÀise (ilma tehinguteta) baitide lÔiguks.
Meetod ToJSON() string muundab ploki JSON-vormingusse stringi kujul.
Meetod FromJSON(data []byte) error laadib andmed JSON'ist ploki struktuuri.
Meetod Check() bool genereerib ploki hash'i ja vÔrdleb seda ploki hash'i vÀljas mÀÀratud vÀÀrtusega.
Meetod GetTxsHash() string tagastab kÔigi plokis olevate tehingute koguhash'i.
Meetod GetMerkleRoot() mÀÀrab plokis olevate tehingute Merkle puu juure.
Meetod Sign(privk string) allkirjastab ploki looja privaatsuse vÔtmega.
Meetod SetHeight(height int) salvestab ploki kÔrguse ploki struktuuri vÀljal.
Meetod GetHeight() int tagastab ploki kÔrguse, nagu on mÀÀratud ploki struktuuri vastavas vÀljas.
Meetod ToGOBBytes() []byte kodeerib ploki GOB formaati ja tagastab selle baitide lÔiguna.
Meetod FromGOBBytes(data []byte) error kirjutab ploki andmed struktuuri plokist edastatud baitide lÔigus GOB formaadis.
Meetod GetHash() string tagastab selle ploki rĂŒmba.
Meetod GetPrevHash() string tagastab eelmise ploki rĂŒmba.
Meetod SetPublicKey(pubk string) kirjutab plokki looja avaliku vÔtme.
Nii et, objektide Block meetodite abil saame kergesti konverteerida need formaati edastamiseks vÔrgu kaudu ja salvestamiseks LevelDB andmebaasi.
Bloki salvestamise eest vastutavad blockchain paketi funktsioonid:
Selleks peab plokk rakendama liidest IBlock:
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 paketi initsialiseerimise ajal funktsioonis init():
db, err = leveldb.OpenFile(BLOCKCHAIN_DB_DEBUG, nil).CloseDB() on db.Cloce() ĂŒmbrik â kutsutakse vĂ€lja pĂ€rast paketi funktsioonidega töötamist, et sulgeda ĂŒhendus andmebaasiga.
Funktsioon SetTargetBlockHash(hash string) error salvestab andmebaasi praeguse ploki rĂŒmbas vĂ”ti, mille on mÀÀranud konstandi BLOCK_HASH.
GetTargetBlockHash() (string, error) funktsioon tagastab praeguse ploki hash'i, mis on salvestatud andmebaasi.
SetTargetBlockHeight(height int) error funktsioon kirjutab andmebaasi blockchain'i kÔrguse vÀÀrtuse sÔlmele, mille vÔti on mÀÀratud konstant BLOCK_HEIGHT.
GetTargetBlockHeight() (int, error) funktsioon tagastab blockchain'i kÔrguse selle sÔlme jaoks, mis on salvestatud andmebaasi.
CheckBlock(block IBlock) bool funktsioon kontrollib ploki korrektsust enne, kui see plokk lisatakse blockchain'i.
AddBlock(block IBlock) error funktsioon lisab ploki blockchain'i.
Plokkide saamise ja vaatamise funktsioonid on failis explore.go blockchain'i paketis:
GetBlockByHash(hash string) (*block.Block, error) funktsioon loob tĂŒhja ploki objekti, laadib sinna ploki andmebaasist, mille hash on edastatud, ja tagastab sellele nĂ€itaja.
Genesis() error funktsioon, mis asub failis genesis.go blockchain'i paketis, vastutab geenesisploki loomise eest.
JĂ€rgmises artiklis kĂ€sitletakse, kuidas ĂŒhendada klientide sĂ”lmega WebSocket'i mehhanismi abil.
Allikas: habr.com
