Որպեսզի ի վերջո հայտնվենք բլոկչեյնով և ոչ միայն տվյալների բազայով, մենք պետք է մեր նախագծին ավելացնենք 3 կարևոր տարր.
- Բլոկի տվյալների կառուցվածքի և մեթոդների նկարագրությունը
- Տվյալների կառուցվածքի և գործարքների մեթոդների նկարագրությունը
- Blockchain-ի գործառույթներ, որոնք պահում են բլոկները տվյալների բազայում և գտնում դրանք այնտեղ իրենց հեշով կամ բարձրությամբ (կամ այլ բանով):
Սա արդյունաբերության համար բլոկչեյնի մասին երկրորդ հոդվածն է, առաջինը
Հիշելով այս շարքի նախորդ հոդվածի վերաբերյալ ընթերցողների կողմից տրված հարցերը, հարկ է նշել. այս դեպքում LevelDB տվյալների բազան օգտագործվում է բլոկչեյնի տվյալները պահելու համար, բայց ոչինչ չի խանգարում ձեզ օգտագործել որևէ այլ, ասենք, MySQL: Հիմա եկեք նայենք այս տվյալների կառուցվածքին:
Սկսենք գործարքներից.
Ահա դրա տվյալների կառուցվածքը.
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 ելքերը պահում են որոշակի արժեք և նաև բայթ կոդը:
Այժմ տեսնենք, թե ինչ գործողություններ կարող է կատարել գործարքն իր տվյալների վրա, այսինքն. Եկեք նայենք մեթոդներին:
Գործարք ստեղծելու համար օգտագործեքtransaction.NewTransaction(txtype byte) *TX ֆունկցիան:
AddTxIn(thattxhash []byte, txoutn int, code []byte) (*TxIn, error) մեթոդը մուտք է ավելացնում գործարքին։
AddTxOut(value int, data []byte) (*TxOut, error) մեթոդը ելք է ավելացնում գործարքին:
ToBytes() []byte մեթոդը գործարքը վերածում է բայթ հատվածի:
Ներքին ֆունկցիայի preByteHash(bytes []byte) տողը օգտագործվում է Build()-ում և Check()-ում՝ ստեղծվող գործարքի հեշը համատեղելի դարձնելու JavaScript հավելվածներից ստեղծված գործարքների հեշերի հետ:
Build() մեթոդը սահմանում է գործարքի հեշը հետևյալ կերպ. tx.TxHash = preByteHash(tx.ToBytes()):
ToJSON() տողի մեթոդը գործարքը փոխակերպում է JSON տողի:
FromJSON(data []byte) սխալի մեթոդը բեռնում է գործարքը JSON ձևաչափից, որը փոխանցվել է որպես բայթ հատված:
Check() bool մեթոդը համեմատում է գործարքի հեշ դաշտից ստացված հեշը այս գործարքի հեշավորման արդյունքում ստացված հեշի հետ (անտեսելով հեշ դաշտը):
Գործարքները ավելացվում են բլոկին.
Բլոկի տվյալների կառուցվածքը ավելի ծավալուն է.
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() ֆունկցիան. Բլոկի տեսակը սահմանվում է նաև տիպերի փաթեթի հաստատունից.
b.DataType = types.BLOCK_TYPE.
AddTx(tx *transaction.TX) մեթոդը գործարք է ավելացնում բլոկին:
Build() մեթոդը բեռնում է արժեքները բլոկի դաշտերում և ստեղծում և սահմանում դրա ընթացիկ հեշը:
ToBytesHeader() []byte մեթոդը բլոկի վերնագիրը (առանց գործարքների) փոխակերպում է բայթ հատվածի։
ToJSON() լարային մեթոդը բլոկը փոխակերպում է JSON ձևաչափի՝ տվյալների տողային ներկայացման մեջ:
FromJSON(data []byte) սխալի մեթոդը JSON-ից տվյալները բեռնում է բլոկի կառուցվածքում:
Check() bool մեթոդը ստեղծում է բլոկի հեշ և համեմատում այն բլոկի հեշ դաշտում նշվածի հետ։
GetTxsHash() լարային մեթոդը վերադարձնում է բլոկի բոլոր գործարքների ընդհանուր հեշը:
GetMerkleRoot() մեթոդը սահմանում է Merkle ծառի արմատը բլոկում գործարքների համար:
Sign (privk string) մեթոդը ստորագրում է բլոկը բլոկ ստեղծողի անձնական բանալիով:
SetHeight(height int) մեթոդը գրում է բլոկի բարձրությունը բլոկի կառուցվածքի դաշտում։
GetHeight() int մեթոդը վերադարձնում է բլոկի բարձրությունը, ինչպես նշված է բլոկի կառուցվածքի համապատասխան դաշտում։
ToGOBBytes() []byte մեթոդը կոդավորում է GOB ձևաչափով բլոկը և վերադարձնում այն որպես բայթ հատված:
FromGOBBytes(data []byte) սխալի մեթոդը բլոկի տվյալները գրում է բլոկի կառուցվածքում անցած բայթի հատվածից GOB ձևաչափով:
GetHash() լարային մեթոդը վերադարձնում է տվյալ բլոկի հեշը։
GetPrevHash() լարային մեթոդը վերադարձնում է նախորդ բլոկի հեշը։
SetPublicKey (pubk string) մեթոդը բլոկի վրա գրում է բլոկ ստեղծողի հանրային բանալին:
Այսպիսով, օգտագործելով Block օբյեկտի մեթոդները, մենք հեշտությամբ կարող ենք այն վերածել ցանցի միջոցով փոխանցման և LevelDB տվյալների բազայում պահպանման ձևաչափի։
Բլոկչեյն փաթեթի գործառույթները պատասխանատու են բլոկչեյնին խնայելու համար.
Դա անելու համար բլոկը պետք է իրականացնի 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(hash string) սխալ ֆունկցիան տվյալների բազայում գրում է ընթացիկ բլոկի հեշը BLOCK_HASH հաստատունով նշված բանալիով:
GetTargetBlockHash() (string, error) ֆունկցիան վերադարձնում է տվյալների բազայում պահվող ընթացիկ բլոկի հեշը։
SetTargetBlockHeight(height int) սխալ ֆունկցիան տվյալների բազայում գրում է հանգույցի համար բլոկչեյնի բարձրության արժեքը BLOCK_HEIGHT հաստատունով նշված բանալիով:
GetTargetBlockHeight() (int, error) ֆունկցիան վերադարձնում է տվյալների բազայում պահվող բլոկչեյնի բարձրությունը տվյալ հանգույցի համար:
CheckBlock (block IBlock) bool ֆունկցիան ստուգում է բլոկի ճշգրտությունը՝ նախքան այս բլոկը բլոկչեյնին ավելացնելը:
AddBlock(block IBlock) սխալ ֆունկցիան բլոկ է ավելացնում բլոկչեյնին:
Բլոկների առբերման և դիտման գործառույթները գտնվում են blockchain փաթեթի explore.go ֆայլում.
GetBlockByHash(hash string) (*block.Block, error) ֆունկցիան ստեղծում է դատարկ բլոկ օբյեկտ, բեռնում է դրա մեջ բլոկ տվյալների բազայից, որի հեշը փոխանցվել է նրան և վերադարձնում ցուցիչ։
Genesis բլոկի ստեղծումն իրականացվում է Genesis() սխալ ֆունկցիայի միջոցով բլոկչեյն փաթեթի genesis.go ֆայլից:
Հաջորդ հոդվածում կխոսվի WebSocket մեխանիզմի միջոցով հաճախորդներին հանգույցին միացնելու մասին:
Source: www.habr.com