Per finisce in fine cù una blockchain è micca solu una basa di dati, avemu bisognu di aghjunghje 3 elementi impurtanti à u nostru prughjettu:
- Descrizzione di a struttura di dati di bloccu è i metudi
- Descrizzione di a struttura di dati è i metudi di transazzione
- Funzioni di Blockchain chì salvanu i blocchi in una basa di dati è li trovanu quì per u so hash o altezza (o qualcos'altro).
Questu hè u sicondu articulu di blockchain per l'industria, u primu
Ricurdativi di e dumande chì i lettori m'hà dumandatu annantu à l'articulu precedente in questa serie, deve esse nutatu: in questu casu, a basa di dati LevelDB hè aduprata per almacenà e dati di blockchain, ma nunda ùn impedisce micca di utilizà qualsiasi altru, dì, MySQL. Avà fighjemu a struttura di sti dati.
Cuminciamu cù e transazzione:
Eccu a so struttura di dati:
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 guarda u tipu di dati (per a transazzione 2), l'hash di quella transazzione, u tipu di a transazzione stessu, un timestamp, è inputs è outputs. L'inputs TxIn almacenanu l'hash di a transazzione chì a so output hè riferita, u numeru di questa output è bytecode, è i outputs TxOut almacenanu qualchì valore è ancu bytecode.
Avà vede ciò chì azzione una transazzione pò fà nantu à i so dati, i.e. Fighjemu i metudi.
Per creà una transazzione, utilizate a transazzione.NewTransaction (txtype byte) * TX funzione.
U metudu AddTxIn (thattxhash []byte, txoutn int, code []byte) (*TxIn, errore) aghjunghje un input à a transazzione.
U metudu AddTxOut (value int, data []byte) (*TxOut, errore) aghjunghje una output à a transazzione.
U metudu ToBytes() []byte trasforma a transazzione in una fetta di byte.
A funzione interna preByteHash(bytes []byte) stringa hè aduprata in Build () è Check () per rende l'hash di transazzione generatu cumpatibile cù l'hash di transazzione generati da l'applicazioni JavaScript.
U metudu Build() stabilisce l'hash di transazzione cum'è seguente: tx.TxHash = preByteHash(tx.ToBytes()).
U metudu di stringa ToJSON() converte una transazzione in una stringa JSON.
U metudu di errore FromJSON (data []byte) carica una transazzione da u formatu JSON passatu cum'è una fetta di byte.
U metudu Check() bool compara l'hash resultante da u campu di l'hash di a transazzione cù l'hash ottenutu da u risultatu di l'hash di sta transazzione (ignorendu u campu di hash).
E transazzione sò aghjuntu à u bloccu:
A struttura di dati di bloccu hè più voluminosa:
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 guarda u tipu di dati, u node l'utiliza è distingue u bloccu da una transazzione o altre dati. Per un bloccu stu valore hè 1.
BlockHeight guarda l'altezza di u bloccu.
Timestamp timestamp.
HeaderSize hè a dimensione di u bloccu in byte.
PrevBlockHash hè l'hash di u bloccu precedente, è SelfBlockHash hè l'hash di l'attuale.
TxsHash hè un hash generale di transazzione.
MerkleRoot hè a radica di l'arburu Merkle.
In più in i campi, ci hè a chjave publica di u creatore di u bloccu, a firma di u creatore, a versione di u bloccu, u nùmeru di transazzione in u bloccu, è sti transazzioni stessi.
Fighjemu i so metudi:
Per creà un blocu, utilizate a funzione block.NewBlock() : NewBlock (prevBlockHash string, height int) *Block, chì piglia l'hash di u bloccu precedente è l'altura stabilita per u bloccu creatu in u blockchain. U tipu di bloccu hè ancu stabilitu da u pacchettu di tippi constanti:
b.DataType = types.BLOCK_TYPE.
U metu AddTx (tx *transaction.TX) aghjunghje una transazzione à un bloccu.
U metudu Build() carica i valori in i campi di u bloccu è genera è stabilisce u so hash attuale.
U metudu ToBytesHeader() []byte converte l'intestazione di bloccu (senza transazzione) in una fetta di byte.
U metudu di stringa ToJSON() converte u bloccu in u formatu JSON in una rapprisintazioni di stringa di e dati.
U metudu di errore FromJSON (data []byte) carica dati da JSON in una struttura di bloccu.
U metudu Check() bool genera un hash di bloccu è u compara cù quellu chì hè specificatu in u campu di bloccu hash.
U metudu di stringa GetTxsHash() torna l'hash tutale di tutte e transazzione in u bloccu.
U metudu GetMerkleRoot() specifica a radica di l'arburu Merkle per transazzione in un bloccu.
U metudu Sign (privk string) firma un bloccu cù a chjave privata di u creatore di bloccu.
U metudu SetHeight(height int) scrive l'altezza di u bloccu à u campu di struttura di bloccu.
U mètudu GetHeight() int torna l'altezza di u bloccu cum'è specificata in u campu currispundente di a struttura di bloccu.
U metudu ToGOBBytes() []byte codifica un bloccu in formatu GOB è u torna cum'è una fetta di byte.
U metudu di errore FromGOBBytes (data []byte) scrive i dati di bloccu à a struttura di bloccu da a fetta di byte passatu in formatu GOB.
U metudu di stringa GetHash() torna l'hash di u bloccu datu.
U metudu di stringa GetPrevHash() torna l'hash di u bloccu precedente.
U metudu SetPublicKey (stringa pubk) scrive a chjave publica di u creatore di bloccu à u bloccu.
Cusì, utilizendu i metudi di l'ughjettu Block, pudemu cunvertisce facilmente in un formatu per a trasmissione nantu à a reta è salvà à a basa di dati LevelDB.
E funzioni di u pacchettu blockchain sò rispunsevuli di salvà à u blockchain:
Per fà questu, u bloccu deve implementà l'interfaccia IBlock:
type IGOBBytes interface {
ToGOBBytes() []byte
FromGOBBytes(data []byte) error
}
type IBlock interface {
IGOBBytes
GetHash() string
GetPrevHash() string
GetHeight() int
Check() bool
}
A cunnessione di basa di dati hè creata una volta quandu u pacchettu hè inizializatu in a funzione init() :
db, err = leveldb.OpenFile(BLOCKCHAIN_DB_DEBUG, nil).
CloseDB () hè un wrapper per db.Cloce () - chjamatu dopu avè travagliatu cù e funzioni di u pacchettu per chjude a cunnessione à a basa di dati.
A funzione d'errore SetTargetBlockHash (hash string) scrive l'hash di u bloccu attuale cù a chjave specificata da a constant BLOCK_HASH à a basa di dati.
A funzione GetTargetBlockHash() (stringa, errore) torna l'hash di u bloccu attuale guardatu in a basa di dati.
A funzione d'errore SetTargetBlockHeight(height int) scrive à a basa di dati u valore di l'altitudine di blockchain per u node cù a chjave specificata da a constant BLOCK_HEIGHT.
A funzione GetTargetBlockHeight() (int, error) torna l'altitudine di u blockchain per un node datu, guardatu in a basa di dati.
A funzione bool CheckBlock (block IBlock) verifica un bloccu per a correzione prima di aghjunghje stu bloccu à a blockchain.
A funzione d'errore AddBlock (block IBlock) aghjunghje un bloccu à u blockchain.
E funzioni per ricuperà è vede i blocchi sò in u schedariu explore.go di u pacchettu blockchain:
A funzione GetBlockByHash(hash string) (*block.Block, error) crea un ughjettu di bloccu viotu, carica un bloccu in questu da a basa di dati, l'hash di quale hè statu passatu à ellu, è torna un punteru à questu.
A creazione di un bloccu di genesi hè realizatu da a funzione d'errore di Genesis () da u schedariu genesis.go di u pacchettu blockchain.
U prossimu articulu parlerà di cunnessione di i clienti à un node utilizendu u mecanismu WebSocket.
Source: www.habr.com