-
Notifications
You must be signed in to change notification settings - Fork 174
/
codec.go
135 lines (116 loc) · 3.64 KB
/
codec.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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
// Go Substrate RPC Client (GSRPC) provides APIs and types around Polkadot and any Substrate-based chain RPC calls
//
// Copyright 2019 Centrifuge GmbH
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package types
import (
"bytes"
"encoding/hex"
"fmt"
"reflect"
"strings"
"github.com/centrifuge/go-substrate-rpc-client/v4/scale"
"golang.org/x/crypto/blake2b"
)
// Hexer interface is implemented by any type that has a Hex() function returning a string
type Hexer interface {
Hex() string
}
// Encode encodes `value` with the scale codec with passed EncoderOptions, returning []byte
func Encode(value interface{}) ([]byte, error) {
var buffer = bytes.Buffer{}
err := scale.NewEncoder(&buffer).Encode(value)
if err != nil {
return buffer.Bytes(), err
}
return buffer.Bytes(), nil
}
// EncodeToHex encodes `value` with the scale codec, returning a hex string (prefixed by 0x)
func EncodeToHex(value interface{}) (string, error) {
bz, err := Encode(value)
if err != nil {
return "", err
}
return fmt.Sprintf("%#x", bz), nil
}
// Decode decodes `bz` with the scale codec into `target`. `target` should be a pointer.
func Decode(bz []byte, target interface{}) error {
return scale.NewDecoder(bytes.NewReader(bz)).Decode(target)
}
// DecodeFromHex decodes `str` with the scale codec into `target`. `target` should be a pointer.
func DecodeFromHex(str string, target interface{}) error {
bz, err := HexDecodeString(str)
if err != nil {
return err
}
return Decode(bz, target)
}
// EncodedLength returns the length of the value when encoded as a byte array
func EncodedLength(value interface{}) (int, error) {
var buffer = bytes.Buffer{}
err := scale.NewEncoder(&buffer).Encode(value)
if err != nil {
return 0, err
}
return buffer.Len(), nil
}
// GetHash returns a hash of the value
func GetHash(value interface{}) (Hash, error) {
enc, err := Encode(value)
if err != nil {
return Hash{}, err
}
return blake2b.Sum256(enc), err
}
// Eq compares the value of the input to see if there is a match
func Eq(one, other interface{}) bool {
return reflect.DeepEqual(one, other)
}
// HexDecodeString decodes bytes from a hex string. Contrary to hex.DecodeString, this function does not error if "0x"
// is prefixed, and adds an extra 0 if the hex string has an odd length.
func HexDecodeString(s string) ([]byte, error) {
s = strings.TrimPrefix(s, "0x")
if len(s)%2 != 0 {
s = "0" + s
}
b, err := hex.DecodeString(s)
if err != nil {
return nil, err
}
return b, nil
}
// MustHexDecodeString panics if str cannot be decoded
func MustHexDecodeString(str string) []byte {
bz, err := HexDecodeString(str)
if err != nil {
panic(err)
}
return bz
}
// HexEncodeToString encodes bytes to a hex string. Contrary to hex.EncodeToString,
// this function prefixes the hex string with "0x"
func HexEncodeToString(b []byte) string {
return "0x" + hex.EncodeToString(b)
}
// Hex returns a hex string representation of the value (not of the encoded value)
func Hex(value interface{}) (string, error) {
switch v := value.(type) {
case Hexer:
return v.Hex(), nil
case []byte:
return fmt.Sprintf("%#x", v), nil
default:
return "", fmt.Errorf("does not support %T", v)
}
}