Da bi na koncu imeli verigo blokov in ne samo bazo podatkov, moramo našemu projektu dodati 3 pomembne elemente:
- Opis podatkovne strukture in metod bloka
- Opis strukture podatkov in transakcijskih metod
- Blockchain funkcije, ki shranjujejo bloke v zbirko podatkov in jih tam najdejo po zgoščeni vrednosti ali višini (ali čem drugem).
To je drugi članek o blockchainu za industrijo, prvi
Če se spomnimo vprašanj, ki so mi jih bralci zastavili o prejšnjem članku v tej seriji, je treba opozoriti: v tem primeru se baza podatkov LevelDB uporablja za shranjevanje podatkov verige blokov, vendar vam nič ne preprečuje uporabe katerega koli drugega, recimo MySQL. Zdaj pa poglejmo strukturo teh podatkov.
Začnimo s transakcijami:
Tukaj je njegova struktura podatkov:
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 shrani vrsto podatkov (za transakcijo 2), zgoščeno vrednost te transakcije, vrsto same transakcije, časovni žig ter vhode in izhode. Vhodi TxIn shranijo zgoščeno vrednost transakcije, katere izhod se sklicuje, številko tega izhoda in bajtno kodo, izhodi TxOut pa shranijo nekaj vrednosti in tudi bajtno kodo.
Zdaj pa poglejmo, katera dejanja lahko transakcija izvede na svojih podatkih, tj. Poglejmo si metode.
Če želite ustvariti transakcijo, uporabite funkcijo transaction.NewTransaction(txtype byte) *TX.
Metoda AddTxIn(thattxhash []byte, txoutn int, code []byte) (*TxIn, error) transakciji doda vnos.
Metoda AddTxOut(value int, data []byte) (*TxOut, error) transakciji doda izhod.
Metoda ToBytes() []byte spremeni transakcijo v bajtno rezino.
Niz notranje funkcije preByteHash(bytes []byte) se uporablja v Build() in Check(), da naredi ustvarjeno zgoščeno vrednost transakcije združljivo z zgoščeno vrednostjo transakcije, ustvarjeno iz aplikacij JavaScript.
Metoda Build() nastavi zgoščeno vrednost transakcije na naslednji način: tx.TxHash = preByteHash(tx.ToBytes()).
Metoda niza ToJSON() pretvori transakcijo v niz JSON.
Metoda napake FromJSON(data []byte) naloži transakcijo iz formata JSON, posredovanega kot bajtna rezina.
Metoda Check() bool primerja dobljeno zgoščeno vrednost iz polja zgoščene vrednosti transakcije z zgoščeno vrednostjo, pridobljeno kot rezultat zgoščevanja te transakcije (brez upoštevanja polja zgoščene vrednosti).
Transakcije se dodajo v blok:
Podatkovna struktura blokov je bolj obsežna:
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 shrani podatkovni tip, vozlišče ga uporabi in loči blok od transakcije ali drugih podatkov. Za blok je ta vrednost 1.
BlockHeight shrani višino bloka.
Časovni žig časovni žig.
HeaderSize je velikost bloka v bajtih.
PrevBlockHash je zgoščena vrednost prejšnjega bloka, SelfBlockHash pa zgoščena vrednost trenutnega.
TxsHash je splošno zgoščevanje transakcij.
MerkleRoot je koren drevesa Merkle.
Nadalje v poljih je javni ključ kreatorja bloka, podpis kreatorja, različica bloka, število transakcij v bloku in te transakcije same.
Oglejmo si njegove metode:
Če želite ustvariti blok, uporabite funkcijo block.NewBlock(): NewBlock(prevBlockHash string, height int) *Block, ki vzame zgoščeno vrednost prejšnjega bloka in višino, nastavljeno za ustvarjeni blok v verigi blokov. Tip bloka je nastavljen tudi iz konstante paketa tipov:
b.DataType = types.BLOCK_TYPE.
Metoda AddTx(tx *transaction.TX) doda transakcijo v blok.
Metoda Build() naloži vrednosti v polja bloka ter ustvari in nastavi njegovo trenutno zgoščeno vrednost.
Metoda ToBytesHeader() []byte pretvori glavo bloka (brez transakcij) v bajtno rezino.
Metoda nizov ToJSON() pretvori blok v format JSON v nizski predstavitvi podatkov.
Metoda napake FromJSON(data []byte) naloži podatke iz JSON v strukturo blokov.
Metoda Check() bool generira zgoščeno vrednost bloka in jo primerja s tisto, navedeno v polju zgoščene vrednosti bloka.
Metoda niza GetTxsHash() vrne skupno zgoščeno vrednost vseh transakcij v bloku.
Metoda GetMerkleRoot() podaja koren drevesa Merkle za transakcije v bloku.
Metoda Sign(privk string) podpiše blok z zasebnim ključem ustvarjalca bloka.
Metoda SetHeight(height int) zapiše višino bloka v polje strukture bloka.
Metoda GetHeight() int vrne višino bloka, kot je določeno v ustreznem polju strukture bloka.
Metoda ToGOBBytes() []byte kodira blok v formatu GOB in ga vrne kot bajtno rezino.
Metoda napake FromGOBBytes(data []byte) zapiše podatke bloka v strukturo bloka iz posredovane rezine bajta v formatu GOB.
Metoda niza GetHash() vrne zgoščeno vrednost danega bloka.
Metoda niza GetPrevHash() vrne zgoščeno vrednost prejšnjega bloka.
Metoda SetPublicKey(pubk string) zapiše javni ključ ustvarjalca bloka v blok.
Tako ga z metodami objekta Block enostavno pretvorimo v obliko za prenos po omrežju in shranjevanje v bazo LevelDB.
Funkcije paketa blockchain so odgovorne za shranjevanje v blockchain:
Če želite to narediti, mora blok izvajati vmesnik IBlock:
type IGOBBytes interface {
ToGOBBytes() []byte
FromGOBBytes(data []byte) error
}
type IBlock interface {
IGOBBytes
GetHash() string
GetPrevHash() string
GetHeight() int
Check() bool
}
Povezava z bazo podatkov se ustvari enkrat, ko je paket inicializiran v funkciji init():
db, err = leveldb.OpenFile(BLOCKCHAIN_DB_DEBUG, nil).
CloseDB() je ovoj za db.Cloce() - poklican po delu s funkcijami paketa za zapiranje povezave z bazo podatkov.
Funkcija napake SetTargetBlockHash(hash string) v bazo podatkov zapiše zgoščeno vrednost trenutnega bloka s ključem, ki ga določa konstanta BLOCK_HASH.
Funkcija GetTargetBlockHash() (niz, napaka) vrne zgoščeno vrednost trenutnega bloka, shranjenega v bazi podatkov.
Funkcija napake SetTargetBlockHeight(height int) zapiše v bazo podatkov vrednost višine verige blokov za vozlišče s ključem, ki ga določa konstanta BLOCK_HEIGHT.
Funkcija GetTargetBlockHeight() (int, error) vrne višino verige blokov za dano vozlišče, shranjeno v bazi podatkov.
Funkcija CheckBlock(block IBlock) bool preveri pravilnost bloka, preden ga doda v verigo blokov.
Funkcija napake AddBlock(block IBlock) doda blok v verigo blokov.
Funkcije za pridobivanje in ogled blokov so v datoteki explore.go paketa blockchain:
Funkcija GetBlockByHash(hash string) (*block.Block, error) ustvari prazen objekt bloka, vanj naloži blok iz baze podatkov, katere hash je bil posredovan vanj, in vrne kazalec nanj.
Ustvarjanje bloka genesis izvede funkcija napake Genesis() iz datoteke genesis.go paketa blockchain.
Naslednji članek bo govoril o povezovanju odjemalcev z vozliščem z uporabo mehanizma WebSocket.
Vir: www.habr.com