Kako bismo na kraju dobili blok lanac, a ne samo bazu podataka, našem projektu moramo dodati 3 važna elementa:
- Opis strukture blok podataka i metoda
- Opis strukture podataka i metoda transakcija
- Blockchain funkcije koje spremaju blokove u bazu podataka i tamo ih pronalaze po njihovom hashu ili visini (ili nečem drugom).
Ovo je drugi članak o blockchainu za industriju, prvi
Sjećajući se pitanja koja su mi čitatelji postavili o prethodnom članku u ovoj seriji, treba napomenuti: u ovom slučaju se baza podataka LevelDB koristi za pohranjivanje blockchain podataka, ali ništa vas ne sprječava da koristite bilo koji drugi, recimo, MySQL. Pogledajmo sada strukturu ovih podataka.
Počnimo sa transakcijama:
Evo njegove strukture podataka:
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 pohranjuje tip podataka (za transakciju 2), hash te transakcije, tip same transakcije, vremensku oznaku, te ulaze i izlaze. TxIn ulazi pohranjuju hash transakcije čiji je izlaz referenciran, broj ovog izlaza i bajtkod, a TxOut izlazi pohranjuju neku vrijednost, a također i bajtkod.
Sada da vidimo koje radnje transakcija može izvršiti nad svojim podacima, tj. Pogledajmo metode.
Za kreiranje transakcije koristite funkciju transakcije.NewTransaction(txtype byte) *TX.
Metoda AddTxIn(thattxhash []byte, txoutn int, code []byte) (*TxIn, greška) dodaje ulaz u transakciju.
Metoda AddTxOut(vrijednost int, podaci []bajt) (*TxOut, greška) dodaje izlaz transakciji.
Metoda ToBytes() []byte pretvara transakciju u odsječak bajta.
Interna funkcija preByteHash(bytes []byte) string se koristi u Build() i Check() kako bi generirani heš transakcije bio kompatibilan sa hešovima transakcija generiranim iz JavaScript aplikacija.
Metoda Build() postavlja heš transakcije na sljedeći način: tx.TxHash = preByteHash(tx.ToBytes()).
Metoda stringa ToJSON() pretvara transakciju u JSON string.
Metoda greške FromJSON(podaci []bajt) učitava transakciju iz JSON formata proslijeđenu kao odsječak bajta.
Check() bool metoda uspoređuje rezultujući heš iz heš polja transakcije sa hešom dobijenim kao rezultat heširanja ove transakcije (zanemarujući heš polje).
Transakcije se dodaju u blok:
Blok struktura podataka je obimnija:
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 pohranjuje tip podataka, čvor ga koristi i razlikuje blok od transakcije ili drugih podataka. Za blok ova vrijednost je 1.
BlockHeight pohranjuje visinu bloka.
Vremenska oznaka vremenska oznaka.
HeaderSize je veličina bloka u bajtovima.
PrevBlockHash je hash prethodnog bloka, a SelfBlockHash je hash trenutnog.
TxsHash je opći hash transakcija.
MerkleRoot je korijen Merkle drveta.
Dalje u poljima se nalazi javni ključ kreatora bloka, potpis kreatora, verzija bloka, broj transakcija u bloku i same te transakcije.
Pogledajmo njegove metode:
Za kreiranje bloka koristite funkciju block.NewBlock(): NewBlock(prevBlockHash string, visina int) *Block, koji uzima hash prethodnog bloka i visinu postavljenu za kreirani blok u blockchainu. Tip bloka se također postavlja iz konstante paketa tipova:
b.DataType = types.BLOCK_TYPE.
Metoda AddTx(tx *transaction.TX) dodaje transakciju u blok.
Metoda Build() učitava vrijednosti u polja bloka i generiše i postavlja njegov trenutni hash.
Metoda ToBytesHeader() []byte pretvara zaglavlje bloka (bez transakcija) u odsječak bajta.
Metoda stringa ToJSON() pretvara blok u JSON format u string prikazu podataka.
Metod greške FromJSON(data []byte) učitava podatke iz JSON-a u blok strukturu.
Check() bool metoda generiše blok heš i upoređuje ga sa onim specificiranim u polju heš bloka.
Metoda stringa GetTxsHash() vraća ukupni hash svih transakcija u bloku.
Metoda GetMerkleRoot() specificira korijen Merkle stabla za transakcije u bloku.
Metoda Sign(privk string) potpisuje blok privatnim ključem kreatora bloka.
Metoda SetHeight(height int) zapisuje visinu bloka u polje strukture bloka.
GetHeight() int metoda vraća visinu bloka kako je navedeno u odgovarajućem polju strukture bloka.
Metoda ToGOBBytes() []byte kodira blok u GOB formatu i vraća ga kao odsječak bajta.
Metoda greške FromGOBBytes(data []byte) upisuje blok podatke u strukturu bloka iz proslijeđenog bajtnog dijela u GOB formatu.
Metoda stringa GetHash() vraća hash datog bloka.
Metoda stringa GetPrevHash() vraća hash prethodnog bloka.
Metoda SetPublicKey(pubk string) upisuje javni ključ kreatora bloka u blok.
Dakle, koristeći metode Block objekta, možemo ga lako pretvoriti u format za prijenos preko mreže i spremanje u LevelDB bazu podataka.
Funkcije blockchain paketa odgovorne su za spremanje u blockchain:
Da bi to uradio, blok mora implementirati IBlock sučelje:
type IGOBBytes interface {
ToGOBBytes() []byte
FromGOBBytes(data []byte) error
}
type IBlock interface {
IGOBBytes
GetHash() string
GetPrevHash() string
GetHeight() int
Check() bool
}
Veza baze podataka se kreira jednom kada se paket inicijalizira u funkciji init():
db, err = leveldb.OpenFile(BLOCKCHAIN_DB_DEBUG, nil).
CloseDB() je omot za db.Cloce() - poziva se nakon rada sa funkcijama paketa da zatvori vezu s bazom podataka.
Funkcija greške SetTargetBlockHash(hash string) zapisuje hash trenutnog bloka s ključem specificiranim konstantom BLOCK_HASH u bazu podataka.
Funkcija GetTargetBlockHash() (string, greška) vraća hash trenutnog bloka pohranjenog u bazi podataka.
Funkcija greške SetTargetBlockHeight(height int) upisuje u bazu podataka vrijednost visine blockchaina za čvor s ključem specificiranim konstantom BLOCK_HEIGHT.
Funkcija GetTargetBlockHeight() (int, error) vraća visinu blockchaina za dati čvor, pohranjenu u bazi podataka.
CheckBlock(block IBlock) bool funkcija provjerava ispravnost bloka prije dodavanja ovog bloka u blockchain.
Funkcija greške AddBlock(block IBlock) dodaje blok u blockchain.
Funkcije za dohvaćanje i pregled blokova nalaze se u datoteci explore.go paketa blockchain:
Funkcija GetBlockByHash(hash string) (*block.Block, error) kreira prazan objekt bloka, učitava blok u njega iz baze podataka, čiji je hash proslijeđen u njega, i vraća pokazivač na njega.
Kreiranje genesis bloka vrši se funkcijom greške Genesis() iz genesis.go datoteke paketa blockchain.
Sljedeći članak će govoriti o povezivanju klijenata na čvor pomoću mehanizma WebSocket.
izvor: www.habr.com