我如何在 Go 區塊鏈中設計區塊和交易

為了最終得到一個區塊鏈而不僅僅是一個資料庫,我們需要在我們的專案中添加 3 個重要元素:

  • 區塊資料結構及方法說明
  • 資料結構及交易方式說明
  • 區塊鏈功能將區塊保存在資料庫中,並透過它們的雜湊值或高度(或其他東西)找到它們。

我如何在 Go 區塊鏈中設計區塊和交易

這是關於產業區塊鏈的第二篇文章,第一篇 這裡.

還記得讀者就本系列上一篇文章向我提出的問題嗎?需要注意的是:在本例中,LevelDB 資料庫用於儲存區塊鏈數據,但沒有什麼可以阻止您使用任何其他資料庫,例如MySQL 。 現在讓我們來看看這個資料的結構。

讓我們從交易開始: github.com/Rusldv/bcstartup/blob/master/transaction/builder.go

這是它的資料結構:

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 方法將交易轉換為位元組切片。

Build() 和 Check() 中使用內部函數 preByteHash(bytes []byte) string 來使產生的交易雜湊與 JavaScript 應用程式產生的交易雜湊相容。

Build() 方法如下設定交易雜湊: tx.TxHash = preByteHash(tx.ToBytes())。

ToJSON() 字串方法將交易轉換為 JSON 字串。

FromJSON(data []byte) 錯誤方法從作為位元組切片傳遞的 JSON 格式載入交易。

Check() bool 方法會將交易雜湊欄位產生的雜湊值與對該交易進行雜湊處理(忽略雜湊欄位)所獲得的雜湊值進行比較。

交易被添加到區塊中: github.com/Rusldv/bcstartup/blob/master/block/builder.go

區塊資料結構更加龐大:

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() 函數:NewBlock(prevBlockHash string, height int) *Block,它採用前一個區塊的雜湊值以及區塊鏈中為創建的區塊設定的高度。 區塊類型也是從 types 包常數設定的:

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資料庫中。

區塊鏈包的函數負責保存到區塊鏈: github.com/Rusldv/bcstartup/tree/master/blockchain

為此,區塊必須實作 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()(字串,錯誤)函數傳回資料庫中儲存的目前區塊的雜湊值。

SetTargetBlockHeight(height int) 錯誤函數將具有由 BLOCK_HEIGHT 常數指定的鍵的節點的區塊鏈高度值寫入資料庫。

GetTargetBlockHeight() (int, error) 函數傳回給定節點的區塊鏈高度,儲存在資料庫中。

CheckBlock(block IBlock) bool 函數在將區塊新增到區塊鏈之前檢查該區塊的正確性。

AddBlock(block IBlock) 錯誤函數會為區塊鏈添加一個區塊。

檢索和查看區塊的函數位於區塊鏈包的explore.go檔案中:

GetBlockByHash(hash string) (*block.Block, error) 函數建立一個空區塊對象,從資料庫載入一個區塊到其中,該區塊的雜湊值被傳遞給它,並傳回一個指向它的指標。

創世區塊的創建是透過區塊鏈包的 genesis.go 檔案中的 Genesis() 錯誤函數執行的。

下一篇文章將討論使用 WebSocket 機制將客戶端連接到節點。

來源: www.habr.com

添加評論