Wie ich Blöcke und Transaktionen in meiner Go-Blockchain entworfen habe

Um letztendlich eine Blockchain und nicht nur eine Datenbank zu erstellen, müssen wir unserem Projekt drei wichtige Elemente hinzufügen:

  • Beschreibung der Datenstruktur und der Blockmethoden
  • Beschreibung der Datenstruktur und der Transaktionsmethoden
  • Blockchain-Funktionen, die Blöcke in der Datenbank speichern und dort anhand ihres Hashs oder ihrer Höhe (oder etwas anderem) finden.

Bild

Dies ist der zweite Artikel über Blockchain für die Industrie, der erste hier .

Wenn Sie sich an die Fragen erinnern, die mir die Leser im vorherigen Artikel dieser Serie gestellt haben, sollten Sie Folgendes beachten: In diesem Fall wird die LevelDB-Datenbank zum Speichern von Blockchain-Daten verwendet, beeinträchtigt jedoch nicht die Verwendung anderer Daten, beispielsweise MySQL. Und jetzt werden wir die Struktur dieser Daten verstehen.

Beginnen wir mit den Transaktionen: github.com/Rusldv/bcstartup/blob/master/transaction/builder.go

Hier ist die Datenstruktur:

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 speichert den Datentyp (für Transaktion 2), den Hash dieser Transaktion, den Transaktionstyp selbst, den Zeitstempel sowie die Ein- und Ausgänge. Die TxIn-Eingaben speichern den Hash der Transaktion, auf die auf die Ausgabe verwiesen wird, die Nummer dieser Ausgabe und den Bytecode, und die TxOut-Ausgaben speichern einen bestimmten Wert und auch den Bytecode.

Nun wollen wir sehen, welche Aktionen eine Transaktion für ihre Daten ausführen kann, d. H. Lassen Sie uns die Methoden analysieren.

Verwenden Sie zum Erstellen einer Transaktion die Funktion transaction.NewTransaction (txtype byte) * TX.

Die AddTxIn-Methode (thattxhash [] Byte, txoutn int, Code [] Byte) (* TxIn, Fehler) fügt die Eingabe zur Transaktion hinzu.

Die Methode AddTxOut (Wert int, Daten [] Byte) (* TxOut, Fehler) fügt der Transaktion eine Ausgabe hinzu.

Die Byte-Methode ToBytes () [] verwandelt eine Transaktion in einen Byte-Slice.

Die Zeichenfolge für die interne Funktion preByteHash (bytes [] byte) wird in Build () und Check () verwendet, um die Kompatibilität des erstellten Transaktions-Hash mit Transaktions-Hashes zu gewährleisten, die aus JavaScript-Anwendungen generiert wurden.

Die Build () -Methode legt den Transaktions-Hash wie folgt fest: tx.TxHash = preByteHash (tx.ToBytes ()).

Die ToJSON () -Methode einer Zeichenfolge konvertiert eine Transaktion in eine JSON-Zeichenfolge.

Die FromJSON-Fehlermethode (data [] byte) lädt eine Transaktion aus dem als Byte-Slice übertragenen JSON-Format.

Die Check () - Bool-Methode vergleicht den empfangenen Hash aus dem Hash-Feld der Transaktion mit dem Hash, der durch das Hashing dieser Transaktion erhalten wurde (mit Ausnahme des Hash-Felds).

Transaktionen werden dem Block hinzugefügt: github.com/Rusldv/bcstartup/blob/master/block/builder.go

Die Datenstruktur des Blocks ist umfangreicher:

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 speichert einen Datentyp, einen Knoten darauf, und trennt den Block von einer Transaktion oder anderen Daten. Für einen Block ist dieser Wert 1.

BlockHeight speichert die Höhe des Blocks.
Zeitstempel Zeitstempel.
HeaderSize-Blockgröße in Bytes.
PrevBlockHash-Hash des vorherigen Blocks und SelfBlockHash - der aktuelle.
TxsHash ist ein gängiger Transaktions-Hash.
MerkleRoot - Die Wurzel des Merkle-Baums.

Als nächstes wird in den Feldern der öffentliche Schlüssel des Erstellers des Blocks, die Signatur des Erstellers, die Version des Blocks, die Anzahl der Transaktionen im Block und diese Transaktionen selbst angezeigt.

Betrachten Sie seine Methoden:
Mit der Funktion block.NewBlock () wird ein Block erstellt: NewBlock (prevBlockHash-Zeichenfolge, height int) * Block, der den Hash des vorherigen Blocks und die für den erstellten Block in der Blockchain festgelegte Höhe verwendet. Der Blocktyp aus der Konstante des Typenpakets wird ebenfalls festgelegt:
b.DataType = types.BLOCK_TYPE.


Die AddTx-Methode (tx * transaction.TX) fügt dem Block eine Transaktion hinzu.

Die Build () -Methode lädt die Werte in die Felder des Blocks und generiert und setzt seinen aktuellen Hash.

Die Byte-Methode ToBytesHeader () [] übersetzt den Blockheader (ohne Transaktionen) in ein Byte-Slice.

Die ToJSON () -Methode der Zeichenfolge übersetzt den Block in der Zeichenfolgendarstellung der Daten in das JSON-Format.

Die FromJSON-Fehlermethode (data [] byte) lädt Daten aus JSON in die Blockstruktur.

Die Check () - Bool-Methode generiert einen Block-Hash und vergleicht ihn mit dem im Block-Hash-Feld angegebenen.

Die String-Methode GetTxsHash () gibt den gemeinsamen Hash aller Transaktionen im Block zurück.

Die GetMerkleRoot () -Methode legt die Wurzel des Merkle-Baums für Transaktionen im Block fest.

Die Sign-Methode (privk string) signiert den Block mit dem privaten Schlüssel des Blockerstellers.

Die SetHeight-Methode (height int) schreibt die Blockhöhe in das Blockstrukturfeld.

Die Methode GetHeight () int gibt die Höhe des Blocks zurück, wie im entsprechenden Feld der Blockstruktur angegeben.

Die Byte-Methode ToGOBBytes () [] codiert den Block im GOB-Format und gibt ihn als Byte-Slice zurück.

Die FromGOBBytes (data [] byte) -Fehlermethode schreibt Blockdaten aus dem übertragenen Byte-Slice im GOB-Format in die Blockstruktur.

Die GetHash () -Methodenzeichenfolge gibt den Hash dieses Blocks zurück.

Die GetPrevHash () -Methodenzeichenfolge gibt den Hash des vorherigen Blocks zurück.

Die SetPublicKey-Methode (pubk string) schreibt den öffentlichen Schlüssel des Blockerstellers in den Block.

Mit den Methoden des Block-Objekts können wir es daher problemlos in ein Format für die Übertragung über das Netzwerk konvertieren und in der LevelDB-Datenbank speichern.

Die Blockchain-Paketfunktionen sind für das Speichern in der Blockchain verantwortlich: github.com/Rusldv/bcstartup/tree/master/blockchain.

Dazu muss der Block die IBlock-Schnittstelle implementieren:

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

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

}

Während der Initialisierung des Pakets in der Funktion init () wird einmal eine Datenbankverbindung erstellt:
db, err = leveldb.OpenFile(BLOCKCHAIN_DB_DEBUG, nil).

CloseDB () ist ein Wrapper für db.Cloce () - wird aufgerufen, nachdem mit den Paketfunktionen gearbeitet wurde, um die Datenbankverbindung zu schließen.

Die Fehlerfunktion SetTargetBlockHash (Hash-String) schreibt den Hash des aktuellen Blocks mit dem Schlüssel, der durch die Konstante BLOCK_HASH in der Datenbank angegeben wird.

Die Funktion GetTargetBlockHash () (Zeichenfolge, Fehler) gibt den Hash des aktuellen Blocks zurück, der in der Datenbank gespeichert ist.

Die Fehlerfunktion SetTargetBlockHeight (height int) schreibt den Wert der Blockchain-Höhe für einen Knoten mit dem durch die BLOCK_HEIGHT-Konstante angegebenen Schlüssel in die Datenbank.

Die Funktion GetTargetBlockHeight () (int, error) gibt die Blockchain-Höhe für einen bestimmten in der Datenbank gespeicherten Knoten zurück.

Die CheckBlock-Bool-Funktion (Block IBlock) überprüft den Block auf Richtigkeit, bevor dieser Block zur Blockchain hinzugefügt wird.

Die AddBlock-Fehlerfunktion (Block IBlock) fügt der Blockchain einen Block hinzu.

Die Funktionen zum Empfangen und Anzeigen von Blöcken befinden sich in der Datei Explore.go des Blockchain-Pakets:

Die Funktion GetBlockByHash (Hash-String) (* block.Block, Fehler) erstellt ein leeres Blockobjekt, lädt einen Block aus der Datenbank, dessen Hash an ihn übergeben wird, und gibt einen Zeiger darauf zurück.

Der Genesis-Block wird von der Genesis () -Fehlerfunktion aus der Datei genesis.go des Blockchain-Pakets erstellt.

Im nächsten Artikel werden wir uns mit dem Herstellen einer Verbindung zu einem Clientknoten mithilfe des WebSocket-Mechanismus befassen.

All Articles