Менің Go блокчейнімде блоктар мен транзакцияларды қалай құрастырдым

Сайып келгенде, жай ғана дерекқор емес, блокчейнмен аяқталу үшін жобамызға 3 маңызды элементті қосуымыз керек:

  • Блок деректерінің құрылымы мен әдістерінің сипаттамасы
  • Мәліметтер құрылымы мен транзакция әдістерінің сипаттамасы
  • Блоктарды дерекқорда сақтайтын және оларды хэш немесе биіктігі (немесе басқа нәрсе) бойынша табатын блокчейн функциялары.

Менің Go блокчейнімде блоктар мен транзакцияларды қалай құрастырдым

Бұл өнеркәсіпке арналған блокчейн туралы екінші мақала, бірінші осында.

Оқырмандардың осы серияның алдыңғы мақаласы туралы маған қойған сұрақтарын еске түсіре отырып, мынаны атап өткен жөн: бұл жағдайда LevelDB дерекқоры блокчейн деректерін сақтау үшін пайдаланылады, бірақ басқа ешнәрсе, айталық, MySQL пайдалануыңызға ешнәрсе кедергі келтірмейді. Енді осы деректердің құрылымын қарастырайық.

Транзакциялардан бастайық: github.com/Rusldv/bcstartup/blob/master/transaction/builder.go

Міне, оның деректер құрылымы:

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 деректер түрін (2-транзакция үшін), осы транзакцияның хэшін, транзакция түрін, уақыт белгісін, кірістер мен шығыстарды сақтайды. TxIn кірістері шығысына сілтеме жасалған транзакция хэшін, осы шығыстың және байт кодының нөмірін, ал TxOut шығыстары кейбір мәнді және сонымен қатар байт кодты сақтайды.

Енді транзакция оның деректерінде қандай әрекеттерді орындай алатынын көрейік, яғни. әдістерін қарастырайық.

Транзакция жасау үшін транзакция.NewTransaction(txtype байт) *TX функциясын пайдаланыңыз.

AddTxIn(thattxhash []byte, txoutn int, code []byte) (*TxIn, error) әдісі транзакцияға енгізуді қосады.

AddTxOut(int мәні, деректер []байт) (*TxOut, қате) әдісі транзакцияға шығыс қосады.

ToBytes() []байт әдісі транзакцияны байт тіліміне айналдырады.

Ішкі функцияның preByteHash(байт []байт) жолы жасалған транзакция хэшін JavaScript қолданбаларынан жасалған транзакция хэштерімен үйлесімді ету үшін Build() және Check() ішінде пайдаланылады.

Build() әдісі транзакция хэшін келесідей орнатады: tx.TxHash = preByteHash(tx.ToBytes()).

ToJSON() жол әдісі транзакцияны JSON жолына түрлендіреді.

FromJSON(деректер []байт) қате әдісі байт тілімі ретінде берілген JSON пішімінен транзакцияны жүктейді.

Check() bool әдісі транзакция хэш өрісінен алынған хэшті осы транзакцияны хэштеу нәтижесінде алынған хэшпен салыстырады (хэш өрісін елемеу).

Блокқа транзакциялар қосылады: github.com/Rusldv/bcstartup/blob/master/block/builder.go

Блоктық деректер құрылымы неғұрлым көлемді:

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 деректер түрін сақтайды, түйін оны пайдаланады және блокты транзакциядан немесе басқа деректерден ажыратады. Блок үшін бұл мән 1.

BlockHeight блоктың биіктігін сақтайды.
Уақыт белгісі уақыт белгісі.
HeaderSize - байттағы блок өлшемі.
PrevBlockHash - алдыңғы блоктың хэші, ал SelfBlockHash - ағымдағы блоктың хэші.
TxsHash – транзакциялардың жалпы хэші.
MerkleRoot - Merkle ағашының тамыры.

Әрі қарай өрістерде блокты жасаушының ашық кілті, жасаушының қолы, блоктың нұсқасы, блоктағы транзакциялар саны және осы транзакциялардың өздері болады.

Оның әдістерін қарастырайық:
Блок жасау үшін block.NewBlock() функциясын пайдаланыңыз: NewBlock(prevBlockHash жолы, биіктік int) *Блок, алдыңғы блоктың хэшін және блокчейндегі құрылған блок үшін орнатылған биіктікті қабылдайды. Блок түрі де түрлер бумасының тұрақтысынан орнатылады:

b.DataType = types.BLOCK_TYPE.

AddTx(tx *transaction.TX) әдісі транзакцияны блокқа қосады.

Build() әдісі мәндерді блоктың өрістеріне жүктейді және оның ағымдағы хэшін жасайды және орнатады.

ToBytesHeader() []байт әдісі блок тақырыбын (транзакцияларсыз) байт кесіндісіне түрлендіреді.

ToJSON() жол әдісі блокты деректердің жол көрінісіндегі JSON пішіміне түрлендіреді.

FromJSON(деректер []байт) қате әдісі JSON деректерін блок құрылымына жүктейді.

Check() bool әдісі блок хэшін жасайды және оны блок хэш өрісінде көрсетілгенмен салыстырады.

GetTxsHash() жол әдісі блоктағы барлық транзакциялардың жалпы хэшін қайтарады.

GetMerkleRoot() әдісі блоктағы транзакциялар үшін Merkle ағашының түбірін көрсетеді.

Sign(privk string) әдісі блок жасаушының жеке кілтімен блокқа қол қояды.

SetHeight(height int) әдісі блоктың биіктігін блок құрылымы өрісіне жазады.

GetHeight() int әдісі блок құрылымының сәйкес өрісінде көрсетілген блоктың биіктігін қайтарады.

ToGOBBytes() []байт әдісі блокты GOB пішімінде кодтайды және оны байт кесіндісі ретінде қайтарады.

FromGOBBytes(деректер []байт) қате әдісі блок деректерін GOB пішімінде жіберілген байт бөлігінен блок құрылымына жазады.

GetHash() жол әдісі берілген блоктың хэшін қайтарады.

GetPrevHash() жол әдісі алдыңғы блоктың хэшін қайтарады.

SetPublicKey(pubk жолы) әдісі блок жасаушының ашық кілтін блокқа жазады.

Осылайша, Block нысанының әдістерін қолдана отырып, біз оны желі арқылы тасымалдау және LevelDB дерекқорына сақтау үшін форматқа оңай түрлендіре аламыз.

Блокчейн пакетінің функциялары блокчейнге сақтау үшін жауап береді: github.com/Rusldv/bcstartup/tree/master/blockchain

Ол үшін блок IBlock интерфейсін енгізуі керек:

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

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

}

Бума init() функциясында инициализацияланған кезде дерекқор қосылымы бір рет жасалады:

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

CloseDB() – db.Cloce() үшін орауыш – дерекқорға қосылымды жабу үшін бума функцияларымен жұмыс істегеннен кейін шақырылады.

SetTargetBlockHash(хэш жолы) қате функциясы дерекқорға BLOCK_HASH тұрақтысы арқылы көрсетілген кілтпен ағымдағы блоктың хэшін жазады.

GetTargetBlockHash() (жол, қате) функциясы дерекқорда сақталған ағымдағы блоктың хэшін қайтарады.

SetTargetBlockHeight(height int) қате функциясы дерекқорға BLOCK_HEIGHT тұрақтысымен көрсетілген кілті бар түйін үшін блокчейн биіктігінің мәнін жазады.

GetTargetBlockHeight() (int, қате) функциясы дерекқорда сақталған берілген түйін үшін блокчейннің биіктігін қайтарады.

CheckBlock(block IBlock) bool функциясы осы блокты блокчейнге қоспас бұрын блоктың дұрыстығын тексереді.

AddBlock(block IBlock) қате функциясы блокчейнге блок қосады.

Блоктарды шығарып алу және қарау функциялары blockchain бумасының explore.go файлында орналасқан:

GetBlockByHash(хэш жолы) (*block.Block, қате) функциясы бос блок нысанын жасайды, оған хэш берілген дерекқордан блокты жүктейді және оған көрсеткішті қайтарады.

Генезис блогын құру блокчейн пакетінің genesis.go файлындағы Genesis() қате функциясы арқылы жүзеге асырылады.

Келесі мақалада WebSocket механизмі арқылы тұтынушыларды түйінге қосу туралы айтылады.

Ақпарат көзі: www.habr.com

пікір қалдыру