Min çawa blokan û danûstendinên di bloka xweya Go-ya xwe de sêwirand

Ji bo ku em di dawiyê de bi blokek û ne tenê databasek bi dawî bibin, divê em 3 hêmanên girîng li projeya xwe zêde bikin:

  • Danasîna struktur û rêbazên daneya blokê
  • Danasîna avahiya daneyê û rêbazên danûstendinê
  • Fonksiyonên Blockchain-ê ku blokan di databasek de hilîne û wan li wir li gorî heş an bilindahiya wan (an tiştek din) dibîne.

Min çawa blokan û danûstendinên di bloka xweya Go-ya xwe de sêwirand

Ev gotara duyemîn di derbarê blokcheyn ji bo pîşesaziyê de, ya yekem e vir.

Bîranîna pirsên ku xwendevanan di derheqê gotara berê ya vê rêzê de ji min pirsîn, divê were zanîn: di vê rewşê de, databasa LevelDB ji bo hilanîna daneyên blokê tê bikar anîn, lê tiştek nahêle ku hûn tiştek din bikar bînin, bêje, MySQL. Niha em li avahiya van daneyan binêrin.

Ka em bi danûstandinan dest pê bikin: github.com/Rusldv/bcstartup/blob/master/transaction/builder.go

Li vir avahiya daneya wê ye:

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 celebê daneyê (ji bo danûstendina 2), hashê wê danûstendinê, celebê danûstendinê bixwe, nîşanek dem, û ketin û derketinan hilîne. Têketinên TxIn haşeya danûstendina ku derenca wê tê referans kirin, hejmara vê derketinê û bytekodê hilîne, û derketinên TxOut hin nirx û di heman demê de bytecode jî hilîne.

Naha em bibînin ka çi kiryarek dikare li ser daneyên xwe bike, yanî. Ka em li rêbazan binêrin.

Ji bo çêkirina danûstendinê, danûstandinê bikar bînin.NewTransaction(txtype byte) *Fonksiyon TX.

Rêbaza AddTxIn(thattxhash []byte, txoutn int, kod []byte) (*TxIn, xeletî) têketinekê li danûstendinê zêde dike.

Rêbaza AddTxOut(nirx int, dane []byte) (*TxOut, xeletî) encamek li danûstendinê zêde dike.

Rêbaza ToBytes() []byte danûstendinê vediguherîne perçeyek byte.

PreByteHash(bytes []byte) rêzika hundurîn di Build() û Check() de tê bikar anîn da ku haşeya danûstendinê ya çêkirî bi haşeyên danûstendinê yên ku ji sepanên JavaScriptê têne çêkirin re hevaheng be.

Rêbaza Avakirin() haşa danûstendinê wiha destnîşan dike: tx.TxHash = preByteHash(tx.ToBytes()).

Rêbaza rêzika ToJSON() danûstendinê vediguherîne stringek JSON.

Rêbaza xeletiya FromJSON(dane []byte) danûstendinek ji formata JSON ku wekî perçeyek byte hatî derbas kirin bar dike.

Rêbaza Check() bool hash-a ku ji qada hash-a danûstendinê tê bi hash-a ku di encama haşkirina vê danûstendinê de hatî peyda kirin (guhnedana qada hash) berhev dike.

Danûstandin li blokê têne zêdekirin: github.com/Rusldv/bcstartup/blob/master/block/builder.go

Struktura daneya blokê pirtir e:

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 cureyê daneyê hildide, nod wê bikar tîne û blokê ji danûstendinek an daneyên din cuda dike. Ji bo blokê ev nirx 1 e.

BlockHeight bilindahiya blokê hilîne.
Demjimêra demjimêrê.
HeaderSize mezinahiya blokê bi bîtan e.
PrevBlockHash hashê bloka berê ye, û SelfBlockHash hasha ya bloka heyî ye.
TxsHash hashek giştî ya danûstendinan e.
MerkleRoot koka dara Merkleyê ye.

Zêdetir di qadan de mifteya giştî ya afirînerê blokê, îmzeya afirîner, guhertoya blokê, hejmara danûstendinên di blokê de, û van kiryaran bixwe hene.

Ka em li rêbazên wê binêrin:
Ji bo afirandina blokê, fonksiyona blokê bikar bînin.Fonksiyon NewBlock(): NewBlock(prevBlockHash string, height int) *Block, ku haşa bloka berê û bilindahiya ku ji bo bloka hatî afirandin di zincîra blokê de hatî danîn digire. Tîpa blokê jî ji celebên pakêtê domdar tê danîn:

b.DataType = types.BLOCK_TYPE.

Rêbaza AddTx(tx *transaction.TX) danûstendinê li blokê zêde dike.

Rêbaza Build() nirxan di nav zeviyên blokê de bar dike û hasha wê ya heyî çêdike û saz dike.

Rêbaza ToBytesHeader() []byte sernavê blokê (bê danûstandin) vediguherîne perçeyek byte.

Rêbaza rêzika ToJSON() blokê di nûneriya rêzika daneyê de vediguherîne formata JSON.

Rêbaza xeletiya FromJSON(dane []byte) daneyan ji JSON di nav avahiyek blokê de bar dike.

Rêbaza Check() bool hashek blokê çêdike û wê bi ya ku di qada blokê de hatî destnîşan kirin berhev dike.

Rêbaza rêzika GetTxsHash() jimareya giştî ya hemî danûstendinên di blokê de vedigerîne.

Rêbaza GetMerkleRoot() koka dara Merkle ji bo danûstandinên di blokê de diyar dike.

Rêbaza Nîşan (rêzika privk) blokê bi mifteya taybet a afirînerê blokê nîşan dide.

Rêbaza SetHeight(height int) bilindahiya blokê li qada avahiya blokê dinivîse.

Rêbaza GetHeight() int bilindahiya blokê wekî ku di qada têkildar a avahiya blokê de hatî destnîşan kirin vedigerîne.

Rêbaza ToGOBBytes() []byte blokê di formata GOB de kod dike û wê wekî perçeyek byte vedigerîne.

Rêbaza xeletiya FromGOBBytes(dane []byte) daneyên blokê li avahiya blokê ji perçeya byte ya derbasbûyî di formata GOB de dinivîse.

Rêbaza rêzika GetHash() haşa bloka diyarkirî vedigerîne.

Rêbaza rêzika GetPrevHash() haşa bloka berê vedigerîne.

Rêbaza SetPublicKey (rêzika pubk) mifteya giştî ya afirînerê blokê li blokê dinivîse.

Bi vî rengî, bi karanîna rêbazên objeya Blockê, em dikarin bi hêsanî wê veguhezînin formatek ji bo veguheztina li ser torê û hilanîna li databasa LevelDB.

Fonksiyonên pakêta blokê berpirsiyar e ku li blokê hilîne: github.com/Rusldv/bcstartup/tree/master/blockchain

Ji bo vê yekê, blok pêdivî ye ku pêwendiya IBlock bicîh bîne:

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

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

}

Dema ku pakêt di fonksiyona init() de dest pê dike, girêdana databasê carekê tê afirandin:

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

CloseDB() ji bo db.Cloce() pêçanek e - piştî xebata bi fonksiyonên pakêtê re tê gotin ku girêdana bi databasê re bigire.

Fonksiyona çewtiya SetTargetBlockHash (xêza haş) haşa bloka heyî bi mifteya ku ji hêla berdewamiya BLOCK_HASH ve hatî destnîşankirin li databasê dinivîse.

Fonksiyona GetTargetBlockHash() (string, çewtî) haşa bloka heyî ya ku di databasê de hatî hilanîn vedigerîne.

Fonksiyona xeletiya SetTargetBlockHeight (bilindahiya int) nirxa bilindahiya zincîra blokê ji bo girêka bi mifteya ku ji hêla berdewamiya BLOCK_HEIGHT ve hatî destnîşan kirin ji databasê re dinivîse.

Fonksiyona GetTargetBlockHeight() (int, xelet) bilindahiya zincîra blokê ji bo nodek diyarkirî, ku di databasê de hatî hilanîn vedigerîne.

Fonksiyona boolê CheckBlock (bloka IBlock) berî ku vê blokê li zincîra blokê zêde bike, blokê ji bo rastbûnê kontrol dike.

Fonksiyona xeletiya AddBlock (bloka IBlock) blokê li zincîra blokê zêde dike.

Fonksiyonên ji bo wergirtin û dîtina blokan di pelê explore.go ya pakêta blokê de ne:

Fonksiyon GetBlockByHash(hash string) (*block.Block, error) objeyek blokek vala diafirîne, blokek ji databasê, ku haş jê re derbas bûye, bar dike û nîşanek jê re vedigerîne.

Afirandina bloka genesisê ji hêla fonksiyona xeletiya Genesis() ve ji pelê genesis.go ya pakêta zincîra blokê ve tête kirin.

Gotara paşîn dê li ser girêdana xerîdaran bi nodek bi karanîna mekanîzmaya WebSocket re biaxive.

Source: www.habr.com

Add a comment