Hur jag designade block och transaktioner i min blockchain pÄ Go

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

  • Beskrivning av dataskstrukturen och metoderna för blocket
  • Beskrivning av dataskstrukturen och metoderna för transaktionen
  • Blockchain-funktioner som sparar block i databasen och hittar dem dĂ€r efter deras hash eller höjd (eller pĂ„ nĂ„got annat sĂ€tt).

Hur jag designade block och transaktioner i min blockchain pÄ Go

Detta Àr den andra artikeln om blockchain för industrin; den första ). Ett typiskt exempel pÄ anvÀndning:.

NÀr jag minns de frÄgor som mina lÀsare stÀllde efter den föregÄende artikeln i denna serie, bör det noteras: för lagring av blockchain-data anvÀnds i detta fall databasen LevelDB, men ingenting hindrar oss frÄn att anvÀnda vilken annan som helst, till exempel MySQL. Nu ska vi ta en titt pÄ strukturen för dessa data.

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

HÀr Àr dess dataskstrukur:

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
}

I TX lagras datatypen (för transaktionen 2), hash för denna transaktion, typen av sjÀlva transaktionen, tidsstÀmpeln samt ingÄngar och utgÄngar. IngÄngarna TxIn sparar hash för transaktionen som deras utgÄng refererar till, numret pÄ denna utgÄng och bytekoden, medan utgÄngarna TxOut lagrar ett vÀrde och ocksÄ bytekoden.

Nu ska vi se vilka ÄtgÀrder transaktionen kan utföra med sina data, det vill sÀga vi kommer att gÄ igenom metoderna.

För att skapa en transaktion anvÀnds funktionen transaction.NewTransaction(txtype byte) *TX.

Metoden AddTxIn(thattxhash []byte, txoutn int, code []byte) (*TxIn, error) lÀgger till en ingÄng till transaktionen.

Metoden AddTxOut(value int, data []byte) (*TxOut, error) lÀgger till en utgÄng till transaktionen.

Metoden ToBytes() []byte omvandlar transaktionen till en byte-array.

Den interna funktionen preByteHash(bytes []byte) string anvÀnds i Build() och Check() för att sÀkerstÀlla att den skapade hash:en av transaktionerna Àr kompatibel med hash:ar som genereras frÄn applikationer i JavaScript.

Metoden Build() stÀller in hash för transaktionen pÄ följande sÀtt: tx.TxHash = preByteHash(tx.ToBytes()).

Metoden ToJSON() string omvandlar transaktionen till en JSON-strÀng.

Metoden FromJSON(data []byte) error laddar transaktionen frÄn JSON-formatet som överförts som en byte-array.

Metoden Check() bool jÀmför den erhÄllna hash av fÀltet i transaktionens hash med den hash som erhÄllits genom hashning av denna transaktion (utan att ta hÀnsyn till hashfÀltet).

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

Dataskstrukturen för blocket Àr mer omfattande:

typ 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, enligt vilken noden avgör blocket frÄn transaktionen eller andra data. För block Àr detta vÀrde 1.

BlockHeight lagrar blockets höjd.
Timestamp Àr tidsstÀmpeln.
HeaderSize Àr blockets storlek i byte.
PrevBlockHash Àr hash av föregÄende block, medan SelfBlockHash Àr det aktuella.
TxsHash Àr den totala hash av transaktionerna.
MerkleRoot Àr roten i Merkle-trÀdet.

NÀst i fÀlten finns den offentliga nyckeln för blockskaparen, signaturen frÄn skaparen, blockets version, antal transaktioner i blocket och faktiskt dessa transaktioner.

LÄt oss titta pÄ dess metoder:
För att skapa ett block anvÀnds funktionen block.NewBlock(): NewBlock(prevBlockHash string, height int) *Block, som tar hash av föregÄende block och höjden instÀlld för det nyskapade blocket i blockkedjan. Typen av blocket anges frÄn konstanten i paketet types:

b.DataType = types.BLOCK_TYPE.

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

Metoden Build() laddar vÀrden i blockets fÀlt och genererar och stÀller in dess aktuella hash.

Metoden ToBytesHeader() []byte konverterar blockets rubrik (utan transaktioner) till en byte-slice.

Metoden ToJSON() string konverterar blocket till JSON-format i strÀngrepresentation.

Metoden FromJSON(data []byte) error laddar data frÄn JSON till blockstrukturen.

Metoden Check() bool genererar blockets hash och jÀmför med den angivna i blockets hash-fÀlt.

Metoden GetTxsHash() string returnerar den totala hash av alla transaktioner i blocket.

Metoden GetMerkleRoot() sÀtter roten i Merkle-trÀdet för transaktionerna i blocket.

Metoden Sign(privk string) signerar blocket med blockskaparen nyckel.

Metoden SetHeight(height int) skriver blockets höjd i blockstrukturens fÀlt.

Metoden GetHeight() int returnerar blockets höjd enligt det angivna fÀltet i blockstrukturen.

Metoden ToGOBBytes() []byte kodar blocket i GOB-format och returnerar det som en byte-slice.

Metoden FromGOBBytes(data []byte) error skriver blockets data i blockstrukturen frÄn den angivna byte-slicen i GOB-format.

Metoden GetHash() string returnerar hash av detta block.

Metoden GetPrevHash() string returnerar hash av föregÄende block.

Metoden SetPublicKey(pubk string) skriver den offentliga nyckeln för blockskaparen i blocket.

Genom metoderna för Block-objektet kan vi enkelt konvertera det till ett format för överföring över nÀtverket och lagring i LevelDB.

Funktionerna i paketet blockchain ansvarar för lagring i blockkedjan: github.com/Rusldv/bcstartup/tree/master/blockchain

För detta mÄste blocket implementera grÀnssnittet IBlock:

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

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

}

Anslutningen till databasen skapas en gÄng vid initialisering av paketet i funktionen init():

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

CloseDB() Ă€r en omslagsfunktion för db.Close() — anropas efter att ha arbetat med funktionerna i paketet för att stĂ€nga kopplingen till databasen.

Funktionen SetTargetBlockHash(hash string) error skriver hash för det aktuella blocket i databasen med nyckeln definierad av konstanten BLOCK_HASH.

Funktionen GetTargetBlockHash() (string, error) returnerar hash för det aktuella blocket som lagras i databasen.

Funktionen SetTargetBlockHeight(height int) error skriver vÀrdet för blockkedjans höjd för noden i databasen med nyckeln definierad av konstanten BLOCK_HEIGHT.

Funktionen GetTargetBlockHeight() (int, error) returnerar blockkedjans höjd för denna nod, lagrad i databasen.

Funktionen CheckBlock(block IBlock) bool kontrollerar blockets korrekthet innan det lÀggs till i blockkedjan.

Funktionen AddBlock(block IBlock) error lÀgger till blocket i blockkedjan.

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

Funktionen GetBlockByHash(hash string) (*block.Block, error) skapar ett tomt blockobjekt, laddar blocket med den angivna hashen frÄn databasen och returnerar en pekare till det.

Skapandet av genesis-blocket utförs av funktionen Genesis() error frÄn filen genesis.go i paketet blockchain.

I nÀsta artikel kommer vi att diskutera hur man ansluter till noden via WebSocket-mekanismen.

KĂ€lla: habr.com

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