1.新建main.go文件
package main
import (
"bufio"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"log"
"math/rand"
"net"
"os"
"strconv"
"sync"
"time"
"github.com/davecgh/go-spew/spew" //spew包将区块链输出到终端
"github.com/joho/godotenv" //godotenv从前面的.env文件中读取配置信息
)
// Block represents each 'item' in the blockchain
type Block struct {
Index int
Timestamp string
BPM int
Hash string
PrevHash string
Validator string //由原先的difficulty改为了现在validator,即记账节点的地址
}
// Blockchain is a series of validated Blocks
var Blockchain []Block
var tempBlocks []Block
// tempBlocks是临时存储单元,在区块被选出来并添加到BlockChain之前,临时存储在这里
// candidateBlocks handles incoming blocks for validation
var candidateBlocks = make(chan Block)
//chan建立的是一个fifo队列,fifo先进先出
//candidateBlocks 是 Block 的通道,任何一个节点在提出一个新块时都将它发送到这个通道
// announcements broadcasts winning validator to all nodes
var announcements = make(chan string)
// announcements也是一个通道,主Go TCP服务器将向所有节点广播最新的区块链
var mutex = &sync.Mutex{
}
//是一个标准变量,允许我们控制读/写和防止数据竞争
// validators keeps track of open validators and balances
var validators = make(map[string]int)
//validators 是节点的存储地址,同时也会保存每个节点持有的令牌数
//calculateBlockHash函数将一个block的所有字段连接到一起后,再调用 calculateHash 将字符串进行求hash。
// SHA256 hasing
// calculateHash is a simple SHA256 hashing function
func calculateHash(s string) string {
h := sha256.New()
h.Write([]byte(s))
hashed := h.Sum(nil)
return hex.EncodeToString(hashed)
}
//calculateBlockHash returns the hash of all block information
func calculateBlockHash(block Block) string {
record := string(block.Index) + block.Timestamp + string(block.BPM) + block.PrevHash
return calculateHash(record)
}
//与前一个区块的hash值,生成区块
func generateBlock(oldBlock Block, BPM int, address string) (Block, error) {
var newBlock Block
t := time.Now()
newBlock.Index = oldBlock.Index + 1
newBlock.Timestamp