区块链挖矿系统源码有哪些,Go语言200行写区块链源代码分析

当前位置:首页 > NFT > 区块链挖矿系统源码有哪些,Go语言200行写区块链源代码分析

区块链挖矿系统源码有哪些,Go语言200行写区块链源代码分析

2022-05-07NFT86

Github上有一个Repo,是一个使用Go语言(golang),不到200行代码写的区块链源代码,准确的说是174行。原作者起了个名字是 Code your own blockchain in less than 200 lines of Go! 而且作者也为此写了一篇文章。https://medium.com/@mycoralhealth/code-your-own-blockchain-in-less-than-200-lines-of-go-e296282bcffc

这篇文章是一个大概的思路和代码的实现,当然还有很多代码的逻辑没有涉及,所以我就针对这不到200行的代码进行一个分析,包含原文章里没有涉及到的知识点,对Go语言,区块链都会有一个更深的认识。

所有的源代码都在这里:https://github.com/nosequeldeebee/blockchain-tutorial/blob/master/main.go

import?(????"crypto/sha256"????"encoding/hex"????"encoding/json"????"io"????"log"????"net/http"????"os"????"strconv"????"sync"????"time"????"github.com/davecgh/go-spew/spew"????"github.com/gorilla/mux"????"github.com/joho/godotenv")

在源代码的开头,是作者引入的一些包,有标准的,也有第三方的。像sha256,hex这些标准包是为了sha-256编码用的,其他还有启动http服务,打印日志的log,并发控制的sync,时间戳的time。

第三方包有三个,其中两个我都详细介绍过,相信大家不会陌生。

go-spew是一个变量结构体的调试利器,可以打印出变量结构体对应的数据和结构,调试非常方便

gorilla/mux是一个web路由服务,可以很简单的帮我们构建web服务。

不过目前用gin的比较多,也推荐使用gin https://github.com/gin-gonic/gin。

godotenv是一个读取配置文章的库,可以让我们读取.env格式的配置文件,比如从配置文件里读取IP、PORT等。不过目前配置文件还是推荐YAML和TOML,对应的第三方库是:

gopkg.in/yaml.v21https://github.com/BurntSushi/toml

既然要写一个区块链,那么肯定的有一个区块的实体,我们通过golang的struct来实现。

//?Block?represents?each?'item'?in?the?blockchaintype?Block?struct?{????Index?????int????Timestamp?string????BPM???????int????Hash??????string????PrevHash??string}

Block里包含几个字段:

Index 就是Block的顺序索引

Timestamp是生成Block的时间戳

BPM,作者说代表心率,每分钟心跳数

Hash是通过sha256生成的散列值,对整个Block数据的Hash

PrevHash 上一个Block的Hash,这样区块才能连在一起构成区块链

有了区块Block了,那么区块链就非常好办了。

//?Blockchain?is?a?series?of?validated?Blocksvar?Blockchain?[]Block

就是这么简单,一个Block数组就是一个区块链。区块链的构成关键在于Hash和PrevHash,通过他们一个个串联起来,就是一串Block,也就是区块链。因为相互之间通过Hash和PrevHash进行关联,所以整个链很难被篡改,链越长被篡改的成本越大,因为要把整个链全部改掉才能完成篡改的目的,这样的话,其他节点验证这次篡改肯定是不能通过的。

既然关键点在于Hash,所以我们要先算出来一个Block的数据的Hash,也就是对Block里的字段进行Hash,计算出一个唯一的Hash值。

//?SHA256?hasingfunc?calculateHash(block?Block)?string?{????record?:=?strconv.Itoa(block.Index)?+?block.Timestamp?+?strconv.Itoa(block.BPM)?+?block.PrevHash????h?:=?sha256.New()????h.Write([]byte(record))????hashed?:=?h.Sum(nil)????return?hex.EncodeToString(hashed)}

sha256是golang内置的sha256的散列标准库,可以让我们很容易的生成对应数据的散列值。从源代码看,是把Block的所有字段进行字符串拼接,然后通过sha256进行散列,散列的数据再通过hex.EncodeToString转换为16进制的字符串,这样就得到了我们常见的sha256散列值,类似这样的字符串8d969eef6ecad3c29a3a629280e686cf0c3f5d5a86aff3ca12020c923adc6c92。

Block的散列值被我们计算出来了,Block的Hash和PrevHash这两个字段搞定了,那么我们现在就可以生成一个区块了,因为其他几个字段都是可以自动生成的。

//?create?a?new?block?using?previous?block's?hashfunc?generateBlock(oldBlock?Block,?BPM?int)?Block?{????var?newBlock?Block????t?:=?time.Now()????newBlock.Index?=?oldBlock.Index?+?1????newBlock.Timestamp?=?t.String()????newBlock.BPM?=?BPM????newBlock.PrevHash?=?oldBlock.Hash????newBlock.Hash?=?calculateHash(newBlock)????return?newBlock}

因为区块链是顺序相连的,所以我们在生成一个新的区块的时候,必须知道上一个区块,也就是源代码里的oldBlock。另外一个参数BPM就是我们需要在区块里存储的数据信息了,这里作者演示的例子是心率,我们可以换成其他业务中想要的数据。

Index是上一个区块的Index+1,保持顺序;Timestamp通过time.Now()可以得到;Hash通过calculateHash方法计算出来。这样我们就生成了一个新的区块。

在这里作者并没有使用POW(工作量证明)这类算法来生成区块,而是没有任何条件的,这里主要是为了模拟区块的生成,演示方便。

区块可以生成了,但是生成的区块是否可信,我们还得对他进行校验,不能随便生成一个区块。在比特币(BitCoin)中校验比较复杂,这里作者采用了简单模拟的方式。

//?make?sure?block?is?valid?by?checking?index,?and?comparing?the?hash?of?the?previous?blockfunc?isBlockValid(newBlock,?oldBlock?Block)?bool?{????if?oldBlock.Index+1?!=?newBlock.Index?{????????return?false????}????if?oldBlock.Hash?!=?newBlock.PrevHash?{????????return?false????}????if?calculateHash(newBlock)?!=?newBlock.Hash?{????????return?false????}????return?true}

简单的对比Index,Hash是否是正确的,并且重新计算了一遍Hash,防止被篡改。

到了这里,关于区块链的代码已经全部完成了,剩下的就是把区块链的生成、查看等包装成一个Web服务,可以通过API、浏览器访问查看。因为作者这里没有实现P2P网络,所以采用的是WEB服务的方式。

//?create?handlersfunc?makeMuxRouter()?http.Handler?{????muxRouter?:=?mux.NewRouter()????muxRouter.HandleFunc("/",?handleGetBlockchain).Methods("GET")????muxRouter.HandleFunc("/",?handleWriteBlock).Methods("POST")????return?muxRouter}

通过mux定义了两个Handler,URL都是/,但是对应的Method是不一样的。

GET方法通过handleGetBlockchain函数实现,用于获取区块链的信息。

func?handleGetBlockchain(w?http.ResponseWriter,?r?*http.Request)?{????bytes,?err?:=?json.MarshalIndent(Blockchain,?"",?"??")????if?err?!=?nil?{????????http.Error(w,?err.Error(),?http.StatusInternalServerError)????????return????}????io.WriteString(w,?string(bytes))}

Blockchain是一个[]Block,handleGetBlockchain函数的作用是把Blockchain格式化为JSON字符串,然后显示出来。io.WriteString是一个很好用的函数,可以往Writer里写入字符串。更多参考 Go语言实战笔记(十九)| Go Writer 和 Reader

'POST'方法通过handleWriteBlock函数实现,用于模拟区块的生成。

func?handleWriteBlock(w?http.ResponseWriter,?r?*http.Request)?{????w.Header().Set("Content-Type",?"application/json")????//使用了一个Mesage结构体,更方便的存储BPM????var?msg?Message????//接收请求的数据信息,类似{"BPM":60}这样的格式????decoder?:=?json.NewDecoder(r.Body)????if?err?:=?decoder.Decode(&msg);?err?!=?nil?{????????respondWithJSON(w,?r,?http.StatusBadRequest,?r.Body)????????return????}????defer?r.Body.Close()????//控制并发,生成区块链,并且校验????mutex.Lock()????prevBlock?:=?Blockchain[len(Blockchain)-1]????newBlock?:=?generateBlock(prevBlock,?msg.BPM)????//校验区块链????if?isBlockValid(newBlock,?prevBlock)?{????????Blockchain?=?append(Blockchain,?newBlock)????????spew.Dump(Blockchain)????}????mutex.Unlock()????//返回新的区块信息????respondWithJSON(w,?r,?http.StatusCreated,?newBlock)}

以上代码我进行了注释,便于理解。主要是通过POST发送一个{"BPM":60}格式的BODY来添加区块,如果格式正确,那么就生成区块进行校验,合格了就加入到区块里;如果格式不对,那么返回错误信息。

用于控制并发的锁可以参考Go语言实战笔记(十七)| Go 读写锁

这个方法里有个Message结构体,主要是为了便于操作方便。

//?Message?takes?incoming?JSON?payload?for?writing?heart?ratetype?Message?struct?{????BPM?int}

返回的JSON信息,也被抽取成了一个函数respondWithJSON,便于公用。

func?respondWithJSON(w?http.ResponseWriter,?r?*http.Request,?code?int,?payload?interface{})?{????response,?err?:=?json.MarshalIndent(payload,?"",?"??")????if?err?!=?nil?{????????w.WriteHeader(http.StatusInternalServerError)????????w.Write([]byte("HTTP?500:?Internal?Server?Error"))????????return????}????w.WriteHeader(code)????w.Write(response)}

好了,快完成了,以上Web的Handler已经好了,现在我们要启动我们的Web服务了。

//?web?serverfunc?run()?error?{????mux?:=?makeMuxRouter()????//从配置文件里读取监听的端口????httpPort?:=?os.Getenv("PORT")????log.Println("HTTP?Server?Listening?on?port?:",?httpPort)????s?:=?&http.Server{????????Addr:???????????":"?+?httpPort,????????Handler:????????mux,????????ReadTimeout:????10?*?time.Second,????????WriteTimeout:???10?*?time.Second,????????MaxHeaderBytes:?1?<和原生的http.Server基本一样,应该比较好理解。mux其实也是一个Handler,这就是整个Handler处理链。现在我们就差一个main主函数来启动我们整个程序了。

//控制并发的锁var?mutex?=?&sync.Mutex{}func?main()?{????//加载env配置文件????err?:=?godotenv.Load()????if?err?!=?nil?{????????log.Fatal(err)????}????//开启一个goroutine生成一个创世区块????go?func()?{????????t?:=?time.Now()??蓑衣网小编??????genesisBlock?:=?Block{}????????genesisBlock?=?Block{0,?t.String(),?0,?calculateHash(genesisBlock),?""}????????spew.Dump(genesisBlock)????????mutex.Lock()????????Blockchain?=?append(Blockchain,?genesisBlock)????????mutex.Unlock()????}()????log.Fatal(run())}

整个main函数并不太复杂,主要就是加载env配置文件,开启一个go协程生成一个创世区块并且添加到区块链的第一个位置,然后就是通过run函数启动Web服务。

一个区块链都有一个创世区块,也就是第一个区块。有了第一个区块我们才能添加第二个,第三个,第N个区块。创世区块因为是第一个区块,所以它是没有PrevHash的。

终于可以运行了,假设我们设置的PORT是8080,现在我们通过go run main.go启动这个简易的区块链程序,就可以看到控制台输出的创世区块信息。然后我们通过浏览器打开http://localhost:8080也可以看到这个区块链的信息,里面只有一个创世区块。

如果我们要新增一个区块,通过curl或者postman,向http://localhost:8080 发送body格式为{"BPM":60}的POST的信息即可。然后在通过浏览器访问http://localhost:8080查看区块链信息,验证是否已经添加成功。

到这里,整个源代码的分析已经完了,我们看下这个简易的区块链涉及到多少知识:

sha256散列

字节到16进制转换

并发同步锁

Web服务

配置文件

后向式链表

结构体

JSON

……

蓑衣网-以上内容来自网络整理,不能代表本站立场,转载请注明出处。

本文链接:https://www.baoguzi.com/11856.html

区块链挖矿系统源码有哪些,Go语言200行写区块链源代码分析 | 分享给朋友:

相关文章

支付宝发行的NFT星云系列有哪些

支付宝发行的NFT星云系列有哪些

纸张尺寸 190*260 是什么尺寸 纸张尺寸 190*260?接近16开: 195×271。 复印店没有这种尺寸,可以使用16开纸张裁剪得到。 开本按照尺寸的大小,通常分三种类型:大型开本、中...

普通人如何玩NFT(普通人如何玩转抖音)

普通人如何玩NFT(普通人如何玩转抖音)

一个人怎么玩扑克? 一副牌去掉大小王和J K Q剩下40张,从上想下抽牌顺次横排,派成4列,同一列挨在一起的3张派如果能够凑成9 19或者29把它收起来放在手中牌的下面,同一列最下面的俩张可以和最上...

元宇宙发展详解,元宇宙不是游戏,发展需获得全社会认同

元宇宙发展详解,元宇宙不是游戏,发展需获得全社会认同

近段时间,元宇宙概念炙手可热。嗅觉最为灵敏的资本市场早已闻风而动,各路产业纷纷将自己嵌套进元宇宙的蓝图,甚至有机构卖“元宇宙网课”已收入百万。那么,元宇宙和我们的生活有什么关系?又会给现实世界带来哪些...

淘派数字藏品NFT平台(NFT数字藏品平台)

淘派数字藏品NFT平台(NFT数字藏品平台)

杭州淘派网络科技有限公司靠谱吗? NFT有线下商铺吗? NFT是线上时尚、潮品资讯社区吧,目前没有听说过有线下商铺。...

小狐狸钱包不显示NFT(小狐狸钱包不显示NFT)

小狐狸钱包不显示NFT(小狐狸钱包不显示NFT)

惠支付通知拦不显怎么办? 会支付通知栏不显示的话,应该是你没有开通相应的权限,你可以在设置中找到应用权限,授予一定的权限就可以了你好!关于这个会支付通知栏不显示,应该是你没有设置显示导航一类的,具体...

元宇宙字体有哪些,元宇宙字体设计图片详解

元宇宙字体有哪些,元宇宙字体设计图片详解

今天一清早就收到宇骐兄弟的微信,传来了他的硬笔书法作品。他是因为要参加单位的比赛,所以才写了这个书法作品。我猜他上一次“正儿八经”写字可能是N年以前的事了,说不定是大学时代甚至高中时代的事。宇骐兄弟的...

metaverse元宇宙分析,metaverse元宇宙代币及游戏解析

metaverse元宇宙分析,metaverse元宇宙代币及游戏解析

导语时至今日,元宇宙仍然代表了人们对互联网未来最切实际的遐想。“Hiro实际上并不在这里。他在一个计算机生成的宇宙中,能从护目镜中看到灯火通明的林荫大道,这条实际上并不存在的大路似乎是这个世界的中心,...

nft市场规模有哪些,2021年市场规模或超1700亿

nft市场规模有哪些,2021年市场规模或超1700亿

越来越多的艺术家、收藏家、画廊开始在NFT加密艺术平台上进行数字艺术品交易,苏富比、佳士得等拍卖行的加入更是让NFT加密艺术备受瞩目。12月20日晚,佳士得公布数据显示,其2021年的成交总额为71亿...

如何创造NFT收藏品(nft收藏品交易平台app)

如何创造NFT收藏品(nft收藏品交易平台app)

软装修与硬装修有哪些区别? 1、含义不同: (1)软装修:基本可以移动。软装是包括整体环境、空间美学、陈设艺术、生活功能、材质风格、意境体验、个性偏好、甚至风水文化等诸多方面的一种创造。软装从客观...

区块链哪个公司,2019年最具活力和影响力的区块链公司

区块链哪个公司,2019年最具活力和影响力的区块链公司

海外知名的区块链Cointelegraph发文盘点2019年最具活力和影响力的区块链公司,其中包括了币安、wink、rsk等项目,范围涉及公链、defi、区块链游戏等,具体如下:1. 加密货币交易所:...

区块链aitd最新分析,区块链aitd骗局靠谱吗

区块链aitd最新分析,区块链aitd骗局靠谱吗

众所周知,区块链技术作为一项重要的技术革命,已经正式进入到金融行业中。2016年以来,美国信托保险银行(AITD)联合斯坦福大学计算机学院共同开发跨法币全球金融结算系统及区块链保险系统。针对区块链技术...

如何发行自己的NFT(如何发行自己的货币)

如何发行自己的NFT(如何发行自己的货币)

独立游戏开发者要如何将自己的作品发布到Steam? 任何刚接触 Steam 并有意向本平台提交游戏的开发者或发行商应通过 Steam 青睐之光提交他们的游戏。 Steam 青睐之光是一个征集社区帮...

怎么理解NFT(怎么理解绿水青山就是金山银山)

怎么理解NFT(怎么理解绿水青山就是金山银山)

向量积怎么理解? 向量数量积是怎么来的,是W=F*S可是这里意义好像已经变了啊?这个又不是如果你非要理解成“功”,不是水平的话就理解为S方向上的功就行了,功也如果两个非零向量a、b的夹角为β(0≤β...

怎么购买NFT币(传奇4nft购买)

怎么购买NFT币(传奇4nft购买)

如何购买虚拟货币 在交易平台上就可以购买虚拟货币的,购买方法非常简单。流程如下: 首先,在一个数字货币交易平台上注册账号,进行实名认证,绑定手机号和银行卡(这是央行的要求); 其次,使用银行转账...

区块链怎么开发的,区块链项目开发的步骤详解

区块链怎么开发的,区块链项目开发的步骤详解

区块链是目前一个比较热门的新概念,蕴含了技术与金融两层概念。本文以联盟链为例,简单描述了实践一个联盟链的基本过程。作者 |陈浩,维优区块链CTO首先要确定这个区块链的类型,是公证型区块链还是价值型?公...