区块链是一种分布式账本技术,它通过加密算法和共识机制确保数据的不可篡改性和透明性。在本文中,我们将使用Go语言实现一个简单的区块链系统,帮助读者理解区块链的基本原理和结构。
在区块链中,数据以区块的形式存储,每个区块包含以下内容:
首先,我们定义一个区块结构体 Block
,包含上述提到的字段。
package main
import (
"crypto/sha256"
"encoding/hex"
"fmt"
"strconv"
"time"
)
type Block struct {
Index int
Timestamp string
Data string
PreviousHash string
Hash string
}
// 计算区块的哈希值
func calculateHash(block Block) string {
record := strconv.Itoa(block.Index) + block.Timestamp + block.Data + block.PreviousHash
h := sha256.New()
h.Write([]byte(record))
hashedBytes := h.Sum(nil)
return hex.EncodeToString(hashedBytes)
}
创世区块是区块链中的第一个区块,它的 PreviousHash
字段为空字符串。
func generateGenesisBlock() *Block {
return &Block{0, time.Now().String(), "Genesis Block", "", calculateHash(Block{0, time.Now().String(), "Genesis Block", "", ""})}
}
为了创建新区块,我们需要知道前一区块的哈希值,并将其作为新区块的 PreviousHash
字段。
func generateBlock(oldBlock Block, newData string) *Block {
newBlock := Block{
oldBlock.Index + 1,
time.Now().String(),
newData,
oldBlock.Hash,
"",
}
newBlock.Hash = calculateHash(newBlock)
return &newBlock
}
在将新区块添加到区块链之前,我们需要验证其有效性。这包括检查新区块的 PreviousHash
是否与前一区块的 Hash
匹配。
func isBlockValid(newBlock, oldBlock Block) bool {
if oldBlock.Index+1 != newBlock.Index {
return false
}
if oldBlock.Hash != newBlock.PreviousHash {
return false
}
if calculateHash(newBlock) != newBlock.Hash {
return false
}
return true
}
最后,我们将所有区块存储在一个切片中,并提供方法来添加新区块。
var Blockchain []Block
func addBlock(newBlock Block) {
if len(Blockchain) == 0 {
Blockchain = append(Blockchain, *generateGenesisBlock())
}
lastBlock := Blockchain[len(Blockchain)-1]
if isBlockValid(newBlock, lastBlock) {
Blockchain = append(Blockchain, newBlock)
} else {
fmt.Println("Error: New block is invalid")
}
}
func main() {
Blockchain = append(Blockchain, *generateGenesisBlock())
addBlock(*generateBlock(Blockchain[len(Blockchain)-1], "Transaction Data 1"))
addBlock(*generateBlock(Blockchain[len(Blockchain)-1], "Transaction Data 2"))
for _, block := range Blockchain {
fmt.Printf("Index: %d\n", block.Index)
fmt.Printf("Timestamp: %s\n", block.Timestamp)
fmt.Printf("Data: %s\n", block.Data)
fmt.Printf("Previous Hash: %s\n", block.PreviousHash)
fmt.Printf("Hash: %s\n", block.Hash)
fmt.Println()
}
}
以下是区块链操作的流程图:
sequenceDiagram participant User participant Blockchain User->>Blockchain: Request to add a new block Blockchain->>Blockchain: Validate the new block alt Block is valid Blockchain-->>User: Add block to the chain else Block is invalid Blockchain-->>User: Reject the block end
通过上述代码,我们实现了用Go语言构建的一个简单区块链。尽管这个实现非常基础,但它展示了区块链的核心概念,如区块结构、哈希计算和区块验证。