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