POW共识算法-简单的模拟

标签:共识算法
发布时间:2018年10月16日 价值:20000.00 / 共识:32

生成区块代码

  1. package Block
  2. import (
  3. "strconv"
  4. "crypto/sha256"
  5. "encoding/hex"
  6. "time"
  7. "strings"
  8. "fmt"
  9. )
  10. //go代码模拟POW挖矿
  11. //区块结构体
  12. type Block struct {
  13. Index int //区块高度
  14. TImeStamp string //时间戳
  15. Diff int //挖矿难度,实际是动态变换
  16. PreHash string //上一个区块的hash值
  17. HashCode string //本身hash值
  18. Nonce int //改变生成hash值的值 控制挖矿是否成功
  19. Data string //交易信息
  20. }
  21. //生产区块hash值
  22. func GenerateBlockHashValue(block Block)string{
  23. //区块信息做拼接
  24. var hashData = strconv.Itoa(block.Index)+block.TImeStamp+
  25. block.Data+strconv.Itoa(block.Diff)+strconv.Itoa(block.Nonce)
  26. //hash算法
  27. var hash = sha256.New()
  28. hash.Write([]byte(hashData))
  29. //将字节转换成16进制的字符串
  30. return hex.EncodeToString(hash.Sum(nil))
  31. }
  32. //创始区块,第一个区块
  33. func GenerateFirstBlock(data string)Block{
  34. var firstBlock Block
  35. firstBlock.Index = 1
  36. firstBlock.TImeStamp = time.Now().String()
  37. firstBlock.Diff = 4
  38. firstBlock.Nonce = 0
  39. firstBlock.Data = data
  40. firstBlock.HashCode = GenerateBlockHashValue(firstBlock)
  41. return firstBlock
  42. }
  43. //产生新区块
  44. func GenerateNextBlock(data string,oldBlock Block)Block{
  45. var newBlock Block
  46. newBlock.Data = data
  47. newBlock.TImeStamp = time.Now().String()
  48. //暂时设定为0.nonce应该由矿工操作处理
  49. newBlock.Nonce = 0
  50. newBlock.PreHash = oldBlock.HashCode
  51. //暂时手动设定
  52. newBlock.Index = oldBlock.Index+1
  53. newBlock.Diff = oldBlock.Diff
  54. //POW成功后,带有0000的hash值
  55. Mine(newBlock.Diff,&newBlock)
  56. return newBlock
  57. }
  58. //挖矿,实际上寻找符合难度的hash值 diff:难度
  59. func Mine(diff int,block *Block){
  60. for {
  61. //生成hash
  62. var hash = GenerateBlockHashValue(*block)
  63. //判断是否符合难度 前面四个零
  64. if strings.HasPrefix(hash,strings.Repeat("0",diff)) {
  65. fmt.Println(hash)
  66. fmt.Println(block.Nonce)
  67. fmt.Println("挖矿成功")
  68. block.HashCode = hash
  69. return
  70. }else {
  71. fmt.Println(hash)
  72. block.Nonce ++
  73. }
  74. }
  75. }

组成区块链代码

  1. package BlockChain
  2. import (
  3. "fmt"
  4. "POW/Block"
  5. )
  6. //通过链表形式维护区块练中的业务
  7. type Node struct {
  8. NextNode *Node //指向下一个区块的指针
  9. Block *Block.Block //本身数据信息
  10. }
  11. //创建头节点
  12. func CreateHeaderNode(block *Block.Block)*Node{
  13. var headerNode *Node = new(Node)
  14. headerNode.NextNode = nil
  15. headerNode.Block = block
  16. return headerNode
  17. }
  18. //添加节点,当挖到框,添加区块
  19. func AddNode(block *Block.Block,node *Node)*Node{
  20. var newNode *Node = new(Node)
  21. newNode.NextNode = nil
  22. newNode.Block = block
  23. node.NextNode = newNode
  24. return newNode
  25. }
  26. //遍历链表
  27. func ShowNodes(node *Node){
  28. n:= node
  29. for {
  30. if n.NextNode == nil {
  31. fmt.Println(n.Block)
  32. break
  33. }else{
  34. fmt.Println(n.Block)
  35. n = n.NextNode
  36. }
  37. }
  38. }

测试

  1. package main
  2. import (
  3. "POW/Block"
  4. "POW/BlockChain"
  5. )
  6. func main() {
  7. var first = Block.GenerateFirstBlock("创始区块")
  8. var second = Block.GenerateNextBlock("第二个区块",first)
  9. //创建链表
  10. var header = BlockChain.CreateHeaderNode(&first)
  11. //将区块放入区块链中
  12. BlockChain.AddNode(&second,header)
  13. //遍历
  14. BlockChain.ShowNodes(header)
  15. }
  • 分享 收藏
0 条评论
  • 这篇文章暂无评论,赶紧评论一下吧~