Hoe't ik blokken en transaksjes ûntwurp yn myn Go blockchain

Om úteinlik te einigjen mei in blockchain en net allinich in database, moatte wy 3 wichtige eleminten tafoegje oan ús projekt:

  • Beskriuwing fan 'e blokgegevensstruktuer en metoaden
  • Beskriuwing fan gegevensstruktuer en transaksjemetoaden
  • Blockchain-funksjes dy't blokken opslaan yn in databank en fine se dêr troch har hash of hichte (of wat oars).

Hoe't ik blokken en transaksjes ûntwurp yn myn Go blockchain

Dit is it twadde artikel oer blockchain foar yndustry, it earste hjir.

Unthâld fan 'e fragen dy't lêzers my fregen oer it foarige artikel yn dizze searje, moat opmurken wurde: yn dit gefal wurdt de LevelDB-database brûkt om blockchain-gegevens op te slaan, mar neat foarkomt jo fan in oare, bygelyks, MySQL. Litte wy no sjen nei de struktuer fan dizze gegevens.

Litte wy begjinne mei transaksjes: github.com/Rusldv/bcstartup/blob/master/transaction/builder.go

Hjir is syn gegevensstruktuer:

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 bewarret it gegevenstype (foar transaksje 2), de hash fan dy transaksje, it type fan 'e transaksje sels, in tiidstempel, en yn- en útgongen. TxIn-ynputen bewarje de hash fan 'e transaksje wêrfan de útfier wurdt ferwiisd, it oantal fan dizze útfier en bytekoade, en TxOut-útgongen bewarje wat wearde en ek bytekoade.

Litte wy no sjen hokker aksjes in transaksje kin útfiere op syn gegevens, d.w.s. Litte wy nei de metoaden sjen.

Om in transaksje te meitsjen, brûk de transaksje.NewTransaction(TXtype byte) *TX-funksje.

De metoade AddTxIn(thattxhash []byte, txoutn int, koade []byte) (*TxIn, flater) foeget in ynfier ta oan de transaksje.

De AddTxOut (wearde int, data [] byte) (*TxOut, flater) metoade foeget in útfier ta oan de transaksje.

De metoade ToBytes() []byte feroaret de transaksje yn in byte-slice.

De ynterne funksje preByteHash(bytes []byte) tekenrige wurdt brûkt yn Build() en Check() om de oanmakke transaksje-hash kompatibel te meitsjen mei transaksje-hashes generearre út JavaScript-applikaasjes.

De metoade Build() stelt de transaksjehash as folget yn: tx.TxHash = preByteHash(tx.ToBytes()).

De ToJSON () string metoade konvertearret in transaksje yn in JSON string.

De FromJSON(data []byte)-flatermetoade laadt in transaksje út it JSON-formaat trochjûn as in byte-slice.

De Check () bool metoade fergeliket de resultearjende hash út it transaksje hash fjild mei de hash krigen as gefolch fan hash dizze transaksje (negearje it hash fjild).

Transaksjes wurde tafoege oan it blok: github.com/Rusldv/bcstartup/blob/master/block/builder.go

De blokgegevensstruktuer is volumineuzer:

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 bewarret it gegevenstype, it knooppunt brûkt it en ûnderskiedt it blok fan in transaksje of oare gegevens. Foar in blok is dizze wearde 1.

BlockHeight bewarret de hichte fan it blok.
Tiidstempel tiidstempel.
HeaderSize is de blokgrutte yn bytes.
PrevBlockHash is de hash fan it foarige blok, en SelfBlockHash is de hash fan it hjoeddeiske.
TxsHash is in algemiene hash fan transaksjes.
MerkleRoot is de woartel fan 'e Merklebeam.

Fierder yn 'e fjilden is d'r de iepenbiere kaai fan' e makker fan it blok, de hantekening fan 'e skepper, de ferzje fan it blok, it oantal transaksjes yn it blok, en dizze transaksjes sels.

Litte wy nei har metoaden sjen:
Om in blok te meitsjen, brûk de funksje block.NewBlock(): NewBlock(prevBlockHash string, hichte int) *Blok, dy't de hash fan it foarige blok nimt en de hichte ynsteld foar it oanmakke blok yn 'e blockchain. It bloktype wurdt ek ynsteld fan 'e typepakketkonstante:

b.DataType = types.BLOCK_TYPE.

De metoade AddTx(tx *transaction.TX) foeget in transaksje ta oan in blok.

De metoade Build () laadt wearden yn 'e fjilden fan it blok en genereart en stelt syn hjoeddeistige hash yn.

De metoade ToBytesHeader() []byte konvertearret de blokkoptekst (sûnder transaksjes) yn in bytestik.

De ToJSON()-stringmetoade konvertearret it blok nei JSON-formaat yn in tekenrige foarstelling fan de gegevens.

De FromJSON (data [] byte) flatermetoade laadt gegevens fan JSON yn in blokstruktuer.

De Check () bool-metoade genereart in blokhash en fergeliket it mei de spesifisearre yn it blokhashfjild.

De stringmetoade GetTxsHash() jout de totale hash werom fan alle transaksjes yn it blok.

De metoade GetMerkleRoot() spesifisearret de woartel fan 'e Merkle-beam foar transaksjes yn in blok.

De metoade Sign (privk string) tekenet in blok mei de privee kaai fan 'e blokmakker.

De metoade SetHeight(height int) skriuwt de hichte fan it blok nei it blokstruktuerfjild.

De metoade GetHeight() int jout de hichte fan it blok werom lykas oantsjutte yn it oerienkommende fjild fan de blokstruktuer.

De metoade ToGOBBytes() []byte kodearret in blok yn GOB-formaat en jout it werom as in byte-slice.

De FromGOBBytes(data []byte)-flatermetoade skriuwt blokgegevens nei de blokstruktuer fanút it trochjûne bytestik yn GOB-formaat.

De stringmetoade GetHash() jout de hash fan it opjûne blok werom.

De stringmetoade GetPrevHash() jout de hash fan it foarige blok werom.

De metoade SetPublicKey(pubk string) skriuwt de iepenbiere kaai fan de blokmakker nei it blok.

Sa kinne wy ​​​​mei de metoaden fan it Block-objekt maklik omsette yn in formaat foar oerdracht oer it netwurk en opslaan yn 'e LevelDB-database.

De funksjes fan it blockchain-pakket binne ferantwurdlik foar it bewarjen nei de blockchain: github.com/Rusldv/bcstartup/tree/master/blockchain

Om dit te dwaan, moat it blok de IBlock-ynterface ymplementearje:

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

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

}

De databankferbining wurdt ien kear oanmakke as it pakket is inisjalisearre yn de funksje init():

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

CloseDB () is in wrapper foar db.Cloce () - neamd nei't wurke mei it pakket funksjes foar in slute de ferbining mei de databank.

De SetTargetBlockHash (hash string) flaterfunksje skriuwt de hash fan it aktive blok mei de kaai oantsjutte troch de BLOCK_HASH konstante nei de databank.

De funksje GetTargetBlockHash() (string, flater) jout de hash werom fan it aktive blok dat yn de databank is opslein.

De SetTargetBlockHeight (hichte int) flaterfunksje skriuwt nei de databank de wearde fan 'e blokhichte foar de knooppunt mei de kaai oantsjutte troch de BLOCK_HEIGHT konstante.

De funksje GetTargetBlockHeight () (int, flater) jout de hichte fan 'e blockchain foar in opjûne knooppunt werom, opslein yn 'e databank.

De boolfunksje CheckBlock (block IBlock) kontrolearret in blok op krektens foardat dit blok tafoege wurdt oan de blockchain.

De flaterfunksje AddBlock (block IBlock) foeget in blok ta oan 'e blockchain.

De funksjes foar it opheljen en besjen fan blokken binne yn it explore.go-bestân fan it blockchain-pakket:

De funksje GetBlockByHash(hash string) (*block.Block, flater) makket in leech blokobjekt, laadt der in blok yn út de databank, wêrfan de hash deroan trochjûn is, en jout der in oanwizer nei werom.

De skepping fan in genesisblok wurdt útfierd troch de Genesis () flaterfunksje út it genesis.go-bestân fan it blockchain-pakket.

It folgjende artikel sil prate oer it ferbinen fan kliïnten oan in knooppunt mei it WebSocket-meganisme.

Boarne: www.habr.com

Add a comment