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).

Detta Àr den andra artikeln om blockchain för industrin; den första .
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:
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:
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:
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
