-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathproofofwork.go
100 lines (81 loc) · 2.38 KB
/
proofofwork.go
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
package main
import (
"bytes"
"crypto/sha256"
"fmt"
"math/big"
)
const Bits = 8 //小数位移动4位 4*4 2位 2*4
//POW
type ProofOfWork struct {
block *Block
target *big.Int
}
func NewProofOfWork(block *Block) *ProofOfWork {
pow := ProofOfWork{
block: block,
}
//定义难度值 难度值应该是推导出来的为了简化我们先固定 后续再推导
//targetStr := "0010000000000000000000000000000000000000000000000000000000000000" //64个数
// SetString : 把string转成big.int类型 SetBytes : 把bytes转成big.int类型 []byte
//var tmp big.Int
//tmp.SetString(targetStr,16)
//pow.target = &tmp
//程序推导难度值, 推导前导为3个难度值
// 0001000000000000000000000000000000000000000000000000000000000000
//初始化 64个数*4=256位
// 0000000000000000000000000000000000000000000000000000000000000001
//向左移动, 256位
//1 0000000000000000000000000000000000000000000000000000000000000000
//向右移动, 四次,一个16进制位代表4个2进制(f:1111)
//向右移动16位
//0 0001000000000000000000000000000000000000000000000000000000000000
// 创建 0000000000000000000000000000000000000000000000000000000000000001
bigTemp := big.NewInt(1)
// 向左移动, 256位
//1 0000000000000000000000000000000000000000000000000000000000000000
// 再向右移动 向右移动位置*4位
bigTemp.Lsh(bigTemp,256-Bits)
pow.target = bigTemp
return &pow
}
//这是pow的运算函数,为了获取挖矿的随机数 返回值:Hash,Nonce
func (pow *ProofOfWork) Run() ([]byte,uint64){
//block := pow.block
var nonce uint64 //默认为0
var hash [32]byte
for{
fmt.Printf("Pow运算:%x\r",hash)
hash = sha256.Sum256(pow.prepareData(nonce))
var tmp big.Int
tmp.SetBytes(hash[:])
if tmp.Cmp(pow.target) == -1{
fmt.Printf("挖矿成功 Nonce:%d Hash:%x\n",nonce,hash)
break
}else{
nonce++
}
}
return hash[:],nonce
}
func (pow *ProofOfWork) prepareData(Nonce uint64) []byte {
block := pow.block
tmp := [][]byte{
uintToByte(block.Version),
block.PrevHash,
block.MarKleRoot,
uintToByte(block.TimeStamp),
uintToByte(block.Difficult),
uintToByte(Nonce),
}
value := bytes.Join(tmp,[]byte{})
return value
}
func (pow *ProofOfWork) IsValid() bool{
//校验工作量证明
data := pow.prepareData(pow.block.Nonce)
hash := sha256.Sum256(data)
var tmp big.Int
tmp.SetBytes(hash[:])
return tmp.Cmp(pow.target) == -1
}