github.com/stafiprotocol/go-substrate-rpc-client@v1.4.7/types/codec.go (about) 1 // Go Substrate RPC Client (GSRPC) provides APIs and types around Polkadot and any Substrate-based chain RPC calls 2 // 3 // Copyright 2020 Stafi Protocol 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 17 package types 18 19 import ( 20 "bytes" 21 "encoding/hex" 22 "fmt" 23 "reflect" 24 "strings" 25 26 "github.com/stafiprotocol/go-substrate-rpc-client/pkg/scale" 27 "golang.org/x/crypto/blake2b" 28 ) 29 30 // Hexer interface is implemented by any type that has a Hex() function returning a string 31 type Hexer interface { 32 Hex() string 33 } 34 35 // EncodeToBytes encodes `value` with the scale codec with passed EncoderOptions, returning []byte 36 // TODO rename to Encode 37 func EncodeToBytes(value interface{}) ([]byte, error) { 38 var buffer = bytes.Buffer{} 39 err := scale.NewEncoder(&buffer).Encode(value) 40 if err != nil { 41 return buffer.Bytes(), err 42 } 43 return buffer.Bytes(), nil 44 } 45 46 // EncodeToHexString encodes `value` with the scale codec, returning a hex string (prefixed by 0x) 47 // TODO rename to EncodeToHex 48 func EncodeToHexString(value interface{}) (string, error) { 49 bz, err := EncodeToBytes(value) 50 if err != nil { 51 return "", err 52 } 53 54 return fmt.Sprintf("%#x", bz), nil 55 } 56 57 // DecodeFromBytes decodes `bz` with the scale codec into `target`. `target` should be a pointer. 58 // TODO rename to Decode 59 func DecodeFromBytes(bz []byte, target interface{}) error { 60 return scale.NewDecoder(bytes.NewReader(bz)).Decode(target) 61 } 62 63 // DecodeFromHexString decodes `str` with the scale codec into `target`. `target` should be a pointer. 64 // TODO rename to DecodeFromHex 65 func DecodeFromHexString(str string, target interface{}) error { 66 bz, err := HexDecodeString(str) 67 if err != nil { 68 return err 69 } 70 return DecodeFromBytes(bz, target) 71 } 72 73 // EncodedLength returns the length of the value when encoded as a byte array 74 func EncodedLength(value interface{}) (int, error) { 75 var buffer = bytes.Buffer{} 76 err := scale.NewEncoder(&buffer).Encode(value) 77 if err != nil { 78 return 0, err 79 } 80 return buffer.Len(), nil 81 } 82 83 // GetHash returns a hash of the value 84 func GetHash(value interface{}) (Hash, error) { 85 enc, err := EncodeToBytes(value) 86 if err != nil { 87 return Hash{}, err 88 } 89 return blake2b.Sum256(enc), err 90 } 91 92 // Eq compares the value of the input to see if there is a match 93 func Eq(one, other interface{}) bool { 94 return reflect.DeepEqual(one, other) 95 } 96 97 // HexDecodeString decodes bytes from a hex string. Contrary to hex.DecodeString, this function does not error if "0x" 98 // is prefixed, and adds an extra 0 if the hex string has an odd length. 99 func HexDecodeString(s string) ([]byte, error) { 100 s = strings.TrimPrefix(s, "0x") 101 102 if len(s)%2 != 0 { 103 s = "0" + s 104 } 105 106 b, err := hex.DecodeString(s) 107 if err != nil { 108 return nil, err 109 } 110 111 return b, nil 112 } 113 114 // MustHexDecodeString panics if str cannot be decoded 115 func MustHexDecodeString(str string) []byte { 116 bz, err := HexDecodeString(str) 117 if err != nil { 118 panic(err) 119 } 120 return bz 121 } 122 123 // HexEncode encodes bytes to a hex string. Contrary to hex.EncodeToString, this function prefixes the hex string 124 // with "0x" 125 func HexEncodeToString(b []byte) string { 126 return "0x" + hex.EncodeToString(b) 127 } 128 129 // Hex returns a hex string representation of the value (not of the encoded value) 130 func Hex(value interface{}) (string, error) { 131 switch v := value.(type) { 132 case Hexer: 133 return v.Hex(), nil 134 case []byte: 135 return fmt.Sprintf("%#x", v), nil 136 default: 137 return "", fmt.Errorf("does not support %T", v) 138 } 139 }