Cumu aghju disignatu blocchi è transazzioni in u mo Go blockchain

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).

Cumu aghju disignatu blocchi è transazzioni in u mo Go blockchain

Questu hè u sicondu articulu di blockchain per l'industria, u primu ccà.

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: github.com/Rusldv/bcstartup/blob/master/transaction/builder.go

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: github.com/Rusldv/bcstartup/blob/master/block/builder.go

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: github.com/Rusldv/bcstartup/tree/master/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

Add a comment