Kuna plokiahelaks saamine eeldab, et te ei kasuta lihtsalt andmebaasi, peame oma projektile lisama kolm olulist elementi:
- Ploki andmestruktuuri ja meetodite kirjeldus
- Tehingu andmestruktuuri ja meetodite kirjeldus
- Plokiahela funktsioonid, mis salvestavad plokid andmebaasi ja leiavad need seal nende hash'i vÔi kÔrguse (vÔi muude viiside) jÀrgi.

See on teine artikkel plokiahela kohta tööstuses, esimene .
Meeldetuletus, arvestades kĂŒsimusi, mis mulle eelneva artikli puhul esitati, tuleks mĂ€rkida: plokiahela andmete salvestamiseks kasutatakse antud juhul LevelDB andmebaasi, kuid miski ei takista kasutada mĂ”nda muud, nĂ€iteks MySQL. NĂŒĂŒd uurime 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 hoitakse andmetĂŒĂŒpi (tehingu jaoks 2), selle tehingu hash'i, tehingu tĂŒĂŒpi, ajatemplit ning sisse- ja vĂ€ljaminekuid. Sisseanded TxIn hoiavad tehingu hash'i, millele viidatakse, selle vĂ€ljamineku numbrit ja bytecode'i, vĂ€ljundid TxOut hoiavad mingit vÀÀrtust ja samuti bytecode'i.
NĂŒĂŒd vaatame, milliseid toiminguid vĂ”ib tehing andmetega teha, st uurime meetodeid.
Tehingu loomiseks on funktsioon transaction.NewTransaction(txtype byte) *TX.
Meetod AddTxIn(thattxhash []byte, txoutn int, code []byte) (*TxIn, error) lisab tehingule sissekande.
Meetod AddTxOut(value int, data []byte) (*TxOut, error) lisab tehingule vÀljundi.
Meetod ToBytes() []byte muudab tehingu byte-salvestusjÀrguks.
Sisefunktsioon preByteHash(bytes []byte) string rakendatakse funktsioonides Build() ja Check() tehingu hash'i ĂŒhilduvuse tagamiseks JavaScripti rakendustest genereeritud tehingu hash'idega.
Meetod Build() mÀÀrab tehingu hash'i jÀrgmiselt: tx.TxHash = preByteHash(tx.ToBytes()).
Meetod ToJSON() string konverteerib tehingu JSON stringiks.
Meetod FromJSON(data []byte) error laadib tehingu JSON-formaadist, mis edastatakse byte-salvestusjÀrguna.
Meetod Check() bool vÔrreldab vÀljastatud hash'i tehingu hash'i vÀlja, mis saadi selle tehingu hash'imise tulemusena (ilma hash'i vÀlja arvestamata).
Tehingud lisatakse plokkidesse:
Bloki andmete struktuur 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 andmete tĂŒĂŒbi, selle jĂ€rgi eristab sĂ”lm bloki tehingutest vĂ”i muudest andmetest. Bloki puhul on selle vÀÀrtus 1.
BlockHeight salvestab bloki kÔrguse.
Timestamp on ajamÀrk.
HeaderSize on bloki suurus baitides.
PrevBlockHash on eelmise bloki hash, samas kui SelfBlockHash â praegune.
TxsHash on kÔigi tehingute koondhash.
MerkleRoot on Merkle puu juur.
Edasi vÀljadel on bloki looja avalik vÔti, looja allkiri, bloki versioon, tehingute arv blokis ja need tehingud ise.
Vaadakem selle meetodeid:
Bloki loomiseks kasutatakse funktsiooni block.NewBlock(): NewBlock(prevBlockHash string, height int) *Block, mis vĂ”tab vastu eelmise bloki hash'i ja kĂ”rguse, mis on loodud bloki jaoks plokiahelas. Samuti mÀÀratakse bloki tĂŒĂŒp types paketi konstandist:
b.DataType = types.BLOCK_TYPE.Meetod AddTx(tx *transaction.TX) lisab tehingu blokki.
Meetod Build() laadib vÀÀrtused bloki vÀljadessa ja genereerib ning seadistab selle praeguse hash'i.
Meetod ToBytesHeader() []byte teisendab bloki pealkirja (ilma tehinguteta) baitide lÔikeks.
Meetod ToJSON() string teisendab bloki JSON formaati stringi andmete kujul.
Meetod FromJSON(data []byte) error laadib andmed JSON'ist bloki struktuuri.
Meetod Check() bool genereerib bloki hash'i ja vÔrdleb seda bloki hash'i vÀljas mÀÀratletud vÀÀrtusega.
Meetod GetTxsHash() string tagastab kÔigi tehingute koondhash'i blokis.
Meetod GetMerkleRoot() mÀÀrab bloki tehingute Merkle puu juure.
Meetod Sign(privk string) allkirjastab bloki looja privaatvÔtmega.
Meetod SetHeight(height int) kirjutab bloki kÔrguse struktuuri vÀli.
Meetod GetHeight() int tagastab bloki kÔrguse, nagu on mÀÀratud struktuuri vÀljas.
Meetod ToGOBBytes() []byte kodeerib bloki GOB formaati ja tagastab selle baitide lÔikena.
Meetod FromGOBBytes(data []byte) error kirjutab bloki andmed struktuuri GOB formaadis edastatud baitide lÔikest.
Meetod GetHash() string tagastab antud bloki hash'i.
Meetod GetPrevHash() string tagastab eelmise bloki hash'i.
Meetod SetPublicKey(pubk string) kirjutab bloki sisse looja avaliku vÔti.
Seega saame Block objekti meetodite abil hÔlpsasti konverteerida selle vÔrgu edastamiseks ja LevelDB andmebaasi salvestamiseks sobivasse vormi.
Plokiahela salvestamise eest vastutavad blockchain paketi funktsioonid:
Selleks peab blokki rakendama IBlock liidest:
type IGOBBytes interface {
ToGOBBytes() []byte
FromGOBBytes(data []byte) error
}
type IBlock interface {
IGOBBytes
GetHash() string
GetPrevHash() string
GetHeight() int
Check() bool
}Andmebaasiga ĂŒhendus luuakse ĂŒks kord paketi initsialiseerimise ajal init() funktsioonis:
db, err = leveldb.OpenFile(BLOCKCHAIN_DB_DEBUG, nil).CloseDB() on db.Close() ĂŒmberminek â seda kutsutakse vĂ€lja pĂ€rast paketi funktsioonidega töötamist, et sulgeda andmebaasiga ĂŒhendus.
Funktsioon SetTargetBlockHash(hash string) error salvestab andmebaasi praeguse ploki hash'i vÔtme all, mille mÀÀrab konstandi BLOCK_HASH vÀÀrtus.
Funktsioon GetTargetBlockHash() (string, error) tagastab andmebaasis hoitud praeguse ploki hash'i.
Funktsioon SetTargetBlockHeight(height int) error salvestab andmebaasi plokiahela kÔrguse vÀÀrtuse sÔlmele, mille mÀÀrab konstandi BLOCK_HEIGHT vÔtme vÀÀrtus.
Funktsioon GetTargetBlockHeight() (int, error) tagastab antud sÔlme plokiahela kÔrguse, mis on salvestatud andmebaasis.
Funktsioon CheckBlock(block IBlock) bool kontrollib ploki Ôigsust enne selle lisamist plokiahelasse.
Funktsioon AddBlock(block IBlock) error lisab ploki plokiahelasse.
Blokke saamiseks ja vaatamiseks mÔeldud funktsioonid asuvad blockchain paketi failis explore.go:
Funktsioon GetBlockByHash(hash string) (*block.Block, error) loob tĂŒhi ploki objekti, laadib sinna andmebaasist ploki, mille hash on talle edastatud, ja tagastab sellele viitaja.
Genezise ploki loomine toimub funktsiooni Genesis() error kaudu blockchain paketi failist genesis.go.
jĂ€rgmisel artiklil rÀÀgitakse klientide sĂ”lme ĂŒhendamisest WebSocket mehhanismi abil.
Allikas: habr.com
