Sut wnes i ddylunio blociau a thrafodion yn fy blockchain Go

Er mwyn cael blockchain yn y pen draw ac nid cronfa ddata yn unig, mae angen i ni ychwanegu 3 elfen bwysig at ein prosiect:

  • Disgrifiad o'r strwythur data bloc a'r dulliau
  • Disgrifiad o strwythur data a dulliau trafod
  • Swyddogaethau Blockchain sy'n arbed blociau mewn cronfa ddata a dod o hyd iddynt yno yn Γ΄l eu hash neu uchder (neu rywbeth arall).

Sut wnes i ddylunio blociau a thrafodion yn fy blockchain Go

Dyma'r ail erthygl am blockchain ar gyfer diwydiant, y gyntaf yma.

Gan gofio'r cwestiynau y gofynnodd darllenwyr i mi am yr erthygl flaenorol yn y gyfres hon, dylid nodi: yn yr achos hwn, defnyddir cronfa ddata LevelDB i storio data blockchain, ond nid oes dim yn eich atal rhag defnyddio unrhyw un arall, dyweder, MySQL. Nawr, gadewch i ni edrych ar strwythur y data hwn.

Gadewch i ni ddechrau gyda thrafodion: github.com/Rusldv/bcstartup/blob/master/transaction/builder.go

Dyma ei strwythur data:

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
}

Mae TX yn storio'r math o ddata (ar gyfer trafodiad 2), hash y trafodiad hwnnw, y math o drafodiad ei hun, stamp amser, a mewnbynnau ac allbynnau. Mae mewnbynnau TxIn yn storio hash y trafodiad y cyfeirir at ei allbwn, nifer yr allbwn hwn a'r cod byte, ac mae allbynnau TxOut yn storio rhywfaint o werth a hefyd cod byte.

Nawr, gadewch i ni weld pa gamau y gall trafodiad eu cyflawni ar ei ddata, h.y. Gadewch i ni edrych ar y dulliau.

I greu trafodiad, defnyddiwch y swyddogaeth trafodiad.NewTransaction(txtype byte) *TX.

Mae'r dull AddTxIn (thattxhash [] beit, txoutn int, cod [] beit) (* TxIn, gwall) yn ychwanegu mewnbwn i'r trafodiad.

Mae'r dull AddTxOut (gwerth int, data [] beit) (* TxOut, gwall) yn ychwanegu allbwn i'r trafodiad.

Mae'r dull ToBytes() []beit yn troi'r trafodiad yn sleisen beit.

Defnyddir y llinyn swyddogaeth fewnol preByteHash (beit [] beit) yn Build() a Check() i wneud y stwnsh trafodiad a gynhyrchir yn gydnaws Γ’ hashes trafodion a gynhyrchir o gymwysiadau JavaScript.

Mae'r dull Build() yn gosod yr hash trafodiad fel a ganlyn: tx.TxHash = preByteHash(tx.ToBytes()).

Mae'r dull llinyn ToJSON() yn trosi trafodiad yn llinyn JSON.

Mae'r dull gwall FromJSON(data []beit) yn llwytho trafodiad o'r fformat JSON a basiwyd fel sleisen beit.

Mae'r dull bool Check() yn cymharu'r stwnsh sy'n deillio o faes stwnsh y trafodiad Γ’'r hash a gafwyd o ganlyniad i stwnsio'r trafodiad hwn (gan anwybyddu'r maes hash).

Mae trafodion yn cael eu hychwanegu at y bloc: github.com/Rusldv/bcstartup/blob/master/block/builder.go

Mae'r strwythur data bloc yn fwy swmpus:

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
}

Mae DataType yn storio'r math o ddata, mae'r nod yn ei ddefnyddio ac yn gwahaniaethu'r bloc o drafodiad neu ddata arall. Ar gyfer bloc, y gwerth hwn yw 1.

Mae BlockHeight yn storio uchder y bloc.
Stamp amser stamp amser.
HeaderSize yw maint y bloc mewn beit.
PrevBlockHash yw hash y bloc blaenorol, a SelfBlockHash yw stwnsh yr un presennol.
Mae TxsHash yn stwnsh cyffredinol o drafodion.
MerkleRoot yw gwraidd y goeden Merkle.

Ymhellach yn y meysydd mae allwedd gyhoeddus crΓ«wr y bloc, llofnod y crΓ«wr, fersiwn y bloc, nifer y trafodion yn y bloc, a'r trafodion hyn eu hunain.

Edrychwn ar ei ddulliau:
I greu bloc, defnyddiwch y swyddogaeth block.NewBlock(): NewBlock (llinyn prevBlockHash, uchder int) *Bloc, sy'n cymryd stwnsh y bloc blaenorol a'r uchder a osodwyd ar gyfer y bloc a grΓ«wyd yn y blockchain. Mae'r math bloc hefyd wedi'i osod o'r math o becyn cyson:

b.DataType = types.BLOCK_TYPE.

Mae'r dull AddTx(tx *transaction.TX) yn ychwanegu trafodiad at floc.

Mae'r dull Build() yn llwytho gwerthoedd i feysydd y bloc ac yn cynhyrchu ac yn gosod ei stwnsh gyfredol.

Mae'r dull ToBytesHeader() [] beit yn trosi'r pennawd bloc (heb drafodion) yn sleisen beit.

Mae'r dull llinyn ToJSON() yn trosi'r bloc i fformat JSON mewn cynrychioliad llinynnol o'r data.

Mae'r dull gwall FromJSON(data []beit) yn llwytho data o JSON i mewn i strwythur bloc.

Mae'r dull bool Check() yn cynhyrchu hash bloc ac yn ei gymharu Γ’'r un a nodir yn y maes stwnsh bloc.

Mae'r dull llinyn GetTxsHash() yn dychwelyd cyfanswm hash yr holl drafodion yn y bloc.

Mae'r dull GetMerkleRoot () yn pennu gwraidd y goeden Merkle ar gyfer trafodion mewn bloc.

Mae'r dull Sign(privk string) yn arwyddo bloc gydag allwedd breifat crΓ«wr y bloc.

Mae'r dull SetHeight (uchder int) yn ysgrifennu uchder y bloc i faes strwythur y bloc.

Mae'r dull GetHeight () int yn dychwelyd uchder y bloc fel y nodir ym maes cyfatebol strwythur y bloc.

Mae'r dull ToGOBBytes() [] beit yn amgodio bloc mewn fformat GOB ac yn ei ddychwelyd fel sleisen beit.

Mae'r dull gwall FromGOBBytes(data []beit) yn ysgrifennu data bloc i'r strwythur bloc o'r sleisen beit a basiwyd mewn fformat GOB.

Mae'r dull llinyn GetHash() yn dychwelyd hash y bloc a roddwyd.

Mae'r dull llinyn GetPrevHash() yn dychwelyd stwnsh y bloc blaenorol.

Mae'r dull SetPublicKey (llinyn pubk) yn ysgrifennu allwedd gyhoeddus crΓ«wr y bloc i'r bloc.

Felly, gan ddefnyddio dulliau'r gwrthrych Bloc, gallwn ei drosi'n hawdd i fformat i'w drosglwyddo dros y rhwydwaith a'i arbed i gronfa ddata LevelDB.

Mae swyddogaethau'r pecyn blockchain yn gyfrifol am arbed i'r blockchain: github.com/Rusldv/bcstartup/tree/master/blockchain

I wneud hyn, rhaid i'r bloc weithredu'r rhyngwyneb IBlock:

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

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

}

Mae'r cysylltiad cronfa ddata yn cael ei greu unwaith pan fydd y pecyn yn cael ei gychwyn yn y swyddogaeth init ():

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

Mae CloseDB() yn ddeunydd lapio ar gyfer db.Cloce() - a elwir ar Γ΄l gweithio gyda'r swyddogaethau pecyn i gau'r cysylltiad Γ’'r gronfa ddata.

Mae ffwythiant gwall SetTargetBlockHash (llinyn hash) yn ysgrifennu stwnsh y bloc cerrynt gyda'r allwedd a nodir gan y cysonyn BLOCK_HASH i'r gronfa ddata.

Mae swyddogaeth GetTargetBlockHash() (llinyn, gwall) yn dychwelyd stwnsh y bloc cyfredol sydd wedi'i storio yn y gronfa ddata.

Mae'r ffwythiant gwall SetTargetBlockHeight (uchder int) yn ysgrifennu i'r gronfa ddata gwerth uchder y blockchain ar gyfer y nod gyda'r allwedd a bennir gan y cysonyn BLOCK_HEIGHT.

Mae swyddogaeth GetTargetBlockHeight() (int, error) yn dychwelyd uchder y blockchain ar gyfer nod penodol, wedi'i storio yn y gronfa ddata.

Mae swyddogaeth bool CheckBlock (bloc IBlock) yn gwirio cywirdeb bloc cyn ychwanegu'r bloc hwn at y blockchain.

Mae swyddogaeth gwall AddBlock (bloc IBlock) yn ychwanegu bloc at y blockchain.

Mae'r swyddogaethau ar gyfer adalw a gwylio blociau yn ffeil explorer.go y pecyn blockchain:

Mae swyddogaeth GetBlockByHash (llinyn hash) (*block.Block, error) yn creu gwrthrych bloc gwag, yn llwytho bloc i mewn iddo o'r gronfa ddata, y mae'r stwnsh ohono wedi'i drosglwyddo iddo, ac yn dychwelyd pwyntydd iddo.

Mae creu bloc genesis yn cael ei wneud gan swyddogaeth gwall Genesis() o ffeil genesis.go y pecyn blockchain.

Bydd yr erthygl nesaf yn sΓ΄n am gysylltu cleientiaid Γ’ nod gan ddefnyddio mecanwaith WebSocket.

Ffynhonnell: hab.com

Ychwanegu sylw