本篇博客的主要内容是用go写一个简单的Proof-of-Work共识机制,不涉及到网络通信环节,只是一个本地的简单demo。开发IDE用的是JB Golang。

整个项目的文件结构如下:

PoWdemo
│ main.go

├─Block
│ block.go

└─BlockChain
blockChain.go

首先是block.go文件,这个文件记录了有关区块的结构体以及对应的操作函数,详细代码如下:

package Block

import (
"crypto/sha256"
"encoding/hex"
"strconv"
"strings"
"time"
) //
// Block
// @Description: Block information
//
type Block struct{
Index int
TimeStamp string
Diff int
PreHash string
HashCode string
Nonce int
Data string
} //
// GenerateFirstBlock
// @Description : generating the genesis block
// @param data : data of genesis block
// @return Block : genesis block
//
func GenerateFirstBlock(data string) Block{
var firstBlock Block
firstBlock.Index = 1
firstBlock.TimeStamp = time.Now().String()
firstBlock.Diff = 4
firstBlock.Nonce = 0
firstBlock.Data = data
firstBlock.HashCode = generateBlockHashValue(firstBlock) return firstBlock
} //
// generateBlockHashValue
// @Description : calculate the hash of a block
// @param block : the aim block
// @return string : hash of the aim block
//
func generateBlockHashValue(block Block) string{
var hashData = strconv.Itoa(block.Index) + block.TimeStamp + strconv.Itoa(block.Diff) + strconv.Itoa(block.Nonce) +
block.Data
var hash = sha256.New()
hash.Write([]byte(hashData))
hashed := hash.Sum(nil)
return hex.EncodeToString(hashed)
} //
// GenerateNextBlock
// @Description : generating the next block
// @param data : data of next block
// @param preBlock : the previous block
// @return : Block
//
func GenerateNextBlock(data string, preBlock Block) Block{
var newBlock Block
newBlock.Data = data
newBlock.Index = preBlock.Index + 1
newBlock.TimeStamp = time.Now().String()
newBlock.Nonce = 0
newBlock.Diff = 6
newBlock.PreHash = preBlock.HashCode
newBlock.HashCode = PoW(newBlock.Diff, &newBlock) return newBlock
} //
// PoW
// @Description : calculate the hash value that meets the diff conditions
// @param diff : number of 0 in the prefix of the hash value
// @param block : aim block
// @return string : the hash of the aim block that meets the diff conditions
//
func PoW(diff int, block *Block) string{
for{
hash := generateBlockHashValue(*block)
if strings.HasPrefix(hash, strings.Repeat("0",diff)){
return hash
} else{
block.Nonce++
}
}
}

其次是blockChain.go文件,该文件记录了区块链所包含的信息,以及生成新区块的函数,详细代码如下:

package BlockChain

import (
"../Block"
"fmt"
) //
// Node
// @Description: blockchain
//
type Node struct{
NextNode *Node
BlockDate *Block.Block
} // the head node of the blockchain
var HeadNode *Node //
// CreatHeadNode
// @Description : creat the head node of blockchain
// @param block : the head block
// @return *Node : the pointer of head node
//
func CreatHeadNode(block *Block.Block) *Node{
var headNode *Node = new(Node)
headNode.NextNode = nil
headNode.BlockDate = block
HeadNode = headNode
return headNode
} //
// AddNode
// @Description : add a new node into the blockchain
// @param blockDate : block of the node
// @param preNode : the previous node
// @return *Node : the pointer of new node
//
func AddNode(blockDate *Block.Block, preNode *Node) *Node{
var newNode *Node = new(Node)
blockDate.PreHash = preNode.BlockDate.HashCode
newNode.BlockDate = blockDate
newNode.NextNode = nil
preNode.NextNode = newNode
fmt.Println(blockDate.HashCode)
return newNode
} //
// ShowBlockChain
// @Description : print the information of each block
// @param headNode : the pointer of head node
//
func ShowBlockChain(headNode *Node){
for node := headNode; node != nil; node = node.NextNode{
fmt.Println(node.BlockDate)
}
}

最后是main.go文件,对区块链进行初始化,并生成新的区块。

package main

import (
"./Block"
"./BlockChain"
"strconv"
) func main(){
var headBlock = Block.GenerateFirstBlock("This is the first block!")
var blockChain = BlockChain.CreatHeadNode(&headBlock) NodePtr := blockChain
for i := 0; i<10; i++{
var newBlock = Block.GenerateNextBlock("This is the " + strconv.Itoa(i) +" block!", headBlock)
NodePtr = BlockChain.AddNode(&newBlock, NodePtr)
} //BlockChain.ShowBlockChain(blockChain) }

以上就是本篇文章实现的简易Pow样例

【阿菜做实践】利用go语言写一个简单的Pow样例的更多相关文章

  1. ruby利用Zip Gem写一个简单的压缩和解压的小工具

    在UNIX下的我们怎么会沦落到用ruby写压缩和解压工具呢?直接上shell啊!但是请允许本猫这次可耻的用ruby来玩玩吧!其实ruby GEM中有很多压缩解压包,我选的是Zip,也许是因为名字符合K ...

  2. 用python语言写一个简单的计算器

    假如我们有这样一个式子: 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2 ...

  3. 用Go语言实现一个简单的聊天机器人

    一.介绍 目的:使用Go语言写一个简单的聊天机器人,复习整合Go语言的语法和基础知识. 软件环境:Go1.9,Goland 2018.1.5. 二.回顾 Go语言基本构成要素:标识符.关键字.字面量. ...

  4. 利用windows.h头文件写一个简单的C语言倒计时

    今天写一个简单的倒计时函数 代码如下: #include<stdio.h> #include<windows.h> int main() { int i; printf(&qu ...

  5. 分享:计算机图形学期末作业!!利用WebGL的第三方库three.js写一个简单的网页版“我的世界小游戏”

    这几天一直在忙着期末考试,所以一直没有更新我的博客,今天刚把我的期末作业完成了,心情澎湃,所以晚上不管怎么样,我也要写一篇博客纪念一下我上课都没有听,还是通过强大的度娘完成了我的作业的经历.(当然作业 ...

  6. 用C语言写一个“事件”的模拟程序

    源:用C语言写一个“事件”的模拟程序 Example.c //定义一个函数指针 func int (*func) (void); //调用该函数相当于触发了事件. //该事件触发后,会检查函数指针fu ...

  7. 利用SpringBoot+Logback手写一个简单的链路追踪

    目录 一.实现原理 二.代码实战 三.测试 最近线上排查问题时候,发现请求太多导致日志错综复杂,没办法把用户在一次或多次请求的日志关联在一起,所以就利用SpringBoot+Logback手写了一个简 ...

  8. 用C写一个简单的推箱子游戏(一)

    我现在在读大二,我们有一门课程叫<操作系统>,课程考查要求我们可以写一段程序或者写Windows.iOS.Mac的发展历程.后面我结合网上的资料参考,就想用自己之前简单学过的C写一关的推箱 ...

  9. (原创)如何使用boost.asio写一个简单的通信程序(一)

    boost.asio相信很多人听说过,作为一个跨平台的通信库,它的性能是很出色的,然而它却谈不上好用,里面有很多地方稍不注意就会出错,要正确的用好asio还是需要花一番精力去学习和实践的,本文将通过介 ...

随机推荐

  1. 快速排序平均时间复杂度O(nlogn)的推导

    快速排序作为随机算法的一种,不能通过常规方法来计算时间复杂度 wiki上有三种快排平均时间复杂度的分析,本文记录了一种推导方法. 先放快速排序的伪代码,便于回顾.参考 quicksort(int L, ...

  2. go微服务框架Kratos笔记(一)入门教程

    kratos简介 Kratos 一套轻量级 Go 微服务框架,包含大量微服务相关功能及工具 本文基于kratos v2.0.3,windows平台,其他系统平台均可借鉴参考 环境搭建 Golang开发 ...

  3. web页面自动化总结。selenium

    web自动化测试终篇:总结我理解的ui自动化,整理归纳: https://blog.csdn.net/CCGGAAG/article/details/89669592 web页面自动化知识点 1.we ...

  4. 面试官问我Redis集群,我真的是

    面试官:聊下Redis的分片集群,先聊 Redis Cluster好咯? 面试官:Redis Cluser是Redis 3.x才有的官方集群方案,这块你了解多少? 候选者:嗯,要不还是从基础讲起呗? ...

  5. [loj3285]Circus

    将奶牛的状态用序列$\{a_{1},a_{2},...,a_{m}\}$来描述,其中$a_{i}$表示第$i$头奶牛的位置(奶牛数量为$m$) 下面,先来考虑对于某个特定的$m$如何处理: 对于一条简 ...

  6. [loj539]旅游路线

    考虑枚举加油的位置,当确定某次在第$i$个位置加油后,且下一次到$j$加油,那么$i$到$j$必然会选择不超过$c_{i}$条边且最长的路径,记作$d_{i,j}$ 如果能求出$d_{i,j}$,再设 ...

  7. react之react Hooks

    函数组件,没有 class 组件中的 componentDidMount.componentDidUpdate 等生命周期方法,也没有 State,但这些可以通过 React Hook 实现. Rea ...

  8. elasticsearch学习(1)

    下载解压,elasticsearch.bat启动 elasticsearch目录: bin 启动文件config 配置文件 log4j2 日志配置文件 jvm.options java虚拟机相关的配置 ...

  9. 多线程03.实现Runnable接口

    package chapter2; public class TicketWindowRun implements Runnable { private static final int MAX =5 ...

  10. 全面了解一致性哈希算法及PHP代码实现

    在设计一个分布式系统的架构时,为了提高系统的负载能力,需要把不同的数据分发到不同的服务节点上.因此这里就需要一种分发的机制,其实就是一种算法,来实现这种功能.这里我们就用到了Consistent Ha ...