【阿菜做实践】利用go语言写一个简单的Pow样例
本篇博客的主要内容是用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样例的更多相关文章
- ruby利用Zip Gem写一个简单的压缩和解压的小工具
在UNIX下的我们怎么会沦落到用ruby写压缩和解压工具呢?直接上shell啊!但是请允许本猫这次可耻的用ruby来玩玩吧!其实ruby GEM中有很多压缩解压包,我选的是Zip,也许是因为名字符合K ...
- 用python语言写一个简单的计算器
假如我们有这样一个式子: 1 - 2 * ( (60-30 +(-40/5) * (9-2*5/3 + 7 /3*99/4*2998 +10 * 568/14 )) - (-4*3)/ (16-3*2 ...
- 用Go语言实现一个简单的聊天机器人
一.介绍 目的:使用Go语言写一个简单的聊天机器人,复习整合Go语言的语法和基础知识. 软件环境:Go1.9,Goland 2018.1.5. 二.回顾 Go语言基本构成要素:标识符.关键字.字面量. ...
- 利用windows.h头文件写一个简单的C语言倒计时
今天写一个简单的倒计时函数 代码如下: #include<stdio.h> #include<windows.h> int main() { int i; printf(&qu ...
- 分享:计算机图形学期末作业!!利用WebGL的第三方库three.js写一个简单的网页版“我的世界小游戏”
这几天一直在忙着期末考试,所以一直没有更新我的博客,今天刚把我的期末作业完成了,心情澎湃,所以晚上不管怎么样,我也要写一篇博客纪念一下我上课都没有听,还是通过强大的度娘完成了我的作业的经历.(当然作业 ...
- 用C语言写一个“事件”的模拟程序
源:用C语言写一个“事件”的模拟程序 Example.c //定义一个函数指针 func int (*func) (void); //调用该函数相当于触发了事件. //该事件触发后,会检查函数指针fu ...
- 利用SpringBoot+Logback手写一个简单的链路追踪
目录 一.实现原理 二.代码实战 三.测试 最近线上排查问题时候,发现请求太多导致日志错综复杂,没办法把用户在一次或多次请求的日志关联在一起,所以就利用SpringBoot+Logback手写了一个简 ...
- 用C写一个简单的推箱子游戏(一)
我现在在读大二,我们有一门课程叫<操作系统>,课程考查要求我们可以写一段程序或者写Windows.iOS.Mac的发展历程.后面我结合网上的资料参考,就想用自己之前简单学过的C写一关的推箱 ...
- (原创)如何使用boost.asio写一个简单的通信程序(一)
boost.asio相信很多人听说过,作为一个跨平台的通信库,它的性能是很出色的,然而它却谈不上好用,里面有很多地方稍不注意就会出错,要正确的用好asio还是需要花一番精力去学习和实践的,本文将通过介 ...
随机推荐
- 大一C语言学习笔记(8)---指针篇--动态内存是什么?与静态内存有什么区别?怎么使用动态内存,有什么需要注意的地方?
静态内存指的是在编译时系统自动给其分配的内存,运行结束后会自动释放:静态内存是在栈中分配的: 动态内存是我们程序员手动分配的内存,正常情况下,程序运行结束后,也不会自动释放,所以为了避免发生未知的错误 ...
- 【Azure 环境】用 PowerShell 调用 AAD Token, 以及调用Azure REST API(如资源组列表)
问题描述 PowerShell 脚本调用Azure REST API, 但是所有的API都需要进行权限验证.要在请求的Header部分带上Authorization参数,并用来对List Resour ...
- Python基础(普通函数及参数)
# def my_abs(x): # if not isinstance(x,(int,float)):#参数类型做检查,只允许整数和浮点数类型的参数.数据类型检查可以用内置函数isinstance( ...
- [uoj76]懒癌
为了方便,称患有懒癌的狗为"坏狗" 记$Q_{i}$为第$i$个人能观察的狗集合,$S$为坏狗集合,那么第$k$天第$i$个人能得到的信息有且仅有$S\ne \empty$.$S\ ...
- [hdu7035]Game
称区间$[i,j]$为普通区间,当且仅当$j-i\ge 3$且其操作两次内不会变为给定区间 结论:若$[i,j]$为普通区间,则$[i,j]$和$[i+1,j-1]$的状态( ...
- [bzoj4553]序列
记第i个位置有三个属性:1.ai表示原来的值:2.bi表示变成最大的值:3.ci表示变成最小的值.那么对于如果i在j的前面,那么必然有:$ai\le cj$且$bi\le aj$,那么令f[i]表示以 ...
- [bzoj3524]Couries
首先用到bzoj2456的做法,因为要求这个数出现次数超过了一半,如果其与不同的数两两相消的话最终一定会剩下自身(如果不保证存在可能会剩下别的,但保证存在了只会剩下自身),然后再用可持久化线段树维护即 ...
- [loj2478]林克卡特树
原题等价于选择恰好$k+1$条不相交(无公共点)的路径使得边权和最大 证明:对于原题中的最优解,一定包含了k条0边权的边(否则可以将未使用的边删掉,然后将这条路径的末尾与不在同一个连通块内的点连边), ...
- Java二次开发海康SDK-对接门禁机
写在最前 SDK版本:CH-HCNetSDKV6.1.6.45_build20210302_win64 参考文档:海康SDK使用手册_V6.1 对接测试设备型号:DS-K1T671M 设备序列号:E5 ...
- AT695 マス目
AT695 マス目 本题选自 DP 优化方法大杂烩 状压部分. 这个题很 nb.下文记 \(n=H\),\(m=W\). 对于每一列,如果只记录一个格子是否为黑色,那么发现它无法处理从右边绕到左边再绕 ...