types.go 8.9 KB

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