Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

internal/ethapi: make NewAccount return EIP-55 format #26973

Merged
merged 3 commits into from
May 17, 2023

Conversation

alexmylonas
Copy link
Contributor

@alexmylonas alexmylonas commented Mar 24, 2023

This PR implements the suggestion of #24406 to return the address as EIP-55 encoded when creating a new account.

@lightclient lightclient changed the title [ethapi] updated NewAccount to return address as EIP-55 format internal/ethapi: updated NewAccount to return address as EIP-55 format Mar 24, 2023
@@ -354,19 +354,19 @@ func (s *PersonalAccountAPI) DeriveAccount(url string, path string, pin *bool) (
}

// NewAccount will create a new account and returns the address for the new account.
func (s *PersonalAccountAPI) NewAccount(password string) (common.Address, error) {
func (s *PersonalAccountAPI) NewAccount(password string) (string, error) {
Copy link
Member

@rjl493456442 rjl493456442 Mar 28, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An alternative approach is to define the customized json marshaller

e.g.

func (a Address) MarshalJSON() ([]byte, error) {
	return json.Marshal(a.Hex())
}

But in this case, the address will always be marshalled in checksum'd format. I am not sure this is what we want.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or we can define ChecksumedAddress type which has this customized marshal rule and return it instead.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or we can define ChecksumedAddress type which has this customized marshal rule and return it instead.

👍 from me. AddressEIP55 or AddressWithChecksum or EIP55Address maybe?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Like adding something like this in types.go?

type AddressEIP55 [AddressEIP55Length]byte // AddressEIP55Length is 42

// NewAddressEIP55 creates a new AddressEIP55 from an Address.
func NewAddressEIP55(addr Address) AddressEIP55 {
	return BytesToAddressEIP(addr.checksumHex())
}

func BytesToAddressEIP(b []byte) AddressEIP55 {
	var a AddressEIP55
	copy(a[:], b)
	return a
}

func (a AddressEIP55) String() string {
	return string(a[:])
}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

diff --git a/common/types.go b/common/types.go
index 218ca0be4c..1431857372 100644
--- a/common/types.go
+++ b/common/types.go
@@ -429,3 +429,12 @@ func (ma *MixedcaseAddress) ValidChecksum() bool {
 func (ma *MixedcaseAddress) Original() string {
 	return ma.original
 }
+
+// AddressEIP55 is an alias of Address with a customized json marshaller
+// defined in the manner of EIP55.
+type AddressEIP55 Address
+
+// MarshalJSON marshals the address in the manner of EIP55.
+func (addr AddressEIP55) MarshalJSON() ([]byte, error) {
+	return json.Marshal(Address(addr).Hex())
+}
diff --git a/common/types_test.go b/common/types_test.go
index 94492278d8..d41b4b1d7e 100644
--- a/common/types_test.go
+++ b/common/types_test.go
@@ -534,3 +534,21 @@ func TestHash_Format(t *testing.T) {
 		})
 	}
 }
+
+func TestAddressEIP55(t *testing.T) {
+	addr := HexToAddress("0x5aaeb6053f3e94c9b9a09f33669435e7ef1beaed")
+	blob, err := json.Marshal(AddressEIP55(addr))
+	if err != nil {
+		t.Fatal("Failed to marshal AddressEIP55", err)
+	}
+	if strings.Trim(string(blob), "\"") != addr.Hex() {
+		t.Fatal("Address with checksum is expected")
+	}
+	var dec Address
+	if err := json.Unmarshal(blob, &dec); err != nil {
+		t.Fatal("Failed to unmarshal AddressEIP55", err)
+	}
+	if addr != dec {
+		t.Fatal("Unexpected address after unmarshal")
+	}
+}

A very quick implementation. You can probably polish a bit on top.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the feedback @rjl493456442!

Pushed a commit that addresses this properly I hope!

Copy link
Contributor

@holiman holiman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally LGTM, but maybe we don't need all that

Comment on lines 173 to 189
func TestNewPersonalAccount(t *testing.T) {
d := t.TempDir()
ks := keystore.NewKeyStore(d, keystore.StandardScryptN, keystore.StandardScryptP)
b := &backendTest{
backends: []accounts.Backend{ks},
}
nonceLock := new(AddrLocker)
pa := NewPersonalAccountAPI(b, nonceLock)
addr, err := pa.NewAccount("password")
if err != nil {
t.Fatalf("failed to create account: %v", err)
}

if !common.IsHexAddress(addr.String()) {
t.Fatalf("address isn't hex encoded: %s", addr)
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure this test really brings anything new? All it does it tests

  1. That an account can be created
  2. That the response is hex-encoded

Unless I missed something, might aswell remove it

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that is exactly what it does.

I saw that this part of the codebase didn't have much unit testing and took it as an opportunity to add a couple.

I can remove it if you feel is superficial!

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for late response. Yes, please remove it, IMO it doesn't add anything. Since you are using NewPersonalAccountApi (not going via any url dispatcher), you are guaranteed to obtain a common.AddressEIP55.
The check common.IsHex.. is basically a long-winded unit-test, and IsHex doesn't even check anything related to EIP-55.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that makes sense while it helped me validate that this actually works initially, I can see it doesn't add a lot in terms of testing. Reverted!

internal/ethapi/api_test.go Outdated Show resolved Hide resolved
Copy link
Contributor

@holiman holiman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@holiman holiman added this to the 1.11.7 milestone May 17, 2023
@holiman holiman changed the title internal/ethapi: updated NewAccount to return address as EIP-55 format internal/ethapi: make NewAccount return EIP-55 format May 17, 2023
@holiman holiman merged commit ae1d90e into ethereum:master May 17, 2023
devopsbo3 pushed a commit to HorizenOfficial/go-ethereum that referenced this pull request Nov 10, 2023
This change implements returning the address as EIP-55 encoded when creating a new account.
devopsbo3 added a commit to HorizenOfficial/go-ethereum that referenced this pull request Nov 10, 2023
devopsbo3 added a commit to HorizenOfficial/go-ethereum that referenced this pull request Nov 10, 2023
@alexmylonas alexmylonas deleted the new-account-eip55 branch September 13, 2024 05:10
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants