Kif iddisinja blokki u tranżazzjonijiet fil-blockchain tiegħi Go

Sabiex fl-aħħar nispiċċaw bi blockchain u mhux biss database, irridu nżidu 3 elementi importanti mal-proġett tagħna:

  • Deskrizzjoni tal-istruttura u l-metodi tad-data tal-blokk
  • Deskrizzjoni ta 'struttura tad-data u metodi ta' transazzjoni
  • Funzjonijiet ta 'Blockchain li jiffrankaw blokki f'database u jsibuhom hemm mill-hash jew l-għoli tagħhom (jew xi ħaġa oħra).

Kif iddisinja blokki u tranżazzjonijiet fil-blockchain tiegħi Go

Dan huwa t-tieni artiklu dwar blockchain għall-industrija, l-ewwel hawn.

Waqt li niftakru l-mistoqsijiet li l-qarrejja staqsewni dwar l-artikolu preċedenti f'din is-serje, għandu jiġi nnutat: f'dan il-każ, id-database LevelDB tintuża biex taħżen dejta tal-blockchain, iżda xejn ma jipprevjenik milli tuża kwalunkwe MySQL ieħor, ngħidu aħna. Issa ejja nħarsu lejn l-istruttura ta 'din id-data.

Nibdew bit-tranżazzjonijiet: github.com/Rusldv/bcstartup/blob/master/transaction/builder.go

Hawnhekk hawn l-istruttura tad-dejta tagħha:

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 jaħżen it-tip tad-dejta (għat-tranżazzjoni 2), il-hash ta 'dik it-tranżazzjoni, it-tip tat-tranżazzjoni nnifisha, timestamp, u inputs u outputs. L-inputs TxIn jaħżnu l-hash tat-tranżazzjoni li l-output tagħha huwa referenzjat, in-numru ta 'dan l-output u bytecode, u l-outputs TxOut jaħżnu xi valur u wkoll bytecode.

Issa ejja naraw x'azzjonijiet tista' twettaq transazzjoni fuq id-dejta tagħha, i.e. Ejja nħarsu lejn il-metodi.

Biex toħloq transazzjoni, uża l-funzjoni transazzjoni.NewTransaction(txtype byte) *TX.

Il-metodu AddTxIn(thattxhash []byte, txoutn int, code []byte) (*TxIn, żball) iżid input għat-tranżazzjoni.

Il-metodu AddTxOut(value int, data []byte) (*TxOut, żball) iżid output mat-tranżazzjoni.

Il-metodu ToBytes() []byte jibdel it-tranżazzjoni f'slice byte.

Is-sekwenza tal-funzjoni interna preByteHash(bytes []byte) tintuża f'Build() u Check() biex tagħmel il-hash tat-tranżazzjoni ġġenerat kompatibbli mal-hashes tat-tranżazzjonijiet iġġenerati minn applikazzjonijiet JavaScript.

Il-metodu Build() jistabbilixxi l-hash tat-tranżazzjoni kif ġej: tx.TxHash = preByteHash(tx.ToBytes()).

Il-metodu string ToJSON() jikkonverti tranżazzjoni fi string JSON.

Il-metodu ta' żball FromJSON(data []byte) jgħabbi tranżazzjoni mill-format JSON mgħoddi bħala slice byte.

Il-metodu Check() bool iqabbel il-hash li jirriżulta mill-qasam tal-hash tat-tranżazzjoni mal-hash miksub bħala riżultat tal-hash ta' din it-tranżazzjoni (jinjora l-qasam tal-hash).

It-tranżazzjonijiet huma miżjuda mal-blokk: github.com/Rusldv/bcstartup/blob/master/block/builder.go

L-istruttura tad-dejta tal-blokk hija aktar voluminuża:

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 jaħżen it-tip tad-dejta, in-nodu jużaha u jiddistingwi l-blokk minn tranżazzjoni jew data oħra. Għal blokk dan il-valur huwa 1.

BlockHeight jaħżen l-għoli tal-blokk.
Timestamp timestamp.
HeaderSize huwa d-daqs tal-blokk f'bytes.
PrevBlockHash huwa l-hash tal-blokk ta 'qabel, u SelfBlockHash huwa l-hash ta' dak attwali.
TxsHash huwa hash ġenerali ta 'tranżazzjonijiet.
MerkleRoot huwa l-għerq tas-siġra Merkle.

Aktar fl-oqsma hemm iċ-ċavetta pubblika tal-kreatur tal-blokk, il-firma tal-kreatur, il-verżjoni tal-blokk, in-numru ta 'tranżazzjonijiet fil-blokk, u dawn it-tranżazzjonijiet infushom.

Ejja nħarsu lejn il-metodi tiegħu:
Biex toħloq blokk, uża l-funzjoni block.NewBlock(): NewBlock(prevBlockHash string, height int) *Block, li jieħu l-hash tal-blokk preċedenti u l-għoli stabbilit għall-blokk maħluqa fil-blockchain. It-tip ta 'blokk huwa stabbilit ukoll mill-kostanti tal-pakkett tat-tipi:

b.DataType = types.BLOCK_TYPE.

Il-metodu AddTx(tx *transaction.TX) iżid transazzjoni ma' blokka.

Il-metodu Build() jgħabbi l-valuri fl-oqsma tal-blokk u jiġġenera u jistabbilixxi l-hash attwali tiegħu.

Il-metodu ToBytesHeader() []byte jikkonverti l-header tal-blokk (mingħajr tranżazzjonijiet) fi slice byte.

Il-metodu string ToJSON() jikkonverti l-blokk f'format JSON f'rappreżentazzjoni string tad-dejta.

Il-metodu ta' żball FromJSON(data []byte) jgħabbi dejta minn JSON fi struttura ta' blokki.

Il-metodu Check() bool jiġġenera block hash u jqabbilha ma' dak speċifikat fil-qasam block hash.

Il-metodu string GetTxsHash() jirritorna l-hash totali tat-tranżazzjonijiet kollha fil-blokk.

Il-metodu GetMerkleRoot() jispeċifika l-għerq tas-siġra Merkle għal tranżazzjonijiet fi blokka.

Il-metodu Sign(privk string) jiffirma blokka biċ-ċavetta privata tal-kreatur tal-blokk.

Il-metodu SetHeight(height int) jikteb l-għoli tal-blokk fil-qasam tal-istruttura tal-blokk.

Il-metodu GetHeight() int jirritorna l-għoli tal-blokk kif speċifikat fil-qasam korrispondenti tal-istruttura tal-blokk.

Il-metodu ToGOBBytes() []byte jikkodifika blokka fil-format GOB u jirritornaha bħala slice byte.

Il-metodu ta 'żball FromGOBBytes(data []byte) jikteb dejta tal-blokk fl-istruttura tal-blokk mill-porzjon tal-byte mgħoddi f'format GOB.

Il-metodu string GetHash() jirritorna l-hash tal-blokk mogħti.

Il-metodu string GetPrevHash() jirritorna l-hash tal-blokk preċedenti.

Il-metodu SetPublicKey(string pubk) jikteb iċ-ċavetta pubblika tal-kreatur tal-blokk fil-blokk.

Għalhekk, bl-użu tal-metodi tal-oġġett Blokk, nistgħu faċilment jaqilbuh f'format għat-trażmissjoni fuq in-netwerk u l-iffrankar fid-database LevelDB.

Il-funzjonijiet tal-pakkett blockchain huma responsabbli għall-iffrankar fil-blockchain: github.com/Rusldv/bcstartup/tree/master/blockchain

Biex tagħmel dan, il-blokk għandu jimplimenta l-interface IBlock:

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

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

}

Il-konnessjoni tad-database tinħoloq darba meta l-pakkett jiġi inizjalizzat fil-funzjoni init():

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

CloseDB() huwa wrapper għal db.Cloce() - imsejjaħ wara li taħdem mal-funzjonijiet tal-pakkett biex tagħlaq il-konnessjoni mad-database.

Il-funzjoni ta 'żball SetTargetBlockHash(hash string) tikteb il-hash tal-blokk kurrenti biċ-ċavetta speċifikata mill-kostanti BLOCK_HASH fid-database.

Il-funzjoni GetTargetBlockHash() (string, żball) tirritorna l-hash tal-blokk attwali maħżun fid-database.

Il-funzjoni ta 'żball SetTargetBlockHeight(height int) tikteb fid-database il-valur tal-għoli tal-blockchain għan-nodu biċ-ċavetta speċifikata mill-kostanti BLOCK_HEIGHT.

Il-funzjoni GetTargetBlockHeight() (int, żball) tirritorna l-għoli tal-blockchain għal nodu partikolari, maħżun fid-database.

Il-funzjoni bool CheckBlock(block IBlock) tiċċekkja blokka għall-korrettezza qabel ma żżid dan il-blokk mal-blockchain.

Il-funzjoni ta 'żball AddBlock(block IBlock) żżid blokka mal-blockchain.

Il-funzjonijiet għall-irkupru u l-wiri tal-blokki jinsabu fil-fajl explore.go tal-pakkett blockchain:

Il-funzjoni GetBlockByHash(hash string) (*block.Block, error) toħloq oġġett ta 'blokk vojt, tagħbija blokka fiha mid-database, li l-hash tagħha ġie mgħoddi lilha, u tirritorna pointer għalih.

Il-ħolqien ta 'blokk tal-ġenesi jitwettaq mill-funzjoni ta' żball Genesis() mill-fajl genesis.go tal-pakkett blockchain.

L-artiklu li jmiss se jitkellem dwar il-konnessjoni tal-klijenti ma 'node bl-użu tal-mekkaniżmu WebSocket.

Sors: www.habr.com

Żid kumment