mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-17 17:33:47 +00:00
common/types: implement case-preserving address for json API input
This commit is contained in:
parent
533f2be9ee
commit
4eea6854c5
2 changed files with 98 additions and 0 deletions
|
|
@ -23,6 +23,7 @@ import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
|
"encoding/json"
|
||||||
"github.com/ethereum/go-ethereum/common/hexutil"
|
"github.com/ethereum/go-ethereum/common/hexutil"
|
||||||
"github.com/ethereum/go-ethereum/crypto/sha3"
|
"github.com/ethereum/go-ethereum/crypto/sha3"
|
||||||
)
|
)
|
||||||
|
|
@ -240,3 +241,56 @@ func (a *UnprefixedAddress) UnmarshalText(input []byte) error {
|
||||||
func (a UnprefixedAddress) MarshalText() ([]byte, error) {
|
func (a UnprefixedAddress) MarshalText() ([]byte, error) {
|
||||||
return []byte(hex.EncodeToString(a[:])), nil
|
return []byte(hex.EncodeToString(a[:])), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MixedcaseAddress retains the original string, which may or may not be
|
||||||
|
// correctly checksummed
|
||||||
|
//
|
||||||
|
// TODO! Should we really keep both addr and original, or _only_ original, and
|
||||||
|
// always calculate addr on the fly? That would reduce the possibilities for errors
|
||||||
|
// if some caller modifies the original at some point. NB: If we do so, we should still
|
||||||
|
// parse the addr in UnmarshalJSON to ensure that the format is correct, e.g. correct size and
|
||||||
|
// hex-encoded and such
|
||||||
|
type MixedcaseAddress struct {
|
||||||
|
addr Address
|
||||||
|
original string
|
||||||
|
}
|
||||||
|
// NewMixedcaseAddress constructor (mainly for testing)
|
||||||
|
func NewMixedcaseAddress(addr Address) MixedcaseAddress {
|
||||||
|
return MixedcaseAddress{addr: addr, original: addr.Hex()}
|
||||||
|
}
|
||||||
|
|
||||||
|
// UnmarshalJSON parses MixedcaseAddress
|
||||||
|
func (ma *MixedcaseAddress) UnmarshalJSON(input []byte) error {
|
||||||
|
if err := hexutil.UnmarshalFixedJSON(addressT, input, ma.addr[:]); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return json.Unmarshal(input, &ma.original)
|
||||||
|
}
|
||||||
|
|
||||||
|
// MarshalJSON marshals the original value
|
||||||
|
func (ma *MixedcaseAddress) MarshalJSON() ([]byte, error) {
|
||||||
|
return json.Marshal(ma.original)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Address returns the address
|
||||||
|
func (ma *MixedcaseAddress) Address() Address {
|
||||||
|
return ma.addr
|
||||||
|
}
|
||||||
|
|
||||||
|
// String implements fmt.Stringer
|
||||||
|
func (ma *MixedcaseAddress) String() string {
|
||||||
|
if ma.ValidChecksum() {
|
||||||
|
return fmt.Sprintf("%s [chksum ok]", ma.original)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%s [chksum INVALID]", ma.original)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidChecksum returns true if the address has valid checksum
|
||||||
|
func (ma *MixedcaseAddress) ValidChecksum() bool {
|
||||||
|
return ma.original == ma.addr.Hex()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Original returns the mixed-case input string
|
||||||
|
func (ma *MixedcaseAddress) Original() string {
|
||||||
|
return ma.original
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ package common
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
|
||||||
"math/big"
|
"math/big"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
@ -149,3 +150,46 @@ func BenchmarkAddressHex(b *testing.B) {
|
||||||
testAddr.Hex()
|
testAddr.Hex()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestMixedcaseAccount_Address(t *testing.T) {
|
||||||
|
|
||||||
|
// https://github.com/ethereum/EIPs/blob/master/EIPS/eip-55.md
|
||||||
|
// Note: 0X{checksum_addr} is not valid according to spec above
|
||||||
|
|
||||||
|
var res []struct {
|
||||||
|
A MixedcaseAddress
|
||||||
|
Valid bool
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal([]byte(`[
|
||||||
|
{"A" : "0xae967917c465db8578ca9024c205720b1a3651A9", "Valid": false},
|
||||||
|
{"A" : "0xAe967917c465db8578ca9024c205720b1a3651A9", "Valid": true},
|
||||||
|
{"A" : "0XAe967917c465db8578ca9024c205720b1a3651A9", "Valid": false},
|
||||||
|
{"A" : "0x1111111111111111111112222222222223333323", "Valid": true}
|
||||||
|
]`), &res); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, r := range res {
|
||||||
|
if got := r.A.ValidChecksum(); got != r.Valid {
|
||||||
|
t.Errorf("Expected checksum %v, got checksum %v, input %v", r.Valid, got, r.A.String())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//These should throw exceptions:
|
||||||
|
var r2 []MixedcaseAddress
|
||||||
|
for _, r := range []string{
|
||||||
|
`["0x11111111111111111111122222222222233333"]`, // Too short
|
||||||
|
`["0x111111111111111111111222222222222333332"]`, // Too short
|
||||||
|
`["0x11111111111111111111122222222222233333234"]`, // Too long
|
||||||
|
`["0x111111111111111111111222222222222333332344"]`, // Too long
|
||||||
|
`["1111111111111111111112222222222223333323"]`, // Missing 0x
|
||||||
|
`["x1111111111111111111112222222222223333323"]`, // Missing 0
|
||||||
|
`["0xG111111111111111111112222222222223333323"]`, //Non-hex
|
||||||
|
} {
|
||||||
|
if err := json.Unmarshal([]byte(r), &r2); err == nil {
|
||||||
|
t.Errorf("Expected failure, input %v", r)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue