For i sidste ende at ende med en blockchain og ikke bare en database, skal vi tilføje 3 vigtige elementer til vores projekt:
- Beskrivelse af blokdatastrukturen og metoder
- Beskrivelse af datastruktur og transaktionsmetoder
- Blockchain-funktioner, der gemmer blokke i en database og finder dem der ved deres hash eller højde (eller noget andet).
Dette er den anden artikel om blockchain til industrien, den første
Når man husker de spørgsmål, som læserne stillede mig om den forrige artikel i denne serie, skal det bemærkes: i dette tilfælde bruges LevelDB-databasen til at gemme blockchain-data, men intet forhindrer dig i at bruge andre, f.eks. MySQL. Lad os nu se på strukturen af disse data.
Lad os starte med transaktioner:
Her er dens datastruktur:
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 gemmer datatypen (for transaktion 2), hashen for den pågældende transaktion, typen af selve transaktionen, et tidsstempel og input og output. TxIn-input gemmer hashen for transaktionen, hvis output refereres til, antallet af denne output og bytekode, og TxOut-output gemmer en vis værdi og også bytekode.
Lad os nu se, hvilke handlinger en transaktion kan udføre på sine data, dvs. Lad os se på metoderne.
For at oprette en transaktion skal du bruge funktionen transaktion.NewTransaction(TXtype byte) *TX.
Metoden AddTxIn(thattxhash []byte, txoutn int, kode []byte) (*TxIn, fejl) tilføjer et input til transaktionen.
Metoden AddTxOut(værdi int, data []byte) (*TxOut, fejl) tilføjer et output til transaktionen.
ToBytes() []byte-metoden gør transaktionen til en byte-slice.
Den interne funktion preByteHash(bytes []byte) streng bruges i Build() og Check() for at gøre den genererede transaktions-hash kompatibel med transaktions-hash genereret fra JavaScript-applikationer.
Build()-metoden indstiller transaktionens hash som følger: tx.TxHash = preByteHash(tx.ToBytes()).
ToJSON()-strengmetoden konverterer en transaktion til en JSON-streng.
FromJSON(data []byte)-fejlmetoden indlæser en transaktion fra JSON-formatet, der sendes som et byteudsnit.
Check() bool-metoden sammenligner den resulterende hash fra transaktions-hash-feltet med den hash, der er opnået som et resultat af hash af denne transaktion (ignorerer hash-feltet).
Transaktioner tilføjes til blokken:
Blokdatastrukturen er mere omfangsrig:
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 gemmer datatypen, noden bruger den og adskiller blokken fra en transaktion eller andre data. For en blok er denne værdi 1.
BlockHeight gemmer blokkens højde.
Tidsstempel tidsstempel.
HeaderSize er blokstørrelsen i bytes.
PrevBlockHash er hashen af den forrige blok, og SelfBlockHash er hashen af den nuværende.
TxsHash er en generel hash af transaktioner.
MerkleRoot er roden til Merkle-træet.
Længere i felterne er der den offentlige nøgle for skaberen af blokken, underskriften af skaberen, versionen af blokken, antallet af transaktioner i blokken og disse transaktioner selv.
Lad os se på dens metoder:
For at oprette en blok skal du bruge block.NewBlock()-funktionen: NewBlock(prevBlockHash-streng, højde int) *Blok, som tager hashen fra den forrige blok og højden indstillet for den oprettede blok i blokkæden. Bloktypen indstilles også fra typepakkekonstanten:
b.DataType = types.BLOCK_TYPE.
Metoden AddTx(tx *transaction.TX) tilføjer en transaktion til en blok.
Build()-metoden indlæser værdier i blokkens felter og genererer og indstiller dens aktuelle hash.
ToBytesHeader() []byte-metoden konverterer blokhovedet (uden transaktioner) til et byteudsnit.
ToJSON()-strengmetoden konverterer blokken til JSON-format i en strengrepræsentation af dataene.
FromJSON(data []byte) fejlmetoden indlæser data fra JSON til en blokstruktur.
Check() bool-metoden genererer en blokhash og sammenligner den med den, der er angivet i blokhashfeltet.
Strengmetoden GetTxsHash() returnerer den samlede hash for alle transaktioner i blokken.
GetMerkleRoot()-metoden angiver roden af Merkle-træet for transaktioner i en blok.
Sign(privk string) metoden signerer en blok med den private nøgle fra blokopretteren.
Metoden SetHeight(height int) skriver blokkens højde til blokstrukturfeltet.
GetHeight() int-metoden returnerer højden af blokken som angivet i det tilsvarende felt i blokstrukturen.
ToGOBBytes() []byte-metoden koder en blok i GOB-format og returnerer den som et byteudsnit.
FromGOBBytes(data []byte) fejlmetoden skriver blokdata til blokstrukturen fra det beståede byteudsnit i GOB-format.
Strengmetoden GetHash() returnerer hashen for den givne blok.
Strengmetoden GetPrevHash() returnerer hashen fra den forrige blok.
Metoden SetPublicKey(pubk string) skriver den offentlige nøgle for blokopretteren til blokken.
Ved hjælp af Block-objektets metoder kan vi således nemt konvertere det til et format til transmission over netværket og gemme til LevelDB-databasen.
Funktionerne i blockchain-pakken er ansvarlige for at gemme til blockchain:
For at gøre dette skal blokken implementere IBlock-grænsefladen:
type IGOBBytes interface {
ToGOBBytes() []byte
FromGOBBytes(data []byte) error
}
type IBlock interface {
IGOBBytes
GetHash() string
GetPrevHash() string
GetHeight() int
Check() bool
}
Databaseforbindelsen oprettes én gang, når pakken initialiseres i funktionen init():
db, err = leveldb.OpenFile(BLOCKCHAIN_DB_DEBUG, nil).
CloseDB() er en wrapper for db.Cloce() - kaldet efter at have arbejdet med pakkefunktionerne for at lukke forbindelsen til databasen.
Fejlfunktionen SetTargetBlockHash(hash-streng) skriver hashen for den aktuelle blok med nøglen angivet af BLOCK_HASH-konstanten til databasen.
Funktionen GetTargetBlockHash() (streng, fejl) returnerer hashen for den aktuelle blok, der er gemt i databasen.
Fejlfunktionen SetTargetBlockHeight(height int) skriver til databasen værdien af blockchain-højden for noden med nøglen angivet af BLOCK_HEIGHT-konstanten.
Funktionen GetTargetBlockHeight() (int, fejl) returnerer højden af blokkæden for en given node, gemt i databasen.
CheckBlock (blok IBlock) bool-funktionen kontrollerer en blok for korrekthed, før denne blok føjes til blockchain.
Fejlfunktionen AddBlock (blok IBlock) tilføjer en blok til blokkæden.
Funktionerne til at hente og se blokke er i explore.go-filen i blockchain-pakken:
Funktionen GetBlockByHash(hash-streng) (*blok.Blok, fejl) opretter et tomt blokobjekt, indlæser en blok i det fra databasen, hvis hash blev sendt til det, og returnerer en pointer til det.
Oprettelsen af en genesis-blok udføres af Genesis()-fejlfunktionen fra genesis.go-filen i blockchain-pakken.
Den næste artikel vil tale om at forbinde klienter til en node ved hjælp af WebSocket-mekanismen.
Kilde: www.habr.com