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