github.com/m3shine/gochain@v2.2.26+incompatible/common/types.go (about) 1 // Copyright 2015 The go-ethereum Authors 2 // This file is part of the go-ethereum library. 3 // 4 // The go-ethereum library is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU Lesser General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // The go-ethereum library is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU Lesser General Public License for more details. 13 // 14 // You should have received a copy of the GNU Lesser General Public License 15 // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. 16 17 package common 18 19 import ( 20 "database/sql/driver" 21 "encoding/hex" 22 "encoding/json" 23 "fmt" 24 "math/big" 25 "math/rand" 26 "reflect" 27 "strings" 28 29 "github.com/gochain-io/gochain/common/hexutil" 30 "github.com/gochain-io/gochain/crypto/sha3" 31 ) 32 33 // Lengths of hashes and addresses in bytes. 34 const ( 35 // HashLength is the expected length of the hash 36 HashLength = 32 37 // AddressLength is the expected length of the address 38 AddressLength = 20 39 ) 40 41 var ( 42 hashT = reflect.TypeOf(Hash{}) 43 addressT = reflect.TypeOf(Address{}) 44 ) 45 46 // Hash represents the 32 byte Keccak256 hash of arbitrary data. 47 type Hash [HashLength]byte 48 49 // BytesToHash sets b to hash. 50 // If b is larger than len(h), b will be cropped from the left. 51 func BytesToHash(b []byte) Hash { 52 var h Hash 53 h.SetBytes(b) 54 return h 55 } 56 func StringToHash(s string) Hash { return BytesToHash([]byte(s)) } 57 58 // BigToHash sets byte representation of b to hash. 59 // If b is larger than len(h), b will be cropped from the left. 60 func BigToHash(b *big.Int) Hash { return BytesToHash(b.Bytes()) } 61 62 // HexToHash sets byte representation of s to hash. 63 // If b is larger than len(h), b will be cropped from the left. 64 func HexToHash(s string) Hash { return BytesToHash(FromHex(s)) } 65 66 // Str gets the string representation of the underlying hash 67 func (h Hash) Str() string { return string(h[:]) } 68 69 // Bytes gets the byte representation of the underlying hash. 70 func (h Hash) Bytes() []byte { return h[:] } 71 72 // Big converts a hash to a big integer. 73 func (h Hash) Big() *big.Int { return new(big.Int).SetBytes(h[:]) } 74 75 // Hex converts a hash to a hex string. 76 func (h Hash) Hex() string { return hexutil.Encode(h[:]) } 77 78 // TerminalString implements log.TerminalStringer, formatting a string for console 79 // output during logging. 80 func (h Hash) TerminalString() string { 81 return fmt.Sprintf("%x…%x", h[:3], h[29:]) 82 } 83 84 // String implements the stringer interface and is used also by the logger when 85 // doing full logging into a file. 86 func (h Hash) String() string { 87 return h.Hex() 88 } 89 90 // Format implements fmt.Formatter, forcing the byte slice to be formatted as is, 91 // without going through the stringer interface used for logging. 92 func (h Hash) Format(s fmt.State, c rune) { 93 fmt.Fprintf(s, "%"+string(c), h[:]) 94 } 95 96 // UnmarshalText parses a hash in hex syntax. 97 func (h *Hash) UnmarshalText(input []byte) error { 98 return hexutil.UnmarshalFixedText("Hash", input, h[:]) 99 } 100 101 // UnmarshalJSON parses a hash in hex syntax. 102 func (h *Hash) UnmarshalJSON(input []byte) error { 103 return hexutil.UnmarshalFixedJSON(hashT, input, h[:]) 104 } 105 106 // MarshalText returns the hex representation of h. 107 func (h Hash) MarshalText() ([]byte, error) { 108 return hexutil.Bytes(h[:]).MarshalText() 109 } 110 111 // SetBytes sets the hash to the value of b. 112 // If b is larger than len(h), b will be cropped from the left. 113 func (h *Hash) SetBytes(b []byte) { 114 if len(b) > len(h) { 115 b = b[len(b)-HashLength:] 116 } 117 118 copy(h[HashLength-len(b):], b) 119 } 120 121 // Set string `s` to h. If s is larger than len(h) s will be cropped (from left) to fit. 122 func (h *Hash) SetString(s string) { h.SetBytes([]byte(s)) } 123 124 // Sets h to other 125 func (h *Hash) Set(other Hash) { 126 for i, v := range other { 127 h[i] = v 128 } 129 } 130 131 // Generate implements testing/quick.Generator. 132 func (h Hash) Generate(rand *rand.Rand, size int) reflect.Value { 133 m := rand.Intn(len(h)) 134 for i := len(h) - 1; i > m; i-- { 135 h[i] = byte(rand.Uint32()) 136 } 137 return reflect.ValueOf(h) 138 } 139 140 // Scan implements Scanner for database/sql. 141 func (h *Hash) Scan(src interface{}) error { 142 srcB, ok := src.([]byte) 143 if !ok { 144 return fmt.Errorf("can't scan %T into Hash", src) 145 } 146 if len(srcB) != HashLength { 147 return fmt.Errorf("can't scan []byte of len %d into Hash, want %d", len(srcB), HashLength) 148 } 149 copy(h[:], srcB) 150 return nil 151 } 152 153 // Value implements valuer for database/sql. 154 func (h Hash) Value() (driver.Value, error) { 155 return h[:], nil 156 } 157 158 func EmptyHash(h Hash) bool { 159 return h == Hash{} 160 } 161 162 // UnprefixedHash allows marshaling a Hash without 0x prefix. 163 type UnprefixedHash Hash 164 165 // UnmarshalText decodes the hash from hex. The 0x prefix is optional. 166 func (h *UnprefixedHash) UnmarshalText(input []byte) error { 167 return hexutil.UnmarshalFixedUnprefixedText("UnprefixedHash", input, h[:]) 168 } 169 170 // MarshalText encodes the hash as hex. 171 func (h UnprefixedHash) MarshalText() ([]byte, error) { 172 return []byte(hex.EncodeToString(h[:])), nil 173 } 174 175 /////////// Address 176 177 // Address represents the 20 byte address of an Ethereum account. 178 type Address [AddressLength]byte 179 180 // BytesToAddress returns Address with value b. 181 // If b is larger than len(h), b will be cropped from the left. 182 func BytesToAddress(b []byte) Address { 183 var a Address 184 a.SetBytes(b) 185 return a 186 } 187 func StringToAddress(s string) Address { return BytesToAddress([]byte(s)) } 188 189 // BigToAddress returns Address with byte values of b. 190 // If b is larger than len(h), b will be cropped from the left. 191 func BigToAddress(b *big.Int) Address { return BytesToAddress(b.Bytes()) } 192 193 // HexToAddress returns Address with byte values of s. 194 // If s is larger than len(h), s will be cropped from the left. 195 func HexToAddress(s string) Address { return BytesToAddress(FromHex(s)) } 196 197 // IsHexAddress verifies whether a string can represent a valid hex-encoded 198 // Ethereum address or not. 199 func IsHexAddress(s string) bool { 200 if hasHexPrefix(s) { 201 s = s[2:] 202 } 203 return len(s) == 2*AddressLength && isHex(s) 204 } 205 206 // Str gets the string representation of the underlying address 207 func (a Address) Str() string { return string(a[:]) } 208 209 // Bytes gets the string representation of the underlying address. 210 func (a Address) Bytes() []byte { return a[:] } 211 212 // Big converts an address to a big integer. 213 func (a Address) Big() *big.Int { return new(big.Int).SetBytes(a[:]) } 214 215 // Hash converts an address to a hash by left-padding it with zeros. 216 func (a Address) Hash() Hash { return BytesToHash(a[:]) } 217 218 // Hex returns an EIP55-compliant hex string representation of the address. 219 func (a Address) Hex() string { 220 unchecksummed := hex.EncodeToString(a[:]) 221 var hash Hash 222 sha3.Keccak256(hash[:], []byte(unchecksummed)) 223 224 result := []byte(unchecksummed) 225 for i := 0; i < len(result); i++ { 226 hashByte := hash[i/2] 227 if i%2 == 0 { 228 hashByte = hashByte >> 4 229 } else { 230 hashByte &= 0xf 231 } 232 if result[i] > '9' && hashByte > 7 { 233 result[i] -= 32 234 } 235 } 236 return "0x" + string(result) 237 } 238 239 // String implements the stringer interface and is used also by the logger. 240 func (a Address) String() string { 241 return a.Hex() 242 } 243 244 // Format implements fmt.Formatter, forcing the byte slice to be formatted as is, 245 // without going through the stringer interface used for logging. 246 func (a Address) Format(s fmt.State, c rune) { 247 fmt.Fprintf(s, "%"+string(c), a[:]) 248 } 249 250 // SetBytes sets the address to the value of b. 251 // If b is larger than len(a) it will panic. 252 func (a *Address) SetBytes(b []byte) { 253 if len(b) > len(a) { 254 b = b[len(b)-AddressLength:] 255 } 256 copy(a[AddressLength-len(b):], b) 257 } 258 259 // Set string `s` to a. If s is larger than len(a) it will panic 260 func (a *Address) SetString(s string) { a.SetBytes([]byte(s)) } 261 262 // Sets a to other 263 func (a *Address) Set(other Address) { 264 for i, v := range other { 265 a[i] = v 266 } 267 } 268 269 // MarshalText returns the hex representation of a. 270 func (a Address) MarshalText() ([]byte, error) { 271 return hexutil.Bytes(a[:]).MarshalText() 272 } 273 274 // UnmarshalText parses a hash in hex syntax. 275 func (a *Address) UnmarshalText(input []byte) error { 276 return hexutil.UnmarshalFixedText("Address", input, a[:]) 277 } 278 279 // UnmarshalJSON parses a hash in hex syntax. 280 func (a *Address) UnmarshalJSON(input []byte) error { 281 return hexutil.UnmarshalFixedJSON(addressT, input, a[:]) 282 } 283 284 // Scan implements Scanner for database/sql. 285 func (a *Address) Scan(src interface{}) error { 286 srcB, ok := src.([]byte) 287 if !ok { 288 return fmt.Errorf("can't scan %T into Address", src) 289 } 290 if len(srcB) != AddressLength { 291 return fmt.Errorf("can't scan []byte of len %d into Address, want %d", len(srcB), AddressLength) 292 } 293 copy(a[:], srcB) 294 return nil 295 } 296 297 // Value implements valuer for database/sql. 298 func (a Address) Value() (driver.Value, error) { 299 return a[:], nil 300 } 301 302 // UnprefixedAddress allows marshaling an Address without 0x prefix. 303 type UnprefixedAddress Address 304 305 // UnmarshalText decodes the address from hex. The 0x prefix is optional. 306 func (a *UnprefixedAddress) UnmarshalText(input []byte) error { 307 return hexutil.UnmarshalFixedUnprefixedText("UnprefixedAddress", input, a[:]) 308 } 309 310 // MarshalText encodes the address as hex. 311 func (a UnprefixedAddress) MarshalText() ([]byte, error) { 312 return []byte(hex.EncodeToString(a[:])), nil 313 } 314 315 // MixedcaseAddress retains the original string, which may or may not be 316 // correctly checksummed 317 type MixedcaseAddress struct { 318 addr Address 319 original string 320 } 321 322 // NewMixedcaseAddress constructor (mainly for testing) 323 func NewMixedcaseAddress(addr Address) MixedcaseAddress { 324 return MixedcaseAddress{addr: addr, original: addr.Hex()} 325 } 326 327 // NewMixedcaseAddressFromString is mainly meant for unit-testing 328 func NewMixedcaseAddressFromString(hexaddr string) (*MixedcaseAddress, error) { 329 if !IsHexAddress(hexaddr) { 330 return nil, fmt.Errorf("Invalid address") 331 } 332 a := FromHex(hexaddr) 333 return &MixedcaseAddress{addr: BytesToAddress(a), original: hexaddr}, nil 334 } 335 336 // UnmarshalJSON parses MixedcaseAddress 337 func (ma *MixedcaseAddress) UnmarshalJSON(input []byte) error { 338 if err := hexutil.UnmarshalFixedJSON(addressT, input, ma.addr[:]); err != nil { 339 return err 340 } 341 return json.Unmarshal(input, &ma.original) 342 } 343 344 // MarshalJSON marshals the original value 345 func (ma *MixedcaseAddress) MarshalJSON() ([]byte, error) { 346 if strings.HasPrefix(ma.original, "0x") || strings.HasPrefix(ma.original, "0X") { 347 return json.Marshal(fmt.Sprintf("0x%s", ma.original[2:])) 348 } 349 return json.Marshal(fmt.Sprintf("0x%s", ma.original)) 350 } 351 352 // Address returns the address 353 func (ma *MixedcaseAddress) Address() Address { 354 return ma.addr 355 } 356 357 // String implements fmt.Stringer 358 func (ma *MixedcaseAddress) String() string { 359 if ma.ValidChecksum() { 360 return fmt.Sprintf("%s [chksum ok]", ma.original) 361 } 362 return fmt.Sprintf("%s [chksum INVALID]", ma.original) 363 } 364 365 // ValidChecksum returns true if the address has valid checksum 366 func (ma *MixedcaseAddress) ValidChecksum() bool { 367 return ma.original == ma.addr.Hex() 368 } 369 370 // Original returns the mixed-case input string 371 func (ma *MixedcaseAddress) Original() string { 372 return ma.original 373 }