golang[46]-区块链-比特币真实挖矿过程实现

jonson_jackson · · 1139 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

比特币真实挖矿过程实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
package main

import (
"bytes"
"encoding/binary"
"log"
"fmt"
"encoding/hex"
"crypto/sha256"
"strconv"
"math"
"math/big"
)

var (

maxnonce int32 = math.MaxInt32
)

type Block struct{
version int32
prevBlockHash []byte
merkleroot [] byte
hash []byte
time int32
bits int32
nonce int32

}



//将类型转化为了字节数组
func IntToHex(num int32) []byte{
buff := new(bytes.Buffer)
//binary.LittleEndian 小端模式
err:= binary.Write(buff,binary.LittleEndian,num)

if err!=nil{
log.Panic(err)
}

return buff.Bytes()

}


//将类型转化为了字节数组
func IntToHex2(num int32) []byte{
buff := new(bytes.Buffer)
//binary.LittleEndian 小端模式
err:= binary.Write(buff,binary.BigEndian,num)

if err!=nil{
log.Panic(err)
}

return buff.Bytes()

}
//字节反转
func ReverseBytes4(data []byte){
for i,j :=0,len(data) - 1;i<j;i,j = i+1,j - 1{
data[i],data[j] = data[j],data[i]
}
}
//序列化
func (block *Block) serialize() []byte{


result := bytes.Join(
[][]byte{
IntToHex(block.version),
block.prevBlockHash,
block.merkleroot,
IntToHex(block.time),
IntToHex(block.bits),
IntToHex(block.nonce)},
[]byte{},
)

return result

}



func main(){


//前一个区块的hash
prev,_ := hex.DecodeString("000000000000000016145aa12fa7e81a304c38aec3d7c5208f1d33b587f966a6")
ReverseBytes4(prev)
fmt.Printf("%x\n",prev)

//默克尔根
merkleroot,_ := hex.DecodeString("3a4f410269fcc4c7885770bc8841ce6781f15dd304ae5d2770fc93a21dbd70d7")
ReverseBytes4(merkleroot)
fmt.Printf("%x\n",merkleroot)

//初始化区块
block := &Block{
2,
prev,
merkleroot,
[]byte{},
1418755780,
404454260,
0,
}


//目标hash
//fmt.Printf("targethash:%x",CalculateTargetFast(IntToHex2(block.bits)))
targetHash:=CalculateTargetFast(IntToHex2(block.bits))

//目标hash转换为bit.int
var tartget big.Int
tartget.SetBytes(targetHash)

//当前hash
var currenthash big.Int


//一直计算到最大值, block.nonce的值不断变化
for  block.nonce < maxnonce{


//序列化,block.nonce的值不断变化带来序列化的变化
data:= block.serialize()
//double hash
fitstHash := sha256.Sum256(data)
secondhash := sha256.Sum256(fitstHash[:])

//反转
ReverseBytes4(secondhash[:])
fmt.Printf("nonce:%d,  currenthash:%x\n",block.nonce,secondhash)
currenthash.SetBytes(secondhash[:])
//比较
if currenthash.Cmp(&tartget) == -1{
break
}else{
block.nonce++
}
}

}


//18   1B7B74

//计算困难度
func CalculateTargetFast(bits []byte) []byte{

var result []byte
//第一个字节  计算指数
exponent := bits[:1]
fmt.Printf("%x\n",exponent)

//计算后面3个系数
coeffient:= bits[1:]
fmt.Printf("%x\n",coeffient)


//将字节,他的16进制为"18"  转化为了string "18"
str:= hex.EncodeToString(exponent)  //"18"
fmt.Printf("str=%s\n",str)
  //将字符串18转化为了10进制int64 24
exp,_:=strconv.ParseInt(str,16,8)

fmt.Printf("exp=%d\n",exp)
//拼接,计算出目标hash
result  = append(bytes.Repeat([]byte{0x00},32-int(exp)),coeffient...)
result  =  append(result,bytes.Repeat([]byte{0x00},32-len(result))...)


return result
}

image.png


有疑问加站长微信联系(非本文作者)

本文来自:51CTO博客

感谢作者:jonson_jackson

查看原文:golang[46]-区块链-比特币真实挖矿过程实现

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1139 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传