本篇内容介绍了“怎么用go语言区块链实战实现简单的区块与区块链”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
区块链实战
字节 | 字段 | 说明 |
---|---|---|
4 | 版本 | 区块版本号,表示本区块遵守的验证规则 |
32 | 父区块头哈希值 | 前一区块的Merkle树根的哈希值,同样采取SHA256计算 |
32 | Merkle根 | 该区块中交易的Merkle树根的哈希值,同样采用SHA256计算 |
4 | 时间戳 | 该区块产生的近似时间,精确到秒的UNIX时间戳,必须严格大于前11各区块的时间的中值,同时全节点也会拒接那些超过自己两个小时的时间戳的区块 |
4 | 难度目标 | 该区块工作量证明算法的难度目标,已经使用特定算法编码 |
4 | Nonce | 未来找到满足难度目标所设定的随机数,为了解决32为随机数在算力飞升的情况下不够用的问题,规定时间戳和coinbase交易信息均改变,以此扩展nonce的位数 |
注意:区块不存储hash值,节点接受区块后独立计算并存储在本地。
Version 1
区块相关:
定义一个区块的结构Block
a.区块头:6个字段
b.区块体:字符串表示data
提供一个创建区块的方法
NewBlock(参数)
区块链相关
定义一个区块链结构BlockChain
Block数组
提供一个创建BlockChain()的方法
NewBlockChain()
提供一个添加区块的方法
AddBlock(参数)
block.go文件
package mainimport ("bytes""crypto/sha256""time")//区块type Block struct {Version int64 //版本PerBlockHash []byte //前一个区块的hash值Hash []byte //当前区块的hash值,是为了简化代码MerKelRoot []byte //梅克尔根TimeStamp int64 //时间抽Bits int64 //难度值Nonce int64 //随机值//区块体Data []byte //交易信息}func NewBlock(data string ,prevBlockHash []byte) *Block {var block Blockblock = Block{Version: 1,PerBlockHash: prevBlockHash,//Hash: []byte{}, //区块不存储hash值,节点接受区块后独立计算并存储在本地。MerKelRoot: []byte{},TimeStamp: time.Now().Unix(),Bits: 1,Nonce: 1,Data: []byte(data),}block.SetHash() //填充Hashreturn &block}func (block *Block) SetHash() {// 源码里面是要传二维切片 func Join(s [][]byte, sep []byte) []bytetmp :=[][]byte{IntToByte(block.Version),block.PerBlockHash,block.MerKelRoot,IntToByte(block.TimeStamp),IntToByte(block.Bits),IntToByte(block.Nonce),}data:=bytes.Join(tmp,[]byte{}) //之后再计算hashhash := sha256.Sum256(data)block.Hash = hash[:] //变切片}//创始块func NewGensisBlock() *Block{return NewBlock("Genesis Block!",[]byte{})}
blockChain.go文件
package maintype BlockChain struct { blocks []*Block}func NewBlockChain() *BlockChain { block := NewGensisBlock() return &BlockChain{blocks:[]*Block{block}} //创建只有一个元素的区块链,初始化}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 mainimport ( "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 mainimport "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语言区块链实战实现简单的区块与区块链”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注编程网网站,小编将为大家输出更多高质量的实用文章!