1 // Copyright 2015 The go-ethereum Authors
2 // This file is part of the go-ethereum library.
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.
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.
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/>.
36 var hashJsonLengthErr = errors.New("common: unmarshalJSON failed: hash must be exactly 32 bytes")
40 Address [AddressLength]byte
43 func BytesToHash(b []byte) Hash {
48 func StringToHash(s string) Hash { return BytesToHash([]byte(s)) }
49 func BigToHash(b *big.Int) Hash { return BytesToHash(b.Bytes()) }
50 func HexToHash(s string) Hash { return BytesToHash(FromHex(s)) }
53 // Don't use the default 'String' method in case we want to overwrite
55 // Get the string representation of the underlying hash
56 func (h Hash) Str() string { return string(h[:]) }
57 func (h Hash) Bytes() []byte { return h[:] }
58 func (h Hash) Big() *big.Int { return Bytes2Big(h[:]) }
59 func (h Hash) Hex() string { return "0x" + Bytes2Hex(h[:]) }
61 // UnmarshalJSON parses a hash in its hex from to a hash.
62 func (h *Hash) UnmarshalJSON(input []byte) error {
64 if length >= 2 && input[0] == '"' && input[length-1] == '"' {
65 input = input[1 : length-1]
67 // strip "0x" for length check
68 if len(input) > 1 && strings.ToLower(string(input[:2])) == "0x" {
72 // validate the length of the input hash
73 if len(input) != HashLength*2 {
74 return hashJsonLengthErr
76 h.SetBytes(FromHex(string(input)))
80 // Serialize given hash to JSON
81 func (h Hash) MarshalJSON() ([]byte, error) {
82 return json.Marshal(h.Hex())
85 // Sets the hash to the value of b. If b is larger than len(h) it will panic
86 func (h *Hash) SetBytes(b []byte) {
88 b = b[len(b)-HashLength:]
91 copy(h[HashLength-len(b):], b)
94 // Set string `s` to h. If s is larger than len(h) it will panic
95 func (h *Hash) SetString(s string) { h.SetBytes([]byte(s)) }
98 func (h *Hash) Set(other Hash) {
99 for i, v := range other {
104 // Generate implements testing/quick.Generator.
105 func (h Hash) Generate(rand *rand.Rand, size int) reflect.Value {
106 m := rand.Intn(len(h))
107 for i := len(h) - 1; i > m; i-- {
108 h[i] = byte(rand.Uint32())
110 return reflect.ValueOf(h)
113 func EmptyHash(h Hash) bool {
118 func BytesToAddress(b []byte) Address {
123 func StringToAddress(s string) Address { return BytesToAddress([]byte(s)) }
124 func BigToAddress(b *big.Int) Address { return BytesToAddress(b.Bytes()) }
125 func HexToAddress(s string) Address { return BytesToAddress(FromHex(s)) }
127 // IsHexAddress verifies whether a string can represent a valid hex-encoded
128 // Ethereum address or not.
129 func IsHexAddress(s string) bool {
130 if len(s) == 2+2*AddressLength && IsHex(s) {
133 if len(s) == 2*AddressLength && IsHex("0x"+s) {
139 // Get the string representation of the underlying address
140 func (a Address) Str() string { return string(a[:]) }
141 func (a Address) Bytes() []byte { return a[:] }
142 func (a Address) Big() *big.Int { return Bytes2Big(a[:]) }
143 func (a Address) Hash() Hash { return BytesToHash(a[:]) }
144 func (a Address) Hex() string { return "0x" + Bytes2Hex(a[:]) }
146 // Sets the address to the value of b. If b is larger than len(a) it will panic
147 func (a *Address) SetBytes(b []byte) {
149 b = b[len(b)-AddressLength:]
151 copy(a[AddressLength-len(b):], b)
154 // Set string `s` to a. If s is larger than len(a) it will panic
155 func (a *Address) SetString(s string) { a.SetBytes([]byte(s)) }
158 func (a *Address) Set(other Address) {
159 for i, v := range other {
164 // Serialize given address to JSON
165 func (a Address) MarshalJSON() ([]byte, error) {
166 return json.Marshal(a.Str())
169 // Parse address from raw json data
170 func (a *Address) UnmarshalJSON(data []byte) error {
171 if len(data) > 2 && data[0] == '"' && data[len(data)-1] == '"' {
172 data = data[1 : len(data)-1]
175 if len(data) != AddressLength {
176 return fmt.Errorf("Invalid address length, expected %d got %d bytes", AddressLength, len(data))
179 _, res, err := AddressDecode("bm", string(data))
184 if len(res) != PubkeyHashLength {
185 return fmt.Errorf("Invalid address")
187 a.Set(BytesToAddress(data))
191 // PP Pretty Prints a byte slice in the following format:
192 // hex(value[:4])...(hex[len(value)-4:])
193 func PP(value []byte) string {
195 return Bytes2Hex(value)
198 return fmt.Sprintf("%x...%x", value[:4], value[len(value)-4])