部分代码(proofofwork.go文件中Run函数实现):
1 //这是pow的运算函数,为了获取挖矿的随机数,同时返回区块的哈希值 2 func (pow *ProofOfWork) Run() ([]byte, uint64) { 3 //1. 获取block数据 4 //2. 拼接nonce 5 //3. sha256 6 //4. 与难度值比较 7 //a. 哈希值大于难度值,nonce++ 8 //b. 哈希值小于难度值,挖矿成功,退出 9 10 var nonce uint64 11 12 //block := pow.block 13 14 var hash [32]byte 15 16 for ; ; { 17 18 fmt.Printf("%x\r", hash) 19 20 //data := block + nonce 21 hash = sha256.Sum256(pow.prepareData(nonce)) 22 23 //将hash(数组类型)转成big.int, 然后与pow.target进行比较, 需要引入局部变量 24 var bigIntTmp big.Int 25 bigIntTmp.SetBytes(hash[:]) 26 27 // -1 if x < y 28 // 0 if x == y 29 // +1 if x > y 30 // 31 //func (x *Int) Cmp(y *Int) (r int) { 32 // x y 33 if bigIntTmp.Cmp(pow.target) == -1 { 34 //此时x < y , 挖矿成功! 35 fmt.Printf("挖矿成功!nonce: %d, 哈希值为: %x\n", nonce, hash) 36 break 37 } else { 38 nonce ++ 39 } 40 } 41 42 return hash[:], nonce 43 } 44 45 //拼接block和nonce 46 func (pow *ProofOfWork) prepareData(nonce uint64) []byte { 47 block := pow.block 48 49 tmp := [][]byte{ 50 uintToByte(block.Version), 51 block.PrevBlockHash, 52 block.MerKleRoot, 53 uintToByte(block.TimeStamp), 54 uintToByte(block.Difficulity), 55 block.Data, 56 uintToByte(nonce), 57 } 58 59 data := bytes.Join(tmp, []byte{}) 60 return data 61 }
部分代码(使用pow更新block.go文件):
1 ackage main 2 3 import ( 4 "time" 5 ) 6 7 //定义区块结构 8 type Block struct { 9 //区块版本号 10 Version uint64 11 //前区块哈希 12 PrevBlockHash [] byte 13 //先填写为空,后续v4的时候使用 14 MerKleRoot [] byte 15 //从1970.1.1至今的秒数 16 TimeStamp uint64 17 //挖矿难度值,v2时使用 18 Difficulity uint64 19 //随机数,挖矿找的就是这个随机数 20 Nonce uint64 21 //数据,目前使用字节流,v4开始使用交易代替 22 Data [] byte 23 //当前区块哈希,区块中本来不存在,为了方便所以添加进来 24 Hash [] byte 25 } 26 27 const genesisInfo = "The Times 03/Jan/2009 Chancellor on brink of second bailout for banks" 28 29 //创建区块,对Block的每一个字段填充数据 30 func NewBlock(data string, prevBlockHash []byte) *Block{ 31 block := Block{ 32 Version:00, 33 34 PrevBlockHash: prevBlockHash, 35 36 MerKleRoot:[]byte{}, 37 38 TimeStamp:uint64(time.Now().Unix()), 39 //随便写,v2再调整 40 Difficulity:10, 41 //随便写,v2再调整 42 Nonce:10, 43 44 Data: []byte(data), 45 46 Hash: []byte{}, //先填充为空 47 } 48 49 ////V1之二版本添加实现hash输出 50 //block.SetHash() 51 52 //V2版本的工作量证明 53 pow := NewProofOfWork(&block) 54 hash,nonce := pow.Run() 55 56 block.Hash = hash 57 block.Nonce = nonce 58 59 return &block 60 } 61 62 //v2版本的工作量证明已经实现过了 63 ////为了生成区块哈希,实现一个简单的函数,来计算哈希值,没有随机值,没有难度值 64 //func (block *Block) SetHash() { 65 // //var data []byte 66 // ////类型是byte,而数据结构是uint64,所以构建一个工具类,将uint64转换为byte 67 // //data = append(data, uintToByte(block.Version)...) 68 // //data = append(data, block.PrevBlockHash...) 69 // //data = append(data, block.MerKleRoot...) 70 // //data = append(data, uintToByte(block.TimeStamp)...) 71 // //data = append(data, uintToByte(block.Difficulity)...) 72 // //data = append(data, uintToByte(block.Nonce)...) 73 // //data = append(data, block.Data...) 74 // 75 // //使用Join函数将二维数据便捷的转换为一维数据 76 // tmp := [][]byte{ 77 // uintToByte(block.Version), 78 // block.PrevBlockHash, 79 // block.MerKleRoot, 80 // uintToByte(block.TimeStamp), 81 // uintToByte(block.Difficulity), 82 // uintToByte(block.Nonce), 83 // block.Data, 84 // } 85 // 86 // data := bytes.Join(tmp,[]byte{}) 87 // 88 // hash /* [32]byte */:= sha256.Sum256(data) 89 // block.Hash = hash[:] 90 //}
显示效果:
原文:https://www.cnblogs.com/shizhe99/p/14076954.html