Wéi hunn ech Blocken an Transaktiounen a mengem Go Blockchain entworf

Fir schlussendlech mat enger Blockchain opzehalen an net nëmmen eng Datebank, musse mir 3 wichteg Elementer fir eise Projet bäidroen:

  • Beschreiwung vun der Blockdatenstruktur a Methoden
  • Beschreiwung vun Daten Struktur an Transaktioun Methoden
  • Blockchain Funktiounen déi Blocken an enger Datebank späicheren an se do duerch hiren Hash oder Héicht (oder soss eppes) fannen.

Wéi hunn ech Blocken an Transaktiounen a mengem Go Blockchain entworf

Dëst ass den zweeten Artikel iwwer Blockchain fir Industrie, den éischten hei.

Erënnert un d'Froen, déi d'Lieser mir iwwer de fréieren Artikel an dëser Serie gefrot hunn, sollt et bemierkt ginn: an dësem Fall gëtt d'LevelDB-Datebank benotzt fir Blockchain-Daten ze späicheren, awer näischt verhënnert Iech all aner ze benotzen, soen, MySQL. Loosst eis elo d'Struktur vun dësen Donnéeën kucken.

Loosst eis mat Transaktiounen ufänken: github.com/Rusldv/bcstartup/blob/master/transaction/builder.go

Hei ass seng Datestruktur:

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 späichert d'Datentyp (fir Transaktioun 2), den Hash vun där Transaktioun, den Typ vun der Transaktioun selwer, en Zäitstempel, an Inputen an Ausgänge. TxIn Input späichert den Hash vun der Transaktioun op deenen hir Ausgang referenzéiert ass, d'Zuel vun dësem Output a Bytecode, an TxOut Ausgänge späicheren e Wäert an och Bytecode.

Loosst eis elo kucken wéi eng Handlungen eng Transaktioun op seng Donnéeën ausféiere kann, d.h. Loosst eis d'Methoden kucken.

Fir eng Transaktioun ze kreéieren, benotzt d'Transaktioun.NewTransaction(TXtype Byte) *TX function.

D'AddTxIn(thattxhash []byte, txoutn int, code []byte) (*TxIn, Feeler) Method füügt en Input un d'Transaktioun.

D'AdTxOut (Wäert int, Daten [] byte) (*TxOut, Feeler) Method füügt en Ausgang un d'Transaktioun.

D'ToBytes () [] Byte Method verwandelt d'Transaktioun an eng Byte Slice.

Déi intern Funktioun preByteHash (Bytes [] Byte) String gëtt am Build () a Check () benotzt fir de generéierten Transaktiounshash kompatibel mat Transaktiounshashen ze maachen, déi aus JavaScript Uwendungen generéiert ginn.

D'Build() Method setzt den Transaktiounshash wéi follegt: tx.TxHash = preByteHash(tx.ToBytes()).

D'ToJSON () String Method konvertéiert eng Transaktioun an eng JSON String.

D'FromJSON (Daten [] Byte) Feeler Method lued eng Transaktioun aus dem JSON Format als Byte Slice weiderginn.

D'Check () bool Method vergläicht de resultéierende Hash aus dem Transaktiounshashfeld mam Hash, deen als Resultat vun dëser Transaktioun kritt gëtt (d'Hash Feld ignoréiert).

Transaktioune ginn an de Block bäigefüügt: github.com/Rusldv/bcstartup/blob/master/block/builder.go

D'Blockdatenstruktur ass méi voluminös:

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 späichert den Datentyp, den Node benotzt se an ënnerscheet de Block vun enger Transaktioun oder aner Donnéeën. Fir e Block ass dëse Wäert 1.

BlockHeight späichert d'Héicht vum Block.
Zäitstempel Zäitstempel.
HeaderSize ass d'Blockgréisst a Bytes.
PrevBlockHash ass den Hash vum fréiere Block, an SelfBlockHash ass den Hash vum aktuellen.
TxsHash ass en allgemenge Hash vun Transaktiounen.
MerkleRoot ass d'Wurzel vum Merkle Bam.

Weider an de Felder gëtt et den ëffentleche Schlëssel vum Ersteller vum Block, d'Ënnerschrëft vum Ersteller, d'Versioun vum Block, d'Zuel vun den Transaktiounen am Block, an dës Transaktioune selwer.

Loosst eis seng Methoden kucken:
Fir e Block ze kreéieren, benotzt d'Block.NewBlock() Funktioun: NewBlock(prevBlockHash string, height int) *Block, deen den Hash vum fréiere Block an d'Héicht fir de erstallte Block an der Blockchain hëlt. De Blocktyp gëtt och aus der Type Package konstant gesat:

b.DataType = types.BLOCK_TYPE.

D'AdTx(tx *transaction.TX) Method füügt eng Transaktioun un e Block derbäi.

D'Build() Method lued Wäerter an d'Felder vum Block a generéiert a setzt säin aktuellen Hash.

D'ToBytesHeader () [] Byte Method konvertéiert de Block Header (ouni Transaktiounen) an eng Byte Slice.

D'ToJSON () String Method konvertéiert de Block op JSON Format an enger String Representatioun vun den Daten.

D'FromJSON (Daten [] Byte) Feeler Method lued Daten vum JSON an eng Blockstruktur.

D'Check () bool Method generéiert e Block Hash a vergläicht et mat deem, deen am Block Hash Feld spezifizéiert ass.

D'GetTxsHash () String Method gëtt den Total Hash vun all Transaktiounen am Block zréck.

D'GetMerkleRoot () Method spezifizéiert d'Wurzel vum Merkle Bam fir Transaktiounen an engem Block.

D'Sign(privk string) Method ënnerschreift e Block mam private Schlëssel vum Block Creator.

D'SetHeight(height int) Method schreift d'Héicht vum Block an d'Blockstrukturfeld.

D'GetHeight() int Method gëtt d'Héicht vum Block zréck wéi am entspriechende Feld vun der Blockstruktur spezifizéiert.

D'ToGOBBytes () [] Byte Method codéiert e Block am GOB Format a gitt et als Byte Slice zréck.

D'FromGOBBytes (Daten [] Byte) Feeler Method schreift Blockdaten an d'Blockstruktur vun der passéierter Byte Slice am GOB Format.

D'GetHash () String Method gëtt den Hash vum gegebene Block zréck.

D'GetPrevHash () String Method gëtt den Hash vum fréiere Block zréck.

D'SetPublicKey (pubk String) Method schreift den ëffentleche Schlëssel vum Block Creator an de Block.

Also, andeems Dir d'Methoden vum Blockobjekt benotzt, kënne mir et einfach an e Format konvertéieren fir iwwer d'Netz iwwerdroen an an d'LevelDB Datebank ze späicheren.

D'Funktioune vum Blockchain Package si verantwortlech fir op de Blockchain ze spueren: github.com/Rusldv/bcstartup/tree/master/blockchain

Fir dëst ze maachen, muss de Block d'IBlock Interface implementéieren:

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

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

}

D'Datebankverbindung gëtt eemol erstallt wann de Package an der init () Funktioun initialiséiert gëtt:

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

CloseDB () ass e Wrapper fir db.Cloce () - genannt nodeems Dir mat de Packagefunktiounen geschafft hutt fir d'Verbindung mat der Datebank zouzemaachen.

D'SetTargetBlockHash (Hash String) Fehlerfunktioun schreift den Hash vum aktuelle Block mat dem Schlëssel, deen vun der BLOCK_HASH Konstant spezifizéiert ass, an d'Datebank.

D'Funktioun GetTargetBlockHash() (String, Feeler) gëtt den Hash vum aktuelle Block an der Datebank gespäichert.

D'SetTargetBlockHeight (Héicht int) Fehlerfunktioun schreift an d'Datebank de Wäert vun der Blockchain Héicht fir den Node mam Schlëssel spezifizéiert vun der BLOCK_HEIGHT Konstante.

D'Funktioun GetTargetBlockHeight () (int, Feeler) gëtt d'Héicht vun der Blockchain fir e bestëmmten Node zréck, an der Datebank gespäichert.

D'CheckBlock (Block IBlock) bool Funktioun iwwerpréift e Block fir Richtegkeet ier Dir dëse Block an d'Blockchain bäidréit.

D'AdBlock (Block IBlock) Fehlerfunktioun füügt e Block un d'Blockchain.

D'Funktioune fir d'Blocke zréckzekommen an ze kucken sinn an der explore.go Datei vum Blockchain Package:

D'Funktion GetBlockByHash (Hash string) (*block.Block, Feeler) erstellt en eidele Blockobjekt, lued e Block an et aus der Datebank, den Hash vun deem un et weidergeleet gouf, a bréngt e Pointer drop zréck.

D'Schafung vun engem Genesisblock gëtt duerch d'Genesis () Feelerfunktioun aus der Genesis.go Datei vum Blockchain Package duerchgefouert.

Den nächsten Artikel schwätzt iwwer d'Verbindung vu Clienten mat engem Node mam WebSocket Mechanismus.

Source: will.com

Setzt e Commentaire