Hoe ek blokke en transaksies op My Go Blockchain ontwerp het

Om uiteindelik 'n blokketting te kry, en nie net 'n databasis nie, moet ons 3 belangrike elemente by ons projek voeg:

  • Beskrywing van die datastruktuur en blokmetodes
  • Beskrywing van die datastruktuur en transaksiemetodes
  • Blockchain-funksies wat blokke in die databasis stoor en dit daar vind volgens hul hash of hoogte (of wat ook al).

Hoe ek blokke en transaksies op My Go Blockchain ontwerp het

Dit is die tweede artikel oor blockchain vir die industrie, die eerste hier.

Onthou die vrae wat lesers my gevra het vir die vorige artikel in hierdie reeks, moet daarop gelet word: in hierdie geval word die LevelDB-databasis gebruik om blokkettingdata te stoor, maar niks verhoed die gebruik van enige ander nie, sΓͺ dieselfde MySQL. Kom ons kyk nou na die struktuur van hierdie data.

Kom ons begin met transaksies: github.com/Rusldv/bcstartup/blob/master/transaction/builder.go

Hier is sy datastruktuur:

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 stoor die tipe data (vir transaksie 2), die hash van hierdie transaksie, die tipe van die transaksie self, die tydstempel, sowel as insette en uitsette. Die TxIn-insette stoor die hash van die transaksie na wie se uitset verwys word, die nommer van hierdie uitset en die greepkode, en die TxOut-uitsette stoor 'n mate van waarde en ook die greepkode.

Kom ons kyk nou watter aksies 'n transaksie op sy data kan uitvoer, m.a.w. Kom ons kyk na die metodes.

Die transaction.NewTransaction(TXtype byte) *TX-funksie word gebruik om 'n transaksie te skep.

Die AddTxIn(thattxhash []byte, txoutn int, kode []byte) (*TxIn, fout) metode voeg 'n inset by die transaksie.

Die AddTxOut(waarde int, data []byte) (*TxOut, fout) metode voeg 'n uitvoer by die transaksie.

Die ToBytes() []byte-metode verander 'n transaksie in 'n byte-sny.

Die preByteHash(bytes []byte)-string interne funksie word in Build() en Check() gebruik om te verseker dat die gegenereerde transaksie-hash versoenbaar is met transaksie-hashes wat uit JavaScript-toepassings gegenereer word.

Die Build()-metode stel die transaksie-hash soos volg: tx.TxHash = preByteHash(tx.ToBytes()).

Die ToJSON()-stringmetode skakel die transaksie om na 'n JSON-string.

Die FromJSON(data []byte)-foutmetode laai 'n transaksie vanaf die JSON-formaat wat as 'n byte-sny deurgegee word.

Die Check() bool metode vergelyk die ontvang hash van die hash veld van die transaksie met die hash verkry as gevolg van hash hierdie transaksie (uitgesluit die hash veld).

Transaksies word by die blok gevoeg: github.com/Rusldv/bcstartup/blob/master/block/builder.go

Die blokdatastruktuur is meer omvangryk:

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 stoor die tipe data, waarvolgens die nodus die blok van die transaksie of ander data skei. Vir 'n blok is hierdie waarde 1.

BlockHeight stoor die hoogte van die blok.
tydstempel tydstempel.
Kopgrootte blokgrootte in grepe.
PrevBlockHash is die hash van die vorige blok, en SelfBlockHash is die hash van die huidige blok.
TxsHash is die totale transaksie-hash.
MerkleRoot is die wortel van die Merkle-boom.

Verder bevat die velde die publieke sleutel van die blokskepper, die skepper se handtekening, die blokweergawe, die aantal transaksies in die blok, en hierdie transaksies self.

Oorweeg sy metodes:
Om 'n blok te skep, word die block.NewBlock() funksie gebruik: NewBlock(prevBlockHash string, height int) *Blok, wat die hash van die vorige blok en die hoogte gestel vir die geskepde blok in die blokketting neem. Die bloktipe word ook ingestel vanaf die tipes pakketkonstante:

b.DataType = types.BLOCK_TYPE.

Die AddTx(tx *transaction.TX) metode voeg 'n transaksie by 'n blok.

Die Build()-metode laai die waardes in die blokvelde en genereer en stel sy huidige hash.

Die ToBytesHeader() []byte-metode vertaal die blokopskrif (sonder transaksies) in 'n greepsnit.

Die ToJSON()-stringmetode skakel die blok om na JSON-formaat in 'n stringvoorstelling van die data.

Die FromJSON(data []byte)-foutmetode laai data vanaf JSON in 'n blokstruktuur.

Die Check() bool-metode genereer die hash van die blok en vergelyk dit met die een gespesifiseer in die hash-veld van die blok.

Die GetTxsHash()-stringmetode gee die totale hash van alle transaksies in die blok terug.

Die GetMerkleRoot()-metode stel die wortel van die Merkle-boom vir transaksies in die blok.

Die Teken (privk string) metode teken die blok met die private sleutel van die blok skepper.

Die SetHeight(height int) metode skryf die blokhoogte na die blokstruktuurveld.

Die GetHeight() int metode gee die hoogte van die blok terug soos gespesifiseer in die ooreenstemmende veld van die blokstruktuur.

Die ToGOBBytes() []byte-metode kodeer 'n blok in GOB-formaat en gee dit terug as 'n byte-sny.

Die FromGOBBytes(data []byte)-foutmetode skryf blokdata na die blokstruktuur vanaf die geslaagde byte-sny in GOB-formaat.

Die GetHash()-stringmetode gee die hash van die gegewe blok terug.

Die GetPrevHash()-stringmetode gee die hash van die vorige blok terug.

Die SetPublicKey(pubk-string)-metode skryf die publieke sleutel van die blokskepper na die blok.

Dus, deur die metodes van die Blok-objek te gebruik, kan ons dit maklik omskep in 'n formaat vir oordrag oor die netwerk en stoor dit in die LevelDB-databasis.

Die funksies van die blokkettingpakket is verantwoordelik vir besparing in die blokketting: github.com/Rusldv/bcstartup/tree/master/blockchain

Om dit te doen, moet die blok die IBlock-koppelvlak implementeer:

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

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

}

Die databasisverbinding word een keer geskep wanneer die pakket in die init()-funksie geΓ―nisialiseer word:

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

CloseDB() is 'n omhulsel vir db.Cloce() - genoem nadat met pakketfunksies gewerk is om die databasisverbinding te sluit.

Die SetTargetBlockHash (hash string) foutfunksie skryf die hash van die huidige blok met die sleutel gespesifiseer deur die BLOCK_HASH konstante na die databasis.

Die GetTargetBlockHash() (string, fout) funksie gee die hash terug van die huidige blok wat in die databasis gestoor is.

Die SetTargetBlockHeight(height int) foutfunksie skryf die blokkettinghoogtewaarde vir die nodus na die databasis met die sleutel gespesifiseer deur die BLOCK_HEIGHT konstante.

Die GetTargetBlockHeight() (int, error) funksie gee die blokhoogte vir die gegewe nodus terug, gestoor in die databasis.

Die CheckBlock (block IBlock) bool-funksie kontroleer die blok vir geldigheid voordat hierdie blok by die blokketting gevoeg word.

Die AddBlock (blok IBlock) foutfunksie voeg 'n blok by die blokketting.

Die funksies om blokke te kry en te bekyk, is in die explore.go-lΓͺer van die blokkettingpakket geleΓ«:

Die GetBlockByHash(hash string) (*block.Block, error) funksie skep 'n leΓ« blok voorwerp, laai 'n blok daar van die databasis wie se hash daarheen deurgegee is, en stuur 'n wyser daarna terug.

Die skepping van die genesis-blok word uitgevoer deur die Genesis()-foutfunksie vanaf die genesis.go-lΓͺer van die blokkettingpakket.

In die volgende artikel sal ons praat oor die koppeling van kliΓ«nte aan die nodus met behulp van die WebSocket-meganisme.

Bron: will.com

Voeg 'n opmerking