-
Notifications
You must be signed in to change notification settings - Fork 0
/
mint.go
108 lines (94 loc) · 2.47 KB
/
mint.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
101
102
103
104
105
106
107
108
package umint
import (
"math/big"
)
type TxOut struct {
Value int64
PkScript []byte
}
type CoinStakeSource struct {
BlockTime int64
StakeModifier uint64
TxOffset uint32
TxTime int64
TxSha []byte
Outputs map[string]*TxOut
}
// BigToCompact converts a whole number N to a compact representation using
// an unsigned 32-bit number. The compact representation only provides 23 bits
// of precision, so values larger than (2^23 - 1) only encode the most
// significant digits of the number. See CompactToBig for details.
func BigToCompact(n *big.Int) uint32 {
// No need to do any work if it's zero.
if n.Sign() == 0 {
return 0
}
// Since the base for the exponent is 256, the exponent can be treated
// as the number of bytes. So, shift the number right or left
// accordingly. This is equivalent to:
// mantissa = mantissa / 256^(exponent-3)
var mantissa uint32
exponent := uint(len(n.Bytes()))
if exponent <= 3 {
mantissa = uint32(n.Bits()[0])
mantissa <<= 8 * (3 - exponent)
} else {
// Use a copy to avoid modifying the caller's original number.
tn := new(big.Int).Set(n)
mantissa = uint32(tn.Rsh(tn, 8*(exponent-3)).Bits()[0])
}
// When the mantissa already has the sign bit set, the number is too
// large to fit into the available 23-bits, so divide the number by 256
// and increment the exponent accordingly.
if mantissa&0x00800000 != 0 {
mantissa >>= 8
exponent++
}
// Pack the exponent, sign bit, and mantissa into an unsigned 32-bit
// int and return it.
compact := uint32(exponent<<24) | mantissa
if n.Sign() < 0 {
compact |= 0x00800000
}
return compact
}
func CompactToDiff(bits uint32) (diff float32) {
nShift := (bits >> 24) & 0xff
diff = float32(0x0000ffff) / float32(bits&0x00ffffff)
for ; nShift < 29; nShift++ {
diff *= 256.0
}
for ; nShift > 29; nShift-- {
diff /= 256.0
}
return
}
func IncCompact(compact uint32) uint32 {
mantissa := compact & 0x007fffff
neg := compact & 0x00800000
exponent := uint(compact >> 24)
if exponent <= 3 {
mantissa += uint32(1 << (8 * (3 - exponent)))
} else {
mantissa++
}
if mantissa >= 0x00800000 {
mantissa >>= 8
exponent++
}
return uint32(exponent<<24) | mantissa | neg
}
func DiffToTarget(diff float32) (target *big.Int) {
mantissa := 0x0000ffff / diff
exp := 1
tmp := mantissa
for tmp >= 256.0 {
tmp /= 256.0
exp++
}
for i := 0; i < exp; i++ {
mantissa *= 256.0
}
target = new(big.Int).Lsh(big.NewInt(int64(mantissa)), uint(26-exp)*8)
return
}