github.com/yinchengtsinghua/golang-Eos-dpos-Ethereum@v0.0.0-20190121132951-92cc4225ed8e/common/hexutil/json.go (about) 1 2 //此源码被清华学神尹成大魔王专业翻译分析并修改 3 //尹成QQ77025077 4 //尹成微信18510341407 5 //尹成所在QQ群721929980 6 //尹成邮箱 yinc13@mails.tsinghua.edu.cn 7 //尹成毕业于清华大学,微软区块链领域全球最有价值专家 8 //https://mvp.microsoft.com/zh-cn/PublicProfile/4033620 9 //版权所有2016 Go Ethereum作者 10 //此文件是Go以太坊库的一部分。 11 // 12 //Go-Ethereum库是免费软件:您可以重新分发它和/或修改 13 //根据GNU发布的较低通用公共许可证的条款 14 //自由软件基金会,或者许可证的第3版,或者 15 //(由您选择)任何更高版本。 16 // 17 //Go以太坊图书馆的发行目的是希望它会有用, 18 //但没有任何保证;甚至没有 19 //适销性或特定用途的适用性。见 20 //GNU较低的通用公共许可证,了解更多详细信息。 21 // 22 //你应该收到一份GNU较低级别的公共许可证副本 23 //以及Go以太坊图书馆。如果没有,请参见<http://www.gnu.org/licenses/>。 24 25 package hexutil 26 27 import ( 28 "encoding/hex" 29 "encoding/json" 30 "fmt" 31 "math/big" 32 "reflect" 33 "strconv" 34 ) 35 36 var ( 37 bytesT = reflect.TypeOf(Bytes(nil)) 38 bigT = reflect.TypeOf((*Big)(nil)) 39 uintT = reflect.TypeOf(Uint(0)) 40 uint64T = reflect.TypeOf(Uint64(0)) 41 ) 42 43 //字节封送/取消封送为带0x前缀的JSON字符串。 44 //空切片封送为“0x”。 45 type Bytes []byte 46 47 //MarshalText实现Encoding.TextMarshaler 48 func (b Bytes) MarshalText() ([]byte, error) { 49 result := make([]byte, len(b)*2+2) 50 copy(result, `0x`) 51 hex.Encode(result[2:], b) 52 return result, nil 53 } 54 55 //unmashaljson实现json.unmasheler。 56 func (b *Bytes) UnmarshalJSON(input []byte) error { 57 if !isString(input) { 58 return errNonString(bytesT) 59 } 60 return wrapTypeError(b.UnmarshalText(input[1:len(input)-1]), bytesT) 61 } 62 63 //UnmarshalText实现encoding.textUnmarshaller。 64 func (b *Bytes) UnmarshalText(input []byte) error { 65 raw, err := checkText(input, true) 66 if err != nil { 67 return err 68 } 69 dec := make([]byte, len(raw)/2) 70 if _, err = hex.Decode(dec, raw); err != nil { 71 err = mapError(err) 72 } else { 73 *b = dec 74 } 75 return err 76 } 77 78 //字符串返回b的十六进制编码。 79 func (b Bytes) String() string { 80 return Encode(b) 81 } 82 83 //unmarshalfixedjson将输入解码为带0x前缀的字符串。输出长度 84 //确定所需的输入长度。此函数通常用于实现 85 //固定大小类型的unmashaljson方法。 86 func UnmarshalFixedJSON(typ reflect.Type, input, out []byte) error { 87 if !isString(input) { 88 return errNonString(typ) 89 } 90 return wrapTypeError(UnmarshalFixedText(typ.String(), input[1:len(input)-1], out), typ) 91 } 92 93 //unmarshalfixedtext将输入解码为带0x前缀的字符串。输出长度 94 //确定所需的输入长度。此函数通常用于实现 95 //为固定大小类型取消标记文本方法。 96 func UnmarshalFixedText(typname string, input, out []byte) error { 97 raw, err := checkText(input, true) 98 if err != nil { 99 return err 100 } 101 if len(raw)/2 != len(out) { 102 return fmt.Errorf("hex string has length %d, want %d for %s", len(raw), len(out)*2, typname) 103 } 104 // 105 for _, b := range raw { 106 if decodeNibble(b) == badNibble { 107 return ErrSyntax 108 } 109 } 110 hex.Decode(out, raw) 111 return nil 112 } 113 114 //unmarshalfixedUnprefixedText将输入解码为带可选0x前缀的字符串。这个 115 //输出长度决定所需的输入长度。此函数通常用于 116 //为固定大小类型实现UnmarshalText方法。 117 func UnmarshalFixedUnprefixedText(typname string, input, out []byte) error { 118 raw, err := checkText(input, false) 119 if err != nil { 120 return err 121 } 122 if len(raw)/2 != len(out) { 123 return fmt.Errorf("hex string has length %d, want %d for %s", len(raw), len(out)*2, typname) 124 } 125 //在修改out之前预先验证语法。 126 for _, b := range raw { 127 if decodeNibble(b) == badNibble { 128 return ErrSyntax 129 } 130 } 131 hex.Decode(out, raw) 132 return nil 133 } 134 135 //大封送/取消封送作为带有0x前缀的JSON字符串。 136 //零值封送为“0x0”。 137 // 138 //此时不支持负整数。试图封送他们将 139 //返回一个错误。大于256位的值将被取消标记拒绝,但将 140 //已正确封送。 141 type Big big.Int 142 143 //MarshalText实现Encoding.TextMarshaler 144 func (b Big) MarshalText() ([]byte, error) { 145 return []byte(EncodeBig((*big.Int)(&b))), nil 146 } 147 148 //unmashaljson实现json.unmasheler。 149 func (b *Big) UnmarshalJSON(input []byte) error { 150 if !isString(input) { 151 return errNonString(bigT) 152 } 153 return wrapTypeError(b.UnmarshalText(input[1:len(input)-1]), bigT) 154 } 155 156 //UnmarshalText实现编码。textUnmarshaller 157 func (b *Big) UnmarshalText(input []byte) error { 158 raw, err := checkNumberText(input) 159 if err != nil { 160 return err 161 } 162 if len(raw) > 64 { 163 return ErrBig256Range 164 } 165 words := make([]big.Word, len(raw)/bigWordNibbles+1) 166 end := len(raw) 167 for i := range words { 168 start := end - bigWordNibbles 169 if start < 0 { 170 start = 0 171 } 172 for ri := start; ri < end; ri++ { 173 nib := decodeNibble(raw[ri]) 174 if nib == badNibble { 175 return ErrSyntax 176 } 177 words[i] *= 16 178 words[i] += big.Word(nib) 179 } 180 end = start 181 } 182 var dec big.Int 183 dec.SetBits(words) 184 *b = (Big)(dec) 185 return nil 186 } 187 188 //ToInt将b转换为big.int。 189 func (b *Big) ToInt() *big.Int { 190 return (*big.Int)(b) 191 } 192 193 //字符串返回b的十六进制编码。 194 func (b *Big) String() string { 195 return EncodeBig(b.ToInt()) 196 } 197 198 //uint64以带有0x前缀的JSON字符串封送/取消封送。 199 //零值封送为“0x0”。 200 type Uint64 uint64 201 202 //MarshalText实现Encoding.TextMarshaler。 203 func (b Uint64) MarshalText() ([]byte, error) { 204 buf := make([]byte, 2, 10) 205 copy(buf, `0x`) 206 buf = strconv.AppendUint(buf, uint64(b), 16) 207 return buf, nil 208 } 209 210 //unmashaljson实现json.unmasheler。 211 func (b *Uint64) UnmarshalJSON(input []byte) error { 212 if !isString(input) { 213 return errNonString(uint64T) 214 } 215 return wrapTypeError(b.UnmarshalText(input[1:len(input)-1]), uint64T) 216 } 217 218 //UnmarshalText实现编码。textUnmarshaller 219 func (b *Uint64) UnmarshalText(input []byte) error { 220 raw, err := checkNumberText(input) 221 if err != nil { 222 return err 223 } 224 if len(raw) > 16 { 225 return ErrUint64Range 226 } 227 var dec uint64 228 for _, byte := range raw { 229 nib := decodeNibble(byte) 230 if nib == badNibble { 231 return ErrSyntax 232 } 233 dec *= 16 234 dec += nib 235 } 236 *b = Uint64(dec) 237 return nil 238 } 239 240 //字符串返回b的十六进制编码。 241 func (b Uint64) String() string { 242 return EncodeUint64(uint64(b)) 243 } 244 245 // 246 //零值封送为“0x0”。 247 type Uint uint 248 249 //MarshalText实现Encoding.TextMarshaler。 250 func (b Uint) MarshalText() ([]byte, error) { 251 return Uint64(b).MarshalText() 252 } 253 254 //unmashaljson实现json.unmasheler。 255 func (b *Uint) UnmarshalJSON(input []byte) error { 256 if !isString(input) { 257 return errNonString(uintT) 258 } 259 return wrapTypeError(b.UnmarshalText(input[1:len(input)-1]), uintT) 260 } 261 262 //UnmarshalText实现encoding.textUnmarshaller。 263 func (b *Uint) UnmarshalText(input []byte) error { 264 var u64 Uint64 265 err := u64.UnmarshalText(input) 266 if u64 > Uint64(^uint(0)) || err == ErrUint64Range { 267 return ErrUintRange 268 } else if err != nil { 269 return err 270 } 271 *b = Uint(u64) 272 return nil 273 } 274 275 //字符串返回b的十六进制编码。 276 func (b Uint) String() string { 277 return EncodeUint64(uint64(b)) 278 } 279 280 func isString(input []byte) bool { 281 return len(input) >= 2 && input[0] == '"' && input[len(input)-1] == '"' 282 } 283 284 func bytesHave0xPrefix(input []byte) bool { 285 return len(input) >= 2 && input[0] == '0' && (input[1] == 'x' || input[1] == 'X') 286 } 287 288 func checkText(input []byte, wantPrefix bool) ([]byte, error) { 289 if len(input) == 0 { 290 return nil, nil //允许空字符串 291 } 292 if bytesHave0xPrefix(input) { 293 input = input[2:] 294 } else if wantPrefix { 295 return nil, ErrMissingPrefix 296 } 297 if len(input)%2 != 0 { 298 return nil, ErrOddLength 299 } 300 return input, nil 301 } 302 303 func checkNumberText(input []byte) (raw []byte, err error) { 304 if len(input) == 0 { 305 return nil, nil //允许空字符串 306 } 307 if !bytesHave0xPrefix(input) { 308 return nil, ErrMissingPrefix 309 } 310 input = input[2:] 311 if len(input) == 0 { 312 return nil, ErrEmptyNumber 313 } 314 if len(input) > 1 && input[0] == '0' { 315 return nil, ErrLeadingZero 316 } 317 return input, nil 318 } 319 320 func wrapTypeError(err error, typ reflect.Type) error { 321 if _, ok := err.(*decError); ok { 322 return &json.UnmarshalTypeError{Value: err.Error(), Type: typ} 323 } 324 return err 325 } 326 327 func errNonString(typ reflect.Type) error { 328 return &json.UnmarshalTypeError{Value: "non-string", Type: typ} 329 }