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