Sut wnes i ddylunio blociau a thrafodion yn fy blockchain Go

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

  • Disgrifiad o strwythur data a dulliau'r bloc
  • Disgrifiad o'r strwythur data a'r dulliau trafodion
  • Swyddogaethau blockchain sy'n storio blociau yn y gronfa ddata ac yn eu canfod yno yn Γ΄l eu hash neu eu huchder (neu ryw ffordd arall).

Sut wnes i ddylunio blociau a thrafodion yn fy blockchain Go

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

Gan gofio'r cwestiynau a ofynnwyd i mi gan ddarllenwyr am yr erthygl flaenorol yn y gyfres hon, mae'n werth nodi: defnyddir LevelDB i storio data blockchain yn yr achos hwn, ond does dim byd yn eich atal rhag defnyddio unrhyw gronfa ddata arall, fel 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 data (ar gyfer trafodiad 2), hash y trafodiad, y math o drafodiad ei hun, y stamp amser, yn ogystal Γ’'r mewnbynnau ac allbynnau. Mae mewnbynnau TxIn yn storio hash allbwn y trafodiad cyfeiriedig, rhif yr allbwn, a'r cod beit, tra bod allbynnau TxOut yn storio gwerth a hefyd y cod beit.

Nawr, gadewch i ni edrych ar ba gamau y gall trafodiad eu perfformio ar ei ddata, h.y., gadewch i ni ddadansoddi'r dulliau.

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

Mae'r dull AddTxIn(thattxhash[]byte, txoutn int, code[]byte)(*TxIn, error) yn ychwanegu mewnbwn at y trafodiad.

Mae'r dull AddTxOut(value int, data []byte) (*TxOut, error) yn ychwanegu allbwn at y trafodiad.

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

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

Mae'r dull Build() yn gosod hash y 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 []byte) yn llwytho trafodiad o fformat JSON wedi'i basio fel sleisen beit.

Mae'r dull bool Check() yn cymharu'r hash sy'n deillio o faes hash y trafodiad Γ’'r hash a geir trwy hasio'r trafodiad hwn (ac eithrio'r maes hash).

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

Mae strwythur data'r bloc yn fwy cyfaint:

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 data, y mae'r nod yn ei ddefnyddio i wahaniaethu bloc oddi wrth drafodiad neu ddata arall. Ar gyfer bloc, y gwerth hwn yw 1.

Mae BlockHeight yn storio uchder bloc.
Stamp amser stamp amser.
Maint y Pennawd yw maint y bloc mewn bytes.
PrevBlockHash yw hash y bloc blaenorol, a SelfBlockHash yw hash y bloc cyfredol.
TxsHash yw'r hash trafodiad a rennir.
MerkleRoot yw gwreiddyn coeden Merkle.

Mae'r meysydd canlynol yn cynnwys allwedd gyhoeddus crΓ«wr y bloc, llofnod y crΓ«wr, fersiwn y bloc, nifer y trafodion yn y bloc, a'r trafodion eu hunain.

Gadewch i ni edrych ar ei ddulliau:
I greu bloc, defnyddiwch y ffwythiant block.NewBlock(): NewBlock(prevBlockHash string, height int) *Block, sy'n derbyn hash y bloc blaenorol a'r uchder a osodwyd ar gyfer y bloc a grΓ«wyd yn y blockchain. Mae'r math o floc hefyd wedi'i bennu o'r cysonyn pecyn types:

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 hash cyfredol.

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

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

Mae'r dull gwall FromJSON(data []byte) 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 bennir yn y maes hash bloc.

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

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

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

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

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

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

Mae'r dull gwall FromGOBBytes(data []byte) yn ysgrifennu data bloc i'r strwythur bloc o'r sleisen beit wedi'i fformatio Γ’ GOB a basiwyd.

Mae'r dull llinyn GetHash() yn dychwelyd hash bloc penodol.

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

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

Felly, gan ddefnyddio'r dulliau gwrthrych Bloc, gallwn ei drosi'n hawdd i fformat ar gyfer trosglwyddo dros y rhwydwaith a'i gadw i gronfa ddata LevelDB.

Mae'r swyddogaethau canlynol o'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 ffwythiant init():

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

Mae CloseDB() yn lapio ar gyfer db.Cloce() - fe'i gelwir ar Γ΄l gweithio gyda ffwythiannau pecyn i gau'r cysylltiad Γ’'r gronfa ddata.

Mae'r ffwythiant gwall SetTargetBlockHash(hash string) yn ysgrifennu hash y bloc cyfredol i'r gronfa ddata gyda'r allwedd a bennir gan y cysonyn BLOCK_HASH.

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

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

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

Mae'r ffwythiant bool CheckBlock(block IBlock) yn gwirio bloc am gywirdeb cyn ychwanegu'r bloc hwnnw at y gadwyn gadwyn.

Mae'r ffwythiant gwall AddBlock(bloc IBlock) yn ychwanegu bloc at y blockchain.

Mae'r swyddogaethau ar gyfer adfer a gweld blociau wedi'u lleoli yn ffeil explore.go y pecyn blockchain:

Mae'r ffwythiant GetBlockByHash(hash string) (*block.Block, error) yn creu gwrthrych bloc gwag, yn llwytho'r bloc o'r gronfa ddata y mae ei hash yn cael ei basio iddo, ac yn dychwelyd pwyntydd iddo.

Mae creu bloc genesis yn cael ei berfformio gan y ffwythiant gwall Genesis() o'r ffeil genesis.go o'r pecyn blockchain.

Bydd yr erthygl nesaf yn trafod cysylltu cleientiaid Γ’'r nod gan ddefnyddio'r mecanwaith WebSocket.

Ffynhonnell: hab.com

Prynu gwesteio dibynadwy ar gyfer gwefannau sydd Γ’ diogelwch DDoS, gweinyddwyr VPS VDS πŸ”₯ Prynu cynnal gwefannau dibynadwy gyda diogelwch DDoS, gweinyddion VPS VDS | ProHoster