>[success] # 一條簡單的區塊鏈
>[info] ### 區塊
- 區塊鏈首先要有區塊, 區塊里存放著交易相關等數據
- 在本節中我們弄一個簡單的區塊, 僅僅包含最關鍵的信息,其數據結構在go語言定義如下:
```go
type Block struct {
Timestamp int64 //時間戳
Data []byte //內容
PrevBlockHash []byte //上一個區塊的Hash
Hash []byte //當前區塊的Hash
}
```
- 其中Hash計算如下
```go
Hash = SHA256(PrevBlockHash + Timestamp + Data)
```
>[info] ### 區塊鏈
- 將一個個區塊連接起來組成區塊鏈
```go
type Blockchain struct {
blocks []*Block //區塊的切片即區塊鏈
}
```
>[warning] ### 一條簡單的區塊鏈
- 通過區塊和區塊鏈實現一條簡單的區塊鏈
```go
package main
import (
"bytes"
"crypto/sha256"
"fmt"
"strconv"
"time"
)
//區塊
type Block struct {
Timestamp int64
PrevBlockHash []byte
Hash []byte
Data []byte
}
//區塊鏈
type BlockChain struct {
blocks []*Block
}
func main() {
// 創建一個有創世塊的鏈
blockchain := NewBlockChain()
//添加新的塊
blockchain.AddBlock("第二個塊的內容")
blockchain.AddBlock("第三個塊的內容")
//遍歷塊
for _, block := range blockchain.blocks {
fmt.Printf("Timestamp: %s\n", time.Unix(block.Timestamp, 0).Format("2006-01-02 03:04:05"))
fmt.Printf("Prev hash: %x\n", block.PrevBlockHash)
fmt.Printf("Data: %s\n", block.Data)
fmt.Printf("Hash: %x\n", block.Hash)
fmt.Println()
}
}
func NewBlock(data string, prevBlockHash []byte) *Block {
block := &Block{
Timestamp: time.Now().Unix(),
PrevBlockHash: prevBlockHash,
Data: []byte(data),
Hash: []byte{},
}
//設置當前塊Hash
block.SetHash()
return block
}
// Hash = sha256(PrevBlockHash + Data + Timestamp)
func (b *Block) SetHash() {
timestamp := []byte(strconv.FormatInt(b.Timestamp, 10))
headers := bytes.Join([][]byte{b.PrevBlockHash, b.Data, timestamp}, []byte{})
hash := sha256.Sum256(headers)
b.Hash = hash[:]
}
//創世塊
func NewGenesisBlock() *Block {
return NewBlock("創世塊", []byte{})
}
//創世鏈
func NewBlockChain() *BlockChain {
return &BlockChain{[]*Block{NewGenesisBlock()}}
}
//添加塊
func (blockchain *BlockChain) AddBlock(data string) {
prevBlock := blockchain.blocks[len(blockchain.blocks)-1] //獲取上一個區塊的Hash
newBlock := NewBlock(data, prevBlock.Hash)
blockchain.blocks = append(blockchain.blocks, newBlock) //把當前塊添加到區塊鏈上
}
```
>[danger] ### 效果圖
```
Timestamp: 2020-01-07 17:14:43
Prev hash:
Data: 創世塊
Hash: cf774fdc758cbb90e28cf053401927576a7350f778b60631112ce6fc074a278a
Timestamp: 2020-01-07 17:14:43
Prev hash: cf774fdc758cbb90e28cf053401927576a7350f778b60631112ce6fc074a278a
Data: 第二個塊的內容
Hash: 3dd326874c10708e299c649760ed93689670a0d4fbeecd0a20755e0cbc9aded1
Timestamp: 2020-01-07 17:14:43
Prev hash: 3dd326874c10708e299c649760ed93689670a0d4fbeecd0a20755e0cbc9aded1
Data: 第三個塊的內容
Hash: 5a2aaa1c443453717cbb92a85893c9600e2166555428a1d5714bf742842bb6cd
```
- 第一節 一條簡單的區塊鏈
- 第二節 工作量證明(區塊Hash)
- 第三節
- 三一序 數據持久化
- 三二序 源碼
- 3.1 block.go
- 3.2 blockchain.go
- 3.3 cli.go
- 3.4 commands.go
- 3.5 main.go
- 3.6 proofofwork.go
- 三三序 服務運行
- 第四節
- 四一序 交易1(UTXO模型)
- 四二序 源碼
- 4.1 utils.go
- 4.2 block.go
- 4.3 blockchain.go
- 4.4 cli.go
- 4.5 main.go
- 4.6 proofofwork.go
- 4.7 transaction.go
- 四三序 服務運行
- 第五節
- 五一序 錢包地址
- 五二序 源碼
- 5.1 wallet.go
- 5.2 base58.go
- 5.3 block.go
- 5.4 blockchain.go
- 5.5 cli.go
- 5.6 main.go
- 5.7 proofofwork.go
- 5.8 transaction.go
- 5.9 utils.go
- 五三序 服務運行
- 第六節
- 六一序 交易2 (Merkle樹)
- 六二序 源碼
- 6.1 wallet.go
- 6.2 base58.go
- 6.3 block.go
- 6.4 blockchain.go
- 6.5 cli.go
- 6.6 main.go
- 6.7 merkletree.go
- 6.8 proofofwork.go
- 6.9 transaction.go
- 6.10 utils.go
- 6.11 utxoset.go
- 六三序 服務運行
- 相關閱讀
- 技術擴展