赞
踩
先装
安装依赖软件**
Go 1.13 及以上(推荐) 打开你的终端并执行 $ go env -w GO111MODULE=on $ go env -w GOPROXY=https://goproxy.cn,direct 完成。 macOS 或 Linux 打开你的终端并执行 $ export GO111MODULE=on $ export GOPROXY=https://goproxy.cn 或者 $ echo "export GO111MODULE=on" >> ~/.profile $ echo "export GOPROXY=https://goproxy.cn" >> ~/.profile $ source ~/.profile 完成。 Windows 打开你的 PowerShell 并执行 C:\> $env:GO111MODULE = "on" C:\> $env:GOPROXY = "https://goproxy.cn"
继续在一遍当中的代码进行修改,不懂得看上一篇
func main() { //测试 随便写 //var firstBlock Block //firstBlock.Diff = 4 //firstBlock.Noce = 0 //firstBlock.PreHash = "0" //firstBlock.BMP = 1 //firstBlock.Index = 0 //firstBlock.HashCode = "0" //generateBlock(firstBlock, 1) //默认加载.env文件,内置名叫就教.env 所以新建的叫.env err := godotenv.Load() if err != nil { log.Fatal(err) } }
结果
新增代码
package main import ( "crypto/sha256" "encoding/hex" "encoding/json" "fmt" "github.com/davecgh/go-spew/spew" "github.com/gorilla/mux" "github.com/joho/godotenv" "io" "log" "net/http" "os" "strconv" "strings" "sync" "time" ) // 设置难度系数,设置为4 const diffculty = 4 // 定义区块 type Block struct { //区块高度 Index int //时间戳 Timestamp string //data,保存交易信息 BMP int //当前区块的哈希 HashCode string //上一个区块的哈希 PreHash string //前导0 个数Diff Diff int //随机值 Noce int } // 用数组去维护区块链 var Blockchain []Block // 声明个锁,以防止并发问题 var mutex = &sync.Mutex{} // 生成区块 func generateBlock(oldBlock Block, BMP int) Block { //声明个新区块 var newBlock Block newBlock.PreHash = oldBlock.HashCode newBlock.Timestamp = time.Now().String() //不能写死了 newBlock.Index = oldBlock.Index + 1 newBlock.BMP = BMP newBlock.Diff = diffculty //循环挖矿 for i := 0; ; i++ { //每挖一次,给Noce加1 newBlock.Noce++ hash := calculateHash(newBlock) fmt.Println(hash) //判断前导0 if isHashValid(hash, newBlock.Diff) { //一致 fmt.Println("挖矿成功") newBlock.HashCode = hash //将新的区块返回 return newBlock } } } // 按照规则生成一个Hash值 func calculateHash(block Block) string { record := strconv.Itoa(block.Index) + block.Timestamp + strconv.Itoa(block.Noce) + strconv.Itoa(block.BMP) + block.PreHash sha := sha256.New() sha.Write([]byte(record)) hashed := sha.Sum(nil) return hex.EncodeToString(hashed) } // 判断哈希值的前导0个数和难度系数是否一直 func isHashValid(hash string, difficulty int) bool { prefix := strings.Repeat("0", difficulty) //判断这个哈希值是否为这个前缀 return strings.HasSuffix(hash, prefix) } func main() { //测试 随便写 //var firstBlock Block //firstBlock.Diff = 4 //firstBlock.Noce = 0 //firstBlock.PreHash = "0" //firstBlock.BMP = 1 //firstBlock.Index = 0 //firstBlock.HashCode = "0" //generateBlock(firstBlock, 1) //默认加载.env文件,内置名叫就教.env 所以新建的叫.env err := godotenv.Load() if err != nil { log.Fatal(err) } go func() { //创世区块 genesisBlock := Block{} genesisBlock = Block{ Index: 0, Timestamp: time.Now().String(), BMP: 0, HashCode: calculateHash(genesisBlock), PreHash: "", Diff: diffculty, } //将区块添加到区块链 mutex.Lock() Blockchain = append(Blockchain, genesisBlock) mutex.Unlock() //格式化输出到控制台 spew.Dump(genesisBlock) }() //作为Http服务器的启动函数 log.Fatal(run()) } // 将run作为Http启动函数 func run() error { //声明一个回调函数,处理get还是Post mux := makeMuxRouter() httpAddr := os.Getenv("ADDR") log.Println("Listening on", os.Getenv("ADDR")) s := &http.Server{ Addr: ":" + httpAddr, Handler: mux, ReadTimeout: 10 * time.Second, WriteTimeout: 10 * time.Second, //设置个最大相应头 1mb MaxHeaderBytes: 1 << 20, } //监听服务打开 if err := s.ListenAndServe(); err != nil { return err } return nil } // 回调函数 func makeMuxRouter() http.Handler { muxRoter := mux.NewRouter() //get 读,post写的处理 muxRoter.HandleFunc("/", handGetBlockchain).Methods("GET") //写的操作post muxRoter.HandleFunc("/", handWriteBlock).Methods("POSt") return muxRoter } // 处理http的GET请求 // 查看区块链的信息 func handGetBlockchain(w http.ResponseWriter, r *http.Request) { //转json bytes, err := json.MarshalIndent(Blockchain, "", "\t") if err !=nil{ //服务器的错误 http.Error(w,err.Error(),http.StatusInternalServerError) return } io.WriteString(w,string(bytes)) }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。