关注小众语言、AI,记录、分享技术点滴!

0%

golang 100行代码实现区块链原型

有人说今年(2018年)是区块链技术元年,作为一种新兴的技术,它不仅弯道超车盖过了人工智能、大数据的风头,而且发展速度更是一日千里。各大厂商都相继推出区块链服务,你可能觉得难以置信。不管你信不信,当你还在熟睡时,有一群人还在挑灯夜战。

在周未闲来无事,虽然之前网上也有各版本的区块链代码,还是动手用golang写了一下,简单实现了区块链的原型。代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
package main

import (
"crypto/sha256"
"encoding/json"
"fmt"
)

//Block 结构
type Block struct {
Index int
Timestamp string
Data string
PreviousHash string
Hash string
}

//CalculateHash 计算HASH
func (b *Block) CalculateHash() string {
s := fmt.Sprintf("%d%s%s%s", b.Index, b.PreviousHash, b.Timestamp, b.Data)
sum := sha256.Sum256([]byte(s))
return fmt.Sprintf("%x", sum)
}

//BlockChain 结构
type BlockChain struct {
Chain []*Block
}

//NewBlockChain 创建区块链
func NewBlockChain() *BlockChain {
bc := &BlockChain{}
bc.Chain = append(bc.Chain, bc.CreateGenesisBlock())
return bc
}

//CreateGenesisBlock 创建创世块
func (bc *BlockChain) CreateGenesisBlock() *Block {
b := &Block{
Index: 0,
Timestamp: "2018-01-01",
Data: "Genesis Block",
PreviousHash: "0",
}
b.Hash = b.CalculateHash()
return b
}

//GetLatestBlock 最新区块
func (bc *BlockChain) GetLatestBlock() *Block {
return bc.Chain[len(bc.Chain)-1]
}

//AddBlock 增加区块
func (bc *BlockChain) AddBlock(newBlock *Block) {
newBlock.Index = bc.GetLatestBlock().Index + 1
newBlock.PreviousHash = bc.GetLatestBlock().Hash
newBlock.Hash = newBlock.CalculateHash()
bc.Chain = append(bc.Chain, newBlock)
}

//IsChainValid 区块是否有效
func (bc *BlockChain) IsChainValid() bool {
for i := 1; i < len(bc.Chain); i++ {
currentBlock := bc.Chain[i]
previousBlock := bc.Chain[i-1]

if currentBlock.Hash != currentBlock.CalculateHash() {
return false
}

if currentBlock.PreviousHash != previousBlock.Hash {
return false
}
}
return true
}

func main() {
bc := NewBlockChain()
bc.AddBlock(&Block{Timestamp: "2018-02-01", Data: `{"amout":10}`})
bc.AddBlock(&Block{Timestamp: "2018-03-01", Data: `{"amout":20}`})
bc.AddBlock(&Block{Timestamp: "2018-04-01", Data: `{"amout":30}`})

blockchain, _ := json.MarshalIndent(bc, "", "\t")
fmt.Println(string(blockchain))

fmt.Println("is BlockChain valid ", bc.IsChainValid())
}