forked from blkchain/blkchain
-
Notifications
You must be signed in to change notification settings - Fork 0
/
uint256.go
61 lines (53 loc) · 1.34 KB
/
uint256.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
package blkchain
import (
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
)
// We're sticking with value rather than pointer for now, we think it's
// faster and safer. TODO: is it?
type Uint256 [32]byte
func (u Uint256) String() string {
for i := 0; i < 16; i++ {
u[i], u[31-i] = u[31-i], u[i]
}
return hex.EncodeToString(u[:])
}
// TODO This may be wrong, do we want this here?
func (u Uint256) MarshalJSON() ([]byte, error) {
return json.Marshal(u.String())
}
// sql.Scanner so that pq can scan these values from postgres
func (u *Uint256) Scan(value interface{}) error {
if b, ok := value.([]byte); !ok {
return fmt.Errorf("Unexpected type: %T", value)
} else {
copy(u[:], b)
}
return nil
}
// NB: we interpret this as little-endian. Traditionally Bitcoin
// transaction ids are printed in big-endian, i.e. reverse of this.
func ShaSha256(b []byte) Uint256 {
first := sha256.Sum256(b)
return sha256.Sum256(first[:])
}
func Uint256FromBytes(from []byte) Uint256 {
var result Uint256
copy(result[:], from)
return result
}
func Uint256FromString(from string) (Uint256, error) {
if len(from) != 32*2 {
return Uint256{}, fmt.Errorf("Incorrect length.")
}
b, err := hex.DecodeString(from)
if err != nil {
return Uint256{}, err
}
for i := 0; i < 16; i++ {
b[i], b[31-i] = b[31-i], b[i]
}
return Uint256FromBytes(b), nil
}