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.
Ez a második cikk a blokkláncról az ipar számára, az első
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:
Í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:
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:
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