用Go语言实现简单的区块链结构
参考:https://www.imooc.com/learn/1011
简介
实现简单的区块链结构,分别在CMD和HTTP服务中测试。没有涉及共识机制。
区块结构
一个区块结构应该包含区块的编号(Index)、区块创建时的时间戳(Timestamp)、上一个区块的哈希值(PrevBlockHash)、当前区块的哈希值(Hash)以及当前区块的数据(Data)。
当前区块的哈希值应该根据当前区块的编号、时间戳、数据,以及上一个区块的哈希值,共同计算得到,保证区块哈希值的唯一。这里区块索引为整型数值,哈希值为16进制表示的32为字符串,区块数据简略为字符串。
新建工程名为demochain,并且将项目放在$GOPATH/src目录下,以保证自定义包可用。项目一共两个核心文件,Block.go和Blockchain.go,分别对应区块和区块链操作。
首先定义区块结构体:
demochain/core/Block.go
然后需要一个方法,计算当前区块的哈希值:
这样就可以写生成新区块的方法,新区块的索引为上一个区块索引 + 1,上一个区块和数据为入参,当前区块哈希使用刚写的哈希计算函数进行计算:
最后缺的是创世区块,当区块链中没有区块,需要用这个区块来作为初始区块:
区块链结构
区块链由多个区块连接组成,基本的区块链结构简单表示为区块数组:
demochain/core/Blockchain.go
先写一个验证区块是否合法的功能性方法:
暂时从三个部分验证区块的合法性,区块索引、上一个区块的哈希和当前区块的哈希。
然后写append方法,用于将新区块添加到区块链:
如果区块链为空,则不验证有效性,直接添加。
类似创世区块,区块链也要有一个初始方法,生成新的区块链:
初始区块链需要将创世区块添加进去,作为第一个区块,以后的区块添加在其后。
最后一个方法是发送添加区块的请求,这个方法里创建一个新的区块,并执行将区块添加进链的操作:
此外还需要一个辅助方法,用于打印出区块的所有数据:
cmd测试
测试还是较简单的,创建区块链,添加区块,打印区块:
demochain/cmd/cmd.go
打印结果如:
HTTP服务测试
Go语言内置的http模块提供了便捷的启动HTTP服务的方法,先声明一个区块链变量,之后将对这个变量进行操作:
demochain/server/server.go
写一个run函数,用于处理http请求并启动监听端口的服务:
HandleFunc方法的第一个参数为请求路径,第二个参数是回调方法,用于处理请求。listenAndServe方法会在8023端口启动服务。
然后写两个回调函数的内容,这两个函数都接收两个参数,响应和请求,类似于Servlet的service方法:
最后写主方法运行程序,注意把包名改为main:
访问 http://localhost:8023/blockchain/get 查看区块链已有区块。
访问 http://localhost:8023/blockchain/write?data=smallyu 写入并读取所有区块链数据。