>[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
- 六三序 服务运行
- 相关阅读
- 技术扩展