Hogyan terveztem blokkokat és tranzakciókat a Go blokkláncomban

Annak érdekében, hogy végül egy blokkláncot kapjunk, és ne csak egy adatbázist, 3 fontos elemet kell hozzáadnunk projektünkhöz:

  • A blokk adatszerkezetének és metódusainak leírása
  • Az adatstruktúra és a tranzakciós módszerek ismertetése
  • Blokklánc-függvények, amelyek a blokkokat adatbázisba mentik, és ott megtalálják azokat a hash vagy a magasság (vagy valami más) alapján.

Hogyan terveztem blokkokat és tranzakciókat a Go blokkláncomban

Ez a második cikk a blokkláncról az ipar számára, az első itt.

Emlékezve azokra a kérdésekre, amelyeket a sorozat előző cikkével kapcsolatban tettek fel nekem az olvasók, meg kell jegyezni: ebben az esetben a LevelDB adatbázist használják a blokklánc adatok tárolására, de semmi sem akadályozza meg, hogy más, mondjuk a MySQL-t használjon. Most nézzük meg ezen adatok szerkezetét.

Kezdjük a tranzakciókkal: github.com/Rusldv/bcstartup/blob/master/transaction/builder.go

Íme az adatszerkezete:

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
}

A TX tárolja az adattípust (a 2. tranzakcióhoz), a tranzakció hash-jét, magának a tranzakciónak a típusát, egy időbélyeget, valamint a bemeneteket és kimeneteket. A TxIn bemenetek tárolják annak a tranzakciónak a hashét, amelynek kimenetére hivatkoznak, ennek a kimenetnek a számát és a bájtkódot, a TxOut kimenetek pedig valamilyen értéket és bájtkódot is tárolnak.

Most nézzük meg, hogy egy tranzakció milyen műveleteket hajthat végre az adatain, pl. Nézzük a módszereket.

Tranzakció létrehozásához használja a tranzakció.NewTransaction(txtype byte) *TX függvényt.

Az AddTxIn(thattxhash []byte, txoutn int, code []byte) (*TxIn, error) metódus bemenetet ad a tranzakcióhoz.

Az AddTxOut(érték int, adat []byte) (*TxOut, hiba) metódus kimenetet ad a tranzakcióhoz.

A ToBytes() []byte metódus a tranzakciót bájtszeletté alakítja.

A preByteHash(bytes []byte) karakterlánc a Build() és Check() függvényben használatos annak érdekében, hogy a generált tranzakciós hash kompatibilis legyen a JavaScript-alkalmazásokból generált tranzakciós hashekkel.

A Build() metódus a következőképpen állítja be a tranzakció kivonatát: tx.TxHash = preByteHash(tx.ToBytes()).

A ToJSON() karakterlánc metódus a tranzakciót JSON-karakterláncsá alakítja.

A FromJSON(data []byte) hibametódus a bájtszeletként átadott JSON-formátumból tölti be a tranzakciót.

A Check() bool metódus összehasonlítja a tranzakció hash mezőjének eredményül kapott kivonatát a tranzakció kivonatolása (a hash mező figyelmen kívül hagyása) eredményeként kapott hash-sel.

A tranzakciók hozzáadódnak a blokkhoz: github.com/Rusldv/bcstartup/blob/master/block/builder.go

A blokk adatstruktúra terjedelmesebb:

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
}

A DataType tárolja az adattípust, a csomópont használja, és megkülönbözteti a blokkot a tranzakciótól vagy egyéb adatoktól. Egy blokknál ez az érték 1.

A BlockHeight tárolja a blokk magasságát.
Időbélyeg időbélyeg.
A HeaderSize a blokk mérete bájtokban.
A PrevBlockHash az előző blokk hash-e, a SelfBlockHash pedig az aktuális blokk hash-je.
A TxsHash a tranzakciók általános kivonata.
A MerkleRoot a Merkle fa gyökere.

Továbbá a mezőkben található a blokk létrehozójának nyilvános kulcsa, a létrehozó aláírása, a blokk verziója, a blokkban lévő tranzakciók száma, és maguk ezek a tranzakciók.

Nézzük a módszereit:
Blokk létrehozásához használja a blokk.NewBlock() függvényt: NewBlock(prevBlockHash string, height int) *Block, amely az előző blokk hash-ét és a létrehozott blokkhoz beállított magasságot veszi fel a blokkláncban. A blokk típusa szintén a Types csomagkonstansból állítható be:

b.DataType = types.BLOCK_TYPE.

Az AddTx(tx *tranzakció.TX) metódus hozzáad egy tranzakciót egy blokkhoz.

A Build() metódus értékeket tölt be a blokk mezőibe, és létrehozza és beállítja az aktuális hash-t.

A ToBytesHeader() []byte metódus a blokkfejlécet (tranzakciók nélkül) bájtszeletté alakítja.

A ToJSON() karakterlánc metódus a blokkot JSON-formátumba konvertálja az adatok karakterlánc-megjelenítésében.

A FromJSON(data []byte) hibametódus adatokat tölt be a JSON-ból egy blokkstruktúrába.

A Check() bool metódus blokkkivonatot generál, és összehasonlítja azt a blokk hash mezőben megadottal.

A GetTxsHash() karakterlánc metódus a blokkban lévő összes tranzakció teljes kivonatát adja vissza.

A GetMerkleRoot() metódus megadja a Merkle-fa gyökerét a blokkban lévő tranzakciókhoz.

A Sign(privk string) metódus aláír egy blokkot a blokk létrehozójának privát kulcsával.

A SetHeight(height int) metódus a blokk magasságát írja a blokkstruktúra mezőbe.

A GetHeight() int metódus a blokk magasságát adja vissza a blokkstruktúra megfelelő mezőjében megadottak szerint.

A ToGOBBytes() []byte metódus GOB formátumban kódol egy blokkot, és bájtszeletként adja vissza.

A FromGOBBytes(data []byte) hibametódus blokkadatokat ír a blokkstruktúrába az átadott bájtszeletből GOB formátumban.

A GetHash() string metódus az adott blokk hash-jét adja vissza.

A GetPrevHash() karakterlánc metódus az előző blokk hash-jét adja vissza.

A SetPublicKey(pubk string) metódus a blokk létrehozójának nyilvános kulcsát írja a blokkba.

Így a Block objektum metódusait használva könnyedén konvertálhatjuk formátumba a hálózaton keresztüli továbbításhoz és a LevelDB adatbázisba való mentéshez.

A blokklánc csomag funkciói felelősek a blokkláncba való mentésért: github.com/Rusldv/bcstartup/tree/master/blockchain

Ehhez a blokknak meg kell valósítania az IBlock interfészt:

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

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

}

Az adatbázis-kapcsolat egyszer jön létre, amikor a csomagot inicializálják az init() függvényben:

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

A CloseDB() a db.Cloce() burkolója – a csomagfüggvényekkel végzett munka után hívják meg, hogy lezárják az adatbázishoz való kapcsolatot.

A SetTargetBlockHash(hash string) hibafüggvény az aktuális blokk kivonatát a BLOCK_HASH konstans által megadott kulccsal írja az adatbázisba.

A GetTargetBlockHash() (karakterlánc, hiba) függvény az adatbázisban tárolt aktuális blokk kivonatát adja vissza.

A SetTargetBlockHeight(height int) hibafüggvény a BLOCK_HEIGHT konstans által megadott kulccsal a csomópont blokklánc-magasságának értékét írja az adatbázisba.

A GetTargetBlockHeight() (int, error) függvény egy adott csomópont blokkláncának magasságát adja vissza, az adatbázisban tárolva.

A CheckBlock(block IBlock) bool függvény ellenőrzi a blokk helyességét, mielőtt hozzáadná a blokklánchoz.

Az AddBlock(block IBlock) hibafüggvény egy blokkot ad hozzá a blokklánchoz.

A blokkok lekérésére és megtekintésére szolgáló funkciók a blockchain csomag explore.go fájljában találhatók:

A GetBlockByHash(hash string) (*block.Block, error) függvény egy üres blokk objektumot hoz létre, az adatbázisból betölt egy blokkot, aminek a hash-ét átadtuk neki, és visszaad egy pointert.

A genesis blokk létrehozását a Genesis() hibafüggvény végzi a blokklánc csomag genesis.go fájljából.

A következő cikk az ügyfelek csomóponthoz történő csatlakoztatásáról lesz szó a WebSocket mechanizmus segítségével.

Forrás: will.com

Hozzászólás