github.com/fxsjy/go-ethereum@v1.8.4-0.20180410143526-2e247705cd27/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 "encoding/hex" 21 "fmt" 22 "math/big" 23 "math/rand" 24 "reflect" 25 26 "github.com/ethereum/go-ethereum/common/hexutil" 27 "github.com/ethereum/go-ethereum/crypto/sha3" 28 ) 29 30 const ( 31 HashLength = 32 32 AddressLength = 20 33 ) 34 35 var ( 36 hashT = reflect.TypeOf(Hash{}) 37 addressT = reflect.TypeOf(Address{}) 38 ) 39 40 // Hash represents the 32 byte Keccak256 hash of arbitrary data. 41 type Hash [HashLength]byte 42 43 func BytesToHash(b []byte) Hash { 44 var h Hash 45 h.SetBytes(b) 46 return h 47 } 48 func BigToHash(b *big.Int) Hash { return BytesToHash(b.Bytes()) } 49 func HexToHash(s string) Hash { return BytesToHash(FromHex(s)) } 50 51 // Get the string representation of the underlying hash 52 func (h Hash) Str() string { return string(h[:]) } 53 func (h Hash) Bytes() []byte { return h[:] } 54 func (h Hash) Big() *big.Int { return new(big.Int).SetBytes(h[:]) } 55 func (h Hash) Hex() string { return hexutil.Encode(h[:]) } 56 57 // TerminalString implements log.TerminalStringer, formatting a string for console 58 // output during logging. 59 func (h Hash) TerminalString() string { 60 return fmt.Sprintf("%x…%x", h[:3], h[29:]) 61 } 62 63 // String implements the stringer interface and is used also by the logger when 64 // doing full logging into a file. 65 func (h Hash) String() string { 66 return h.Hex() 67 } 68 69 // Format implements fmt.Formatter, forcing the byte slice to be formatted as is, 70 // without going through the stringer interface used for logging. 71 func (h Hash) Format(s fmt.State, c rune) { 72 fmt.Fprintf(s, "%"+string(c), h[:]) 73 } 74 75 // UnmarshalText parses a hash in hex syntax. 76 func (h *Hash) UnmarshalText(input []byte) error { 77 return hexutil.UnmarshalFixedText("Hash", input, h[:]) 78 } 79 80 // UnmarshalJSON parses a hash in hex syntax. 81 func (h *Hash) UnmarshalJSON(input []byte) error { 82 return hexutil.UnmarshalFixedJSON(hashT, input, h[:]) 83 } 84 85 // MarshalText returns the hex representation of h. 86 func (h Hash) MarshalText() ([]byte, error) { 87 return hexutil.Bytes(h[:]).MarshalText() 88 } 89 90 // Sets the hash to the value of b. If b is larger than len(h), 'b' will be cropped (from the left). 91 func (h *Hash) SetBytes(b []byte) { 92 if len(b) > len(h) { 93 b = b[len(b)-HashLength:] 94 } 95 96 copy(h[HashLength-len(b):], b) 97 } 98 99 // Set string `s` to h. If s is larger than len(h) s will be cropped (from left) to fit. 100 func (h *Hash) SetString(s string) { h.SetBytes([]byte(s)) } 101 102 // Sets h to other 103 func (h *Hash) Set(other Hash) { 104 for i, v := range other { 105 h[i] = v 106 } 107 } 108 109 // Generate implements testing/quick.Generator. 110 func (h Hash) Generate(rand *rand.Rand, size int) reflect.Value { 111 m := rand.Intn(len(h)) 112 for i := len(h) - 1; i > m; i-- { 113 h[i] = byte(rand.Uint32()) 114 } 115 return reflect.ValueOf(h) 116 } 117 118 func EmptyHash(h Hash) bool { 119 return h == Hash{} 120 } 121 122 // UnprefixedHash allows marshaling a Hash without 0x prefix. 123 type UnprefixedHash Hash 124 125 // UnmarshalText decodes the hash from hex. The 0x prefix is optional. 126 func (h *UnprefixedHash) UnmarshalText(input []byte) error { 127 return hexutil.UnmarshalFixedUnprefixedText("UnprefixedHash", input, h[:]) 128 } 129 130 // MarshalText encodes the hash as hex. 131 func (h UnprefixedHash) MarshalText() ([]byte, error) { 132 return []byte(hex.EncodeToString(h[:])), nil 133 } 134 135 /////////// Address 136 137 // Address represents the 20 byte address of an Ethereum account. 138 type Address [AddressLength]byte 139 140 func BytesToAddress(b []byte) Address { 141 var a Address 142 a.SetBytes(b) 143 return a 144 } 145 func BigToAddress(b *big.Int) Address { return BytesToAddress(b.Bytes()) } 146 func HexToAddress(s string) Address { return BytesToAddress(FromHex(s)) } 147 148 // IsHexAddress verifies whether a string can represent a valid hex-encoded 149 // Ethereum address or not. 150 func IsHexAddress(s string) bool { 151 if hasHexPrefix(s) { 152 s = s[2:] 153 } 154 return len(s) == 2*AddressLength && isHex(s) 155 } 156 157 // Get the string representation of the underlying address 158 func (a Address) Str() string { return string(a[:]) } 159 func (a Address) Bytes() []byte { return a[:] } 160 func (a Address) Big() *big.Int { return new(big.Int).SetBytes(a[:]) } 161 func (a Address) Hash() Hash { return BytesToHash(a[:]) } 162 163 // Hex returns an EIP55-compliant hex string representation of the address. 164 func (a Address) Hex() string { 165 unchecksummed := hex.EncodeToString(a[:]) 166 sha := sha3.NewKeccak256() 167 sha.Write([]byte(unchecksummed)) 168 hash := sha.Sum(nil) 169 170 result := []byte(unchecksummed) 171 for i := 0; i < len(result); i++ { 172 hashByte := hash[i/2] 173 if i%2 == 0 { 174 hashByte = hashByte >> 4 175 } else { 176 hashByte &= 0xf 177 } 178 if result[i] > '9' && hashByte > 7 { 179 result[i] -= 32 180 } 181 } 182 return "0x" + string(result) 183 } 184 185 // String implements the stringer interface and is used also by the logger. 186 func (a Address) String() string { 187 return a.Hex() 188 } 189 190 // Format implements fmt.Formatter, forcing the byte slice to be formatted as is, 191 // without going through the stringer interface used for logging. 192 func (a Address) Format(s fmt.State, c rune) { 193 fmt.Fprintf(s, "%"+string(c), a[:]) 194 } 195 196 // Sets the address to the value of b. If b is larger than len(a) it will panic 197 func (a *Address) SetBytes(b []byte) { 198 if len(b) > len(a) { 199 b = b[len(b)-AddressLength:] 200 } 201 copy(a[AddressLength-len(b):], b) 202 } 203 204 // Set string `s` to a. If s is larger than len(a) it will panic 205 func (a *Address) SetString(s string) { a.SetBytes([]byte(s)) } 206 207 // Sets a to other 208 func (a *Address) Set(other Address) { 209 for i, v := range other { 210 a[i] = v 211 } 212 } 213 214 // MarshalText returns the hex representation of a. 215 func (a Address) MarshalText() ([]byte, error) { 216 return hexutil.Bytes(a[:]).MarshalText() 217 } 218 219 // UnmarshalText parses a hash in hex syntax. 220 func (a *Address) UnmarshalText(input []byte) error { 221 return hexutil.UnmarshalFixedText("Address", input, a[:]) 222 } 223 224 // UnmarshalJSON parses a hash in hex syntax. 225 func (a *Address) UnmarshalJSON(input []byte) error { 226 return hexutil.UnmarshalFixedJSON(addressT, input, a[:]) 227 } 228 229 // UnprefixedHash allows marshaling an Address without 0x prefix. 230 type UnprefixedAddress Address 231 232 // UnmarshalText decodes the address from hex. The 0x prefix is optional. 233 func (a *UnprefixedAddress) UnmarshalText(input []byte) error { 234 return hexutil.UnmarshalFixedUnprefixedText("UnprefixedAddress", input, a[:]) 235 } 236 237 // MarshalText encodes the address as hex. 238 func (a UnprefixedAddress) MarshalText() ([]byte, error) { 239 return []byte(hex.EncodeToString(a[:])), nil 240 }