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