go语言区块链实战实现简单的区块与区块链
程序员文章站
2022-03-01 16:28:50
目录区块链实战version 1区块相关:区块链相关区块链实战 字节 字段 说明...
区块链实战
字节 | 字段 | 说明 |
---|---|---|
4 | 版本 | 区块版本号,表示本区块遵守的验证规则 |
32 | 父区块头哈希值 | 前一区块的merkle树根的哈希值,同样采取sha256计算 |
32 | merkle根 | 该区块中交易的merkle树根的哈希值,同样采用sha256计算 |
4 | 时间戳 | 该区块产生的近似时间,精确到秒的unix时间戳,必须严格大于前11各区块的时间的中值,同时全节点也会拒接那些超过自己两个小时的时间戳的区块 |
4 | 难度目标 | 该区块工作量证明算法的难度目标,已经使用特定算法编码 |
4 | nonce | 未来找到满足难度目标所设定的随机数,为了解决32为随机数在算力飞升的情况下不够用的问题,规定时间戳和coinbase交易信息均改变,以此扩展nonce的位数 |
注意:区块不存储hash值,节点接受区块后独立计算并存储在本地。
version 1
区块相关:
1.定义一个区块的结构block
a.区块头:6个字段
b.区块体:字符串表示data
2.提供一个创建区块的方法
newblock(参数)
区块链相关
定义一个区块链结构blockchain
block数组
提供一个创建blockchain()的方法
newblockchain()
提供一个添加区块的方法
addblock(参数)
block.go文件
package main import ( "bytes" "crypto/sha256" "time" ) /* 1.定义一个区块的结构block a.区块头:6个字段 b.区块体:字符串表示data */ //区块 type block struct { version int64 //版本 perblockhash []byte //前一个区块的hash值 hash []byte //当前区块的hash值,是为了简化代码 merkelroot []byte //梅克尔根 timestamp int64 //时间抽 bits int64 //难度值 nonce int64 //随机值 //区块体 data []byte //交易信息 } /* 提供一个创建区块的方法 newblock(参数) */ func newblock(data string ,prevblockhash []byte) *block { var block block block = block{ version: 1, perblockhash: prevblockhash, //hash: []byte{}, //区块不存储hash值,节点接受区块后独立计算并存储在本地。 merkelroot: []byte{}, timestamp: time.now().unix(), bits: 1, nonce: 1, data: []byte(data), } block.sethash() //填充hash return &block } func (block *block) sethash() { // 源码里面是要传二维切片 func join(s [][]byte, sep []byte) []byte tmp :=[][]byte{ inttobyte(block.version), block.perblockhash, block.merkelroot, inttobyte(block.timestamp), inttobyte(block.bits), inttobyte(block.nonce), } data:=bytes.join(tmp,[]byte{}) //之后再计算hash hash := sha256.sum256(data) block.hash = hash[:] //变切片 } //创始块 func newgensisblock() *block{ return newblock("genesis block!",[]byte{}) }
blockchain.go文件
package main /* 1. 定义一个区块链结构blockchain block数组 */ type blockchain struct { blocks []*block } /* 2. 提供一个创建blockchain()的方法 newblockchain() */ func newblockchain() *blockchain { block := newgensisblock() return &blockchain{blocks:[]*block{block}} //创建只有一个元素的区块链,初始化 } /* 3. 提供一个添加区块的方法 addblock(参数) */ func (bc *blockchain)addblock(data string) { perblockhash := bc.blocks[len(bc.blocks)-1].hash //这一个区块的哈希是前一块的哈希值 block := newblock(data,perblockhash) bc.blocks = append(bc.blocks,block) }
utils.go文件
package main import ( "bytes" "encoding/binary" "fmt" "os" ) func inttobyte(num int64) []byte { //func write(w io.writer, order byteorder, data interface{}) error { var buffer bytes.buffer err := binary.write(&buffer, binary.bigendian, num) checkerr("inttobyte",err) return buffer.bytes() } func checkerr(position string,err error) { if err != nil { fmt.println("error ,pos:",position,err) os.exit(1) } }
main.go文件
package main import "fmt" func main() { bc := newblockchain() bc.addblock("a send b 1btc") bc.addblock("b send c 1btc") for _,block := range bc.blocks { fmt.printf("version : %d\n",block.version) fmt.printf("perblockhash : %x\n",block.perblockhash) fmt.printf("hash : %x\n",block.hash) fmt.printf("merkelroot : %x\n",block.merkelroot) fmt.printf("timestamp : %d\n",block.timestamp) fmt.printf("bits : %d\n",block.bits) fmt.printf("nonce : %d\n",block.nonce) fmt.printf("data : %s\n",block.data) } }
执行结果
以上就是go语言区块链实战实现简单的区块与区块链的详细内容,更多关于go语言实现区块与区块链的资料请关注其它相关文章!
上一篇: go语言区块链学习调用以太坊
下一篇: go语言区块链学习调用智能合约