Hur jag designade block och transaktioner i min Go blockchain

För att i slutÀndan fÄ en blockkedja och inte bara en databas, mÄste vi lÀgga till tre viktiga element till vÄrt projekt:

  • Beskrivning av blockdatastrukturen och metoder
  • Beskrivning av datastruktur och transaktionsmetoder
  • Blockkedjefunktioner som sparar block i en databas och hittar dem dĂ€r genom deras hash eller höjd (eller nĂ„got annat).

Hur jag designade block och transaktioner i min Go blockchain

Detta Àr den andra artikeln om blockchain för industrin, den första hÀr.

Kom ihÄg frÄgorna som lÀsarna stÀllde mig om den tidigare artikeln i den hÀr serien, bör det noteras: i det hÀr fallet anvÀnds LevelDB-databasen för att lagra blockchain-data, men ingenting hindrar dig frÄn att anvÀnda nÄgon annan, sÀg, MySQL. LÄt oss nu titta pÄ strukturen för dessa data.

LÄt oss börja med transaktioner: github.com/Rusldv/bcstartup/blob/master/transaction/builder.go

HÀr Àr dess datastruktur:

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 lagrar datatypen (för transaktion 2), hashen för den transaktionen, typen av sjÀlva transaktionen, en tidsstÀmpel och in- och utdata. TxIn-ingÄngar lagrar hashen för transaktionen vars utgÄng refereras till, numret pÄ denna utgÄng och bytekod, och TxOut-utgÄngar lagrar ett visst vÀrde och Àven bytekod.

LÄt oss nu se vilka ÄtgÀrder en transaktion kan utföra pÄ sina data, dvs. LÄt oss titta pÄ metoderna.

För att skapa en transaktion, anvÀnd funktionen transaction.NewTransaction(TXtype byte) *TX.

Metoden AddTxIn(thattxhash []byte, txoutn int, kod []byte) (*TxIn, fel) lÀgger till en indata till transaktionen.

Metoden AddTxOut(vÀrde int, data []byte) (*TxOut, fel) lÀgger till en utdata till transaktionen.

Metoden ToBytes() []byte förvandlar transaktionen till en bytedel.

Den interna funktionen preByteHash(bytes []byte)-strÀngen anvÀnds i Build() och Check() för att göra den genererade transaktionshashen kompatibel med transaktionshashar som genereras frÄn JavaScript-applikationer.

Metoden Build() stÀller in transaktionshashen enligt följande: tx.TxHash = preByteHash(tx.ToBytes()).

StrÀngmetoden ToJSON() konverterar en transaktion till en JSON-strÀng.

FromJSON(data []byte)-felmetoden lÀser in en transaktion frÄn JSON-formatet som skickas som ett bytesegment.

Check() bool-metoden jÀmför den resulterande hashen frÄn transaktionshashfÀltet med hashen som erhÄlls som ett resultat av hashning av denna transaktion (ignorerar hashfÀltet).

Transaktioner lÀggs till i blocket: github.com/Rusldv/bcstartup/blob/master/block/builder.go

Blockdatastrukturen Àr mer voluminös:

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 lagrar datatypen, noden anvÀnder den och skiljer blocket frÄn en transaktion eller annan data. För ett block Àr detta vÀrde 1.

BlockHeight lagrar höjden pÄ blocket.
TidsstÀmpel tidsstÀmpel.
HeaderSize Àr blockstorleken i byte.
PrevBlockHash Àr hashen för det föregÄende blocket och SelfBlockHash Àr hashen för det nuvarande.
TxsHash Àr en allmÀn hash av transaktioner.
MerkleRoot Àr roten till MerkletrÀdet.

LÀngre i fÀlten finns den publika nyckeln för skaparen av blocket, signaturen för skaparen, versionen av blocket, antalet transaktioner i blocket och dessa transaktioner sjÀlva.

LÄt oss titta pÄ dess metoder:
För att skapa ett block, anvÀnd block.NewBlock()-funktionen: NewBlock(prevBlockHash-strÀng, höjd int) *Block, som tar hashen för det föregÄende blocket och höjden för det skapade blocket i blockkedjan. Blocktypen stÀlls ocksÄ in frÄn typens paketkonstant:

b.DataType = types.BLOCK_TYPE.

Metoden AddTx(tx *transaction.TX) lÀgger till en transaktion i ett block.

Build()-metoden laddar in vÀrden i blockets fÀlt och genererar och stÀller in dess nuvarande hash.

Metoden ToBytesHeader() []byte konverterar blockhuvudet (utan transaktioner) till ett bytesegment.

StrÀngmetoden ToJSON() konverterar blocket till JSON-format i en strÀngrepresentation av data.

FromJSON(data []byte)-felmetoden laddar data frÄn JSON till en blockstruktur.

Check() bool-metoden genererar en blockhash och jÀmför den med den som anges i blockhashfÀltet.

StrÀngmetoden GetTxsHash() returnerar den totala hashen för alla transaktioner i blocket.

Metoden GetMerkleRoot() specificerar roten till Merkle-trÀdet för transaktioner i ett block.

Metoden Sign(privk string) signerar ett block med blockskaparens privata nyckel.

Metoden SetHeight(height int) skriver höjden pÄ blocket till blockstrukturfÀltet.

Metoden GetHeight() int returnerar höjden pÄ blocket som specificerats i motsvarande fÀlt i blockstrukturen.

Metoden ToGOBBytes() []byte kodar ett block i GOB-format och returnerar det som ett bytesegment.

FromGOBBytes(data []byte)-felmetoden skriver blockdata till blockstrukturen frÄn den skickade byte-delen i GOB-format.

StrÀngmetoden GetHash() returnerar hashen för det givna blocket.

StrÀngmetoden GetPrevHash() returnerar hashen för föregÄende block.

Metoden SetPublicKey(pubk string) skriver den publika nyckeln för blockskaparen till blocket.

SÄledes, med metoderna för Block-objektet, kan vi enkelt konvertera det till ett format för överföring över nÀtverket och spara till LevelDB-databasen.

Funktionerna i blockchain-paketet Àr ansvariga för att spara till blockchain: github.com/Rusldv/bcstartup/tree/master/blockchain

För att göra detta mÄste blocket implementera IBlock-grÀnssnittet:

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

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

}

Databasanslutningen skapas en gÄng nÀr paketet initieras i funktionen init():

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

CloseDB() Àr en wrapper för db.Cloce() - anropad efter att ha arbetat med paketfunktionerna för att stÀnga anslutningen till databasen.

Felfunktionen SetTargetBlockHash(hash-strÀng) skriver hashen för det aktuella blocket med nyckeln som anges av BLOCK_HASH-konstanten till databasen.

Funktionen GetTargetBlockHash() (strÀng, fel) returnerar hashen för det aktuella blocket som Àr lagrat i databasen.

Felfunktionen SetTargetBlockHeight(height int) skriver till databasen vÀrdet för blockkedjehöjden för noden med nyckeln specificerad av BLOCK_HEIGHT-konstanten.

Funktionen GetTargetBlockHeight() (int, error) returnerar höjden pÄ blockkedjan för en given nod, lagrad i databasen.

CheckBlock (block IBlock) bool-funktionen kontrollerar att ett block Àr korrekt innan det lÀggs till detta block i blockkedjan.

Felfunktionen AddBlock (block IBlock) lÀgger till ett block till blockkedjan.

Funktionerna för att hÀmta och visa block finns i filen explore.go i blockchain-paketet:

Funktionen GetBlockByHash(hash-strÀng) (*block.Block, error) skapar ett tomt blockobjekt, laddar in ett block i det frÄn databasen, vars hash skickades till det, och returnerar en pekare till det.

Skapandet av ett genesisblock utförs av Genesis()-felfunktionen frÄn filen genesis.go i blockchain-paketet.

NÀsta artikel kommer att prata om att ansluta klienter till en nod med hjÀlp av WebSocket-mekanismen.

KĂ€lla: will.com

Köp pĂ„litlig hosting för webbplatser med DDoS-skydd, VPS VDS-servrar đŸ”„ Köp pĂ„litlig webbhotell med DDoS-skydd, VPS VDS-servrar | ProHoster