本篇博客的主要内容是用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. MySQL 各版本连接驱动字符串

    绪论 MySQL版本与连接驱动的版本有严格的对应关系,所以在这里记录一下 MySQL 5.7 jdbc.drive=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql: ...

  2. python将字符串转换成对应的python数据类型--eval和json.loads(),json.dumps()

    eval()和json.loads() 都可以将字符串转换成对应的python数据类型,举个字典的例子,同样适合其他数据类型元组.列表.集合. In [3]: ss = '{"a" ...

  3. [atARC066F]Contest with Drinks Hard

    先不考虑修改,那么很明显即对于每一个极长的的区间,若其长度为$l$,有${l+1\choose 2}$的贡献 考虑dp去做,即$f_{i}$表示前$i$个数最大的答案,则$$f_{i}=\max(\m ...

  4. [bzoj1178]会议中心

    考虑用f[i][j]表示以i为起点(i是时间,所以要离散)选$2^j$条线段(这里不是时间)最小的终点,预处理用倍增的方式来求即可预处理出这个数组后,就可以很快的求出在$[l,r]$的时间内最多能选多 ...

  5. WinRAR下载

    https://www.win-rar.com 垃圾7Z有的解压不了.

  6. 什么是JIT?

    目录 什么是JIT? 为什么HotSpot虚拟机要使用解释器与编译器并存的架构? 编译的时间开销 什么是JIT? 1.动态编译(dynamic compilation)指的是"在运行时进行编 ...

  7. 洛谷 P3270 - [JLOI2016]成绩比较(容斥原理+组合数学+拉格朗日插值)

    题面传送门 考虑容斥.我们记 \(a_i\) 为钦定 \(i\) 个人被 B 神碾压的方案数,如果我们已经求出了 \(a_i\) 那么一遍二项式反演即可求出答案,即 \(ans=\sum\limits ...

  8. 快速傅里叶变换(FFT)随笔

    终于学会了FFT,水一篇随笔记录一下 前置知识网上一大堆,这里就不多赘述了,直接切入正题 01 介绍FFT 这里仅指出FFT在竞赛中的一般应用,即优化多项式乘法 一般情况下,计算两个规模为$n$的多项 ...

  9. 什么是总线、总线的类型、局部总线、局部总线类型和什么是接口方式?什么是IDE?什么是SCSI?

    在安装电脑系统时,进行内核配置时涉及到各种总线类型,有必要了解一下什么是总线.总线的类型.局部总线.局部总线类型和接口方式. 1)总线总线是一组通信线.在机器内部, 各部件通过总线连接; 对于外部设备 ...

  10. Bootstrap实战 - 瀑布流布局

    讲 Bootstrap 基础的教程网上已经很多了,实际上 Bootstrap 中文网(bootcss.com)里的文档已经写的很详细了,但实战的案例却不多.这里用一些当前流行的网页布局为导向,使用 B ...