aboutsummaryrefslogtreecommitdiffstats
path: root/common
diff options
context:
space:
mode:
Diffstat (limited to 'common')
-rw-r--r--common/bitutil/compress_test.go8
-rw-r--r--common/hexutil/json.go9
-rw-r--r--common/types.go24
-rw-r--r--common/types_test.go31
4 files changed, 62 insertions, 10 deletions
diff --git a/common/bitutil/compress_test.go b/common/bitutil/compress_test.go
index 805ab0369..9bd1de103 100644
--- a/common/bitutil/compress_test.go
+++ b/common/bitutil/compress_test.go
@@ -121,20 +121,20 @@ func TestCompression(t *testing.T) {
in := hexutil.MustDecode("0x4912385c0e7b64000000")
out := hexutil.MustDecode("0x80fe4912385c0e7b64")
- if data := CompressBytes(in); bytes.Compare(data, out) != 0 {
+ if data := CompressBytes(in); !bytes.Equal(data, out) {
t.Errorf("encoding mismatch for sparse data: have %x, want %x", data, out)
}
- if data, err := DecompressBytes(out, len(in)); err != nil || bytes.Compare(data, in) != 0 {
+ if data, err := DecompressBytes(out, len(in)); err != nil || !bytes.Equal(data, in) {
t.Errorf("decoding mismatch for sparse data: have %x, want %x, error %v", data, in, err)
}
// Check the the compression returns the input if the bitset encoding is longer
in = hexutil.MustDecode("0xdf7070533534333636313639343638373532313536346c1bc33339343837313070706336343035336336346c65fefb3930393233383838ac2f65fefb")
out = hexutil.MustDecode("0xdf7070533534333636313639343638373532313536346c1bc33339343837313070706336343035336336346c65fefb3930393233383838ac2f65fefb")
- if data := CompressBytes(in); bytes.Compare(data, out) != 0 {
+ if data := CompressBytes(in); !bytes.Equal(data, out) {
t.Errorf("encoding mismatch for dense data: have %x, want %x", data, out)
}
- if data, err := DecompressBytes(out, len(in)); err != nil || bytes.Compare(data, in) != 0 {
+ if data, err := DecompressBytes(out, len(in)); err != nil || !bytes.Equal(data, in) {
t.Errorf("decoding mismatch for dense data: have %x, want %x, error %v", data, in, err)
}
// Check that decompressing a longer input than the target fails
diff --git a/common/hexutil/json.go b/common/hexutil/json.go
index 943288fad..11e14cae7 100644
--- a/common/hexutil/json.go
+++ b/common/hexutil/json.go
@@ -26,11 +26,10 @@ import (
)
var (
- textZero = []byte(`0x0`)
- bytesT = reflect.TypeOf(Bytes(nil))
- bigT = reflect.TypeOf((*Big)(nil))
- uintT = reflect.TypeOf(Uint(0))
- uint64T = reflect.TypeOf(Uint64(0))
+ bytesT = reflect.TypeOf(Bytes(nil))
+ bigT = reflect.TypeOf((*Big)(nil))
+ uintT = reflect.TypeOf(Uint(0))
+ uint64T = reflect.TypeOf(Uint64(0))
)
// Bytes marshals/unmarshals as a JSON string with 0x prefix.
diff --git a/common/types.go b/common/types.go
index 803726634..eaf8352fb 100644
--- a/common/types.go
+++ b/common/types.go
@@ -24,6 +24,7 @@ import (
"reflect"
"github.com/ethereum/go-ethereum/common/hexutil"
+ "github.com/ethereum/go-ethereum/crypto/sha3"
)
const (
@@ -163,7 +164,28 @@ func (a Address) Str() string { return string(a[:]) }
func (a Address) Bytes() []byte { return a[:] }
func (a Address) Big() *big.Int { return new(big.Int).SetBytes(a[:]) }
func (a Address) Hash() Hash { return BytesToHash(a[:]) }
-func (a Address) Hex() string { return hexutil.Encode(a[:]) }
+
+// Hex returns an EIP55-compliant hex string representation of the address.
+func (a Address) Hex() string {
+ unchecksummed := hex.EncodeToString(a[:])
+ sha := sha3.NewKeccak256()
+ sha.Write([]byte(unchecksummed))
+ hash := sha.Sum(nil)
+
+ result := []byte(unchecksummed)
+ for i := 0; i < len(result); i++ {
+ hashByte := hash[i/2]
+ if i%2 == 0 {
+ hashByte = hashByte >> 4
+ } else {
+ hashByte &= 0xf
+ }
+ if result[i] > '9' && hashByte > 7 {
+ result[i] -= 32
+ }
+ }
+ return "0x" + string(result)
+}
// String implements the stringer interface and is used also by the logger.
func (a Address) String() string {
diff --git a/common/types_test.go b/common/types_test.go
index 154c33063..6f3b31576 100644
--- a/common/types_test.go
+++ b/common/types_test.go
@@ -94,3 +94,34 @@ func TestAddressUnmarshalJSON(t *testing.T) {
}
}
}
+
+func TestAddressHexChecksum(t *testing.T) {
+ var tests = []struct {
+ Input string
+ Output string
+ }{
+ // Test cases from https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md#specification
+ {"0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed", "0x5aAeb6053F3E94C9b9A09f33669435E7Ef1BeAed"},
+ {"0xfb6916095ca1df60bb79ce92ce3ea74c37c5d359", "0xfB6916095ca1df60bB79Ce92cE3Ea74c37c5d359"},
+ {"0xdbf03b407c01e7cd3cbea99509d93f8dddc8c6fb", "0xdbF03B407c01E7cD3CBea99509d93f8DDDC8C6FB"},
+ {"0xd1220a0cf47c7b9be7a2e6ba89f429762e7b9adb", "0xD1220A0cf47c7B9Be7A2E6BA89F429762e7b9aDb"},
+ // Ensure that non-standard length input values are handled correctly
+ {"0xa", "0x000000000000000000000000000000000000000A"},
+ {"0x0a", "0x000000000000000000000000000000000000000A"},
+ {"0x00a", "0x000000000000000000000000000000000000000A"},
+ {"0x000000000000000000000000000000000000000a", "0x000000000000000000000000000000000000000A"},
+ }
+ for i, test := range tests {
+ output := HexToAddress(test.Input).Hex()
+ if output != test.Output {
+ t.Errorf("test #%d: failed to match when it should (%s != %s)", i, output, test.Output)
+ }
+ }
+}
+
+func BenchmarkAddressHex(b *testing.B) {
+ testAddr := HexToAddress("0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed")
+ for n := 0; n < b.N; n++ {
+ testAddr.Hex()
+ }
+}