10_BitCoin全攻略十_难度值
我们看下NewProofOfWork方法
func NewProofOfWork(block Block) (*ProofOfWork) {
targetStr := "0001000000000000000000000000000000000000000000000000000000000000"
bigIntTemp := big.Int{}
bigIntTemp.SetString(targetStr, 16)
pow := ProofOfWork{
block: block,
target: bigIntTemp,
}
return &pow
}
现在我们的难度值,
也就是target是写死的
那么实际上,
我们需要根据block的属性Bits
来推算出当前的难度值
那么我们来看
0000000000000000000000000000000000000000000000000000000000000001
这样的话,是1,
0000000000000000000000000000000000000000000000000000000000000010
这样的话,就是左移了一位,
也就是二进制4位
那么
1 0000000000000000000000000000000000000000000000000000000000000000
这样就是向左移动了256位,多出了一位
那么
1000000000000000000000000000000000000000000000000000000000000000
这样就是,先左256,再右4位
0100000000000000000000000000000000000000000000000000000000000000
这样就是,先左256,再右8位
0010000000000000000000000000000000000000000000000000000000000000
这样就是,先左256,再右12位
0001000000000000000000000000000000000000000000000000000000000000
这样就是,先左256,再右16位
所以
如果我们想表示
0001000000000000000000000000000000000000000000000000000000000000
或者
0000100000000000000000000000000000000000000000000000000000000000
就可以这样
1.定义一个数值1
2.向左移动256位
3.向右移动(Bits+1)*4位
也就是说
Bits为1,就是010000...就是1个零
Bits为2,就是001000...就是2个零
Bits为3,就是000100...就是3个零
接下来写下代码
bigIntTemp := big.NewInt(1)
bigIntTemp.Lsh(bigIntTemp, 256-(Bits+1)*4)
这样就ok了
然后我们看下完整代码
func NewProofOfWork(block Block) (*ProofOfWork) {
bits := uint(block.Bits)
bigIntTemp := big.NewInt(1)
bigIntTemp.Lsh(bigIntTemp, 256-(bits+1)*4)
pow := ProofOfWork{
block: block,
target: *bigIntTemp,
}
return &pow
}
然后是block.go文件
const bits = 3
func NewBlock(data []byte, prevBlockHash []byte) *Block {
timeStamp := uint64(time.Now().Unix())
block := Block{
PrevBlockHash: prevBlockHash,
Hash: nil,
Data: data,
Version: version,
MerkleRoot: nil,
TimeStamp: timeStamp,
Bits: bits,
Nonce: 0,
}
pow := NewProofOfWork(block)
nonce, hash := pow.Run()
block.Nonce = nonce
block.Hash = hash
return &block
}