Ako som navrhol bloky a transakcie v mojom blockchaine Go

Aby sme nakoniec skončili s blockchainom a nie len databázou, musíme do nášho projektu pridať 3 dôležité prvky:

  • Popis dátovej štruktúry a metód bloku
  • Popis štruktúry údajov a transakčných metód
  • Blockchain funkcie, ktoré ukladajú bloky do databázy a nachádzajú ich tam podľa ich hashu alebo výšky (alebo niečoho iného).

Ako som navrhol bloky a transakcie v mojom blockchaine Go

Toto je druhý článok o blockchaine pre priemysel, prvý tu.

Pri spomienke na otázky, ktoré mi čitatelia položili v súvislosti s predchádzajúcim článkom z tejto série, treba poznamenať: v tomto prípade sa na ukladanie blockchainových dát používa databáza LevelDB, no nič vám nebráni v používaní akéhokoľvek iného, ​​povedzme, MySQL. Teraz sa pozrime na štruktúru týchto údajov.

Začnime s transakciami: github.com/Rusldv/bcstartup/blob/master/transaction/builder.go

Tu je jeho dátová štruktúra:

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 ukladá typ údajov (pre transakciu 2), hash tejto transakcie, typ samotnej transakcie, časovú značku a vstupy a výstupy. Vstupy TxIn uchovávajú hash transakcie, na ktorej výstup sa odkazuje, číslo tohto výstupu a bajtkód a výstupy TxOut ukladajú určitú hodnotu a tiež bajtkód.

Teraz sa pozrime, aké akcie môže transakcia vykonať so svojimi dátami, t.j. Pozrime sa na metódy.

Na vytvorenie transakcie použite funkciutransakcia.NováTransaction(bajt typu TX) *TX.

Metóda AddTxIn(thattxhash []bajt, txoutn int, kód []bajt) (*TxIn, chyba) pridá vstup do transakcie.

Metóda AddTxOut(hodnota int, údaj []bajt) (*TxOut, chyba) pridá výstup do transakcie.

Metóda ToBytes() []byte zmení transakciu na bajtový rez.

Reťazec internej funkcie preByteHash(bytes []byte) sa používa v Build() a Check(), aby bol vygenerovaný hash transakcie kompatibilný s hodnotami hash transakcií generovanými z aplikácií JavaScript.

Metóda Build() nastavuje hodnotu hash transakcie takto: tx.TxHash = preByteHash(tx.ToBytes()).

Metóda reťazca ToJSON() konvertuje transakciu na reťazec JSON.

Chybová metóda FromJSON(data []bajt) načíta transakciu z formátu JSON odovzdaného ako bajtový rez.

Metóda Check() bool porovnáva výsledný hash z hashového poľa transakcie s hashom získaným ako výsledok hashovania tejto transakcie (ignorovaním hash poľa).

Transakcie sa pridávajú do bloku: github.com/Rusldv/bcstartup/blob/master/block/builder.go

Štruktúra údajov bloku je objemnejšia:

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 ukladá typ údajov, uzol ho používa a rozlišuje blok od transakcie alebo iných údajov. Pre blok je táto hodnota 1.

BlockHeight ukladá výšku bloku.
Časová pečiatka časová pečiatka.
HeaderSize je veľkosť bloku v bajtoch.
PrevBlockHash je hash predchádzajúceho bloku a SelfBlockHash je hash aktuálneho bloku.
TxsHash je všeobecný hash transakcií.
MerkleRoot je koreň stromu Merkle.

Ďalej v poliach je verejný kľúč tvorcu bloku, podpis tvorcu, verzia bloku, počet transakcií v bloku a tieto transakcie samotné.

Pozrime sa na jeho metódy:
Na vytvorenie bloku použite funkciu block.NewBlock(): NewBlock(prevBlockHash string, height int) *Block, ktorá prevezme hash predchádzajúceho bloku a výšku nastavenú pre vytvorený blok v blockchaine. Typ bloku sa tiež nastavuje z konštanty balíka typov:

b.DataType = types.BLOCK_TYPE.

Metóda AddTx(tx *transaction.TX) pridá transakciu do bloku.

Metóda Build() načíta hodnoty do polí bloku a vygeneruje a nastaví jeho aktuálny hash.

Metóda ToBytesHeader() []byte konvertuje hlavičku bloku (bez transakcií) na bajtový výsek.

Metóda reťazca ToJSON() konvertuje blok na formát JSON v reťazcovom vyjadrení údajov.

Chybová metóda FromJSON(data []byte) načítava údaje z JSON do blokovej štruktúry.

Bool metóda Check() generuje blokový hash a porovnáva ho s tým, ktorý je zadaný v poli blokového hash.

Metóda reťazca GetTxsHash() vráti celkový hash všetkých transakcií v bloku.

Metóda GetMerkleRoot() určuje koreň stromu Merkle pre transakcie v bloku.

Metóda Sign(privk string) podpíše blok súkromným kľúčom tvorcu bloku.

Metóda SetHeight(height int) zapíše výšku bloku do poľa štruktúry bloku.

Metóda GetHeight() int vracia výšku bloku tak, ako je špecifikovaná v zodpovedajúcom poli štruktúry bloku.

Metóda ToGOBBytes() []byte zakóduje blok vo formáte GOB a vráti ho ako bajtový rez.

Chybová metóda FromGOBBytes(data []byte) zapisuje údaje bloku do štruktúry bloku z odovzdaného bajtového rezu vo formáte GOB.

Reťazcová metóda GetHash() vracia hash daného bloku.

Metóda reťazca GetPrevHash() vráti hash predchádzajúceho bloku.

Metóda SetPublicKey(pubk string) zapíše verejný kľúč tvorcu bloku do bloku.

Pomocou metód objektu Block ho teda jednoducho prevedieme do formátu pre prenos po sieti a uloženie do databázy LevelDB.

Funkcie balíka blockchain sú zodpovedné za ukladanie do blockchainu: github.com/Rusldv/bcstartup/tree/master/blockchain

Na tento účel musí blok implementovať rozhranie IBlock:

type IGOBBytes interface {
	ToGOBBytes() []byte
	FromGOBBytes(data []byte) error
}

type IBlock interface {
	IGOBBytes
	GetHash() string
	GetPrevHash() string
	GetHeight() int
	Check() bool

}

Pripojenie k databáze sa vytvorí raz, keď sa balík inicializuje vo funkcii init():

db, err = leveldb.OpenFile(BLOCKCHAIN_DB_DEBUG, nil).

CloseDB() je obal pre db.Cloce() – volá sa po práci s funkciami balíka na zatvorenie spojenia s databázou.

Chybová funkcia SetTargetBlockHash(reťazec hash) zapíše hash aktuálneho bloku s kľúčom určeným konštantou BLOCK_HASH do databázy.

Funkcia GetTargetBlockHash() (reťazec, chyba) vráti hash aktuálneho bloku uloženého v databáze.

Chybová funkcia SetTargetBlockHeight(height int) zapíše do databázy hodnotu výšky blockchainu pre uzol s kľúčom určeným konštantou BLOCK_HEIGHT.

Funkcia GetTargetBlockHeight() (int, chyba) vracia výšku blockchainu pre daný uzol uloženú v databáze.

Bool funkcia CheckBlock (blok IBlock) kontroluje správnosť bloku pred pridaním tohto bloku do blockchainu.

Chybová funkcia AddBlock (blok IBlock) pridá blok do blockchainu.

Funkcie na načítanie a prezeranie blokov sú v súbore explore.go balíka blockchain:

Funkcia GetBlockByHash(hash string) (*block.Block, error) vytvorí prázdny blokový objekt, načíta do neho z databázy blok, ktorého hash mu bol odovzdaný a vráti naň ukazovateľ.

Vytvorenie bloku genesis sa vykonáva chybovou funkciou Genesis() zo súboru genesis.go balíka blockchain.

Nasledujúci článok bude hovoriť o pripojení klientov k uzlu pomocou mechanizmu WebSocket.

Zdroj: hab.com

Pridať komentár