比特币相关的字节操作有点棘手,因为它们倾向于随意切换字节顺序。首先,我们需要取出代表的初始[]byte数组。
00000001c570c4764aadb3f09895619f549000b8b51a789e7f58ea750000709700000000103ca064f8c76c390683f8203043e91466a7fcc40e6ebc428fbcc2d89b574a864db8345b1b00b5ac00000000000000800000000000000000000000000000000000000000000000000000000000000000000000000000000080020000
然后,我们将数组的前一半分离出来,得到:
00000001c570c4764aadb3f09895619f549000b8b51a789e7f58ea750000709700000000103ca06 4f8c76c390683f8203043e91466a7fcc40e6ebc428fbcc2d8
接下来,我们需要交换一些字节。我们将每个4字节的片段中的字节顺序翻转,从而得到:
0100000076C470C5F0B3AD4A9F619598B80090549E781AB575EA587F977000000000000064A03C10396CC7F820F8830614E94330C4FCA76642BC6E0ED8C2BC8F
这是我们将用于计算中间状态的数组。现在,我们需要修改文件hash.go
,添加到type Hash interface
中:
Midstate() []byte
请修改文件sha256.go
,添加以下函数:
func (d *digest) Midstate() []byte {
var answer []byte
for i:=0;i<len(d.h);i++{
answer=append(answer[:], Uint322Hex(d.h[i])...)
}
return answer
}
在这里,Uint322Hex
将一个 uint32
变量转换成一个 []byte
变量。有了这些,我们就可以调用:
var h BitSHA.Hash = BitSHA.New()
h.Write(Str2Hex("0100000076C470C5F0B3AD4A9F619598B80090549E781AB575EA587F977000000000000064A03C10396CC7F820F8830614E94330C4FCA76642BC6E0ED8C2BC8F"))
log.Printf("%X", h.Midstate())
Str2Hex
函数将string
转换为[]byte
。结果如下:
69FC72E76DB0E764615A858F483E3566E42D56B2BC7A03ADCE9492887010EDA8
记住正确答案:
e772fc6964e7b06d8f855a6166353e48b2562de4ad037abc889294cea8ed1070
我们可以进行比较:
69FC72E7 6DB0E764 615A858F 483E3566 E42D56B2 BC7A03AD CE949288 7010EDA8
e772fc69 64e7b06d 8f855a61 66353e48 b2562de4 ad037abc 889294ce a8ed1070
因此,我们可以看到,我们只需要在每个4字节的片段中交换字节顺序,就可以得到比特币池和矿工使用的正确“中间状态”(直到它由于被弃用而不再需要)。
h.Sum([]byte{})
来返回结果。 - emickleih.Sum(nil)
也是有效的,@emicklei :-) - elimisteve