Skip to content
This repository has been archived by the owner on Nov 30, 2021. It is now read-only.

types: update account pubkey JSON to string #494

Merged
merged 9 commits into from
Sep 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ Ref: https://keepachangelog.com/en/1.0.0/

### Improvements

* (types) [\#494](https://github.com/ChainSafe/ethermint/pull/494) Update `EthAccount` public key JSON type to `string`.
* (app) [\#471](https://github.com/ChainSafe/ethermint/pull/471) Add `x/upgrade` module for managing software updates.
* (`x/evm`) [\#458](https://github.com/ChainSafe/ethermint/pull/458) Define parameter for token denomination used for the EVM module.
* (`x/evm`) [\#443](https://github.com/ChainSafe/ethermint/issues/443) Support custom Ethereum `ChainConfig` params.
Expand Down
20 changes: 15 additions & 5 deletions crypto/secp256k1.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func GenerateKey() (PrivKeySecp256k1, error) {
// PubKey returns the ECDSA private key's public key.
func (privkey PrivKeySecp256k1) PubKey() tmcrypto.PubKey {
ecdsaPKey := privkey.ToECDSA()
return PubKeySecp256k1(ethcrypto.FromECDSAPub(&ecdsaPKey.PublicKey))
return PubKeySecp256k1(ethcrypto.CompressPubkey(&ecdsaPKey.PublicKey))
}

// Bytes returns the raw ECDSA private key bytes.
Expand All @@ -58,8 +58,12 @@ func (privkey PrivKeySecp256k1) Equals(other tmcrypto.PrivKey) bool {
}

// ToECDSA returns the ECDSA private key as a reference to ecdsa.PrivateKey type.
// The function will panic if the private key is invalid.
func (privkey PrivKeySecp256k1) ToECDSA() *ecdsa.PrivateKey {
key, _ := ethcrypto.ToECDSA(privkey)
key, err := ethcrypto.ToECDSA(privkey)
if err != nil {
panic(err)
}
return key
}

Expand All @@ -68,17 +72,23 @@ func (privkey PrivKeySecp256k1) ToECDSA() *ecdsa.PrivateKey {

var _ tmcrypto.PubKey = (*PubKeySecp256k1)(nil)

// PubKeySecp256k1 defines a type alias for an ecdsa.PublicKey that implements
// Tendermint's PubKey interface.
// PubKeySecp256k1 defines a type alias for an ecdsa.PublicKey that implements Tendermint's PubKey
// interface. It represents the 33-byte compressed public key format.
type PubKeySecp256k1 []byte

// Address returns the address of the ECDSA public key.
// The function will panic if the public key is invalid.
func (key PubKeySecp256k1) Address() tmcrypto.Address {
pubk, _ := ethcrypto.UnmarshalPubkey(key)
pubk, err := ethcrypto.DecompressPubkey(key)
if err != nil {
panic(err)
}

return tmcrypto.Address(ethcrypto.PubkeyToAddress(*pubk).Bytes())
}

// Bytes returns the raw bytes of the ECDSA public key.
// The function panics if the key cannot be marshaled to bytes.
func (key PubKeySecp256k1) Bytes() []byte {
bz, err := CryptoCodec.MarshalBinaryBare(key)
if err != nil {
Expand Down
2 changes: 1 addition & 1 deletion docs/basics/accounts.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ Cosmos `sdk.AccAddress`.

- Address (Bech32): `eth1crwhac03z2pcgu88jfnqnwu66xlthlz2rhljah`
- Address (Hex): `0xc0dd7ee1f112838470e7926609bb9ad1bebbfc4a`
- Public Key (Bech32): `ethpub1pfqnmk6pqnwwuw0h9hj58t2hyzwvqc3truhhp5tl5hfucezcfy2rs8470nkyzju2vmk645fzmw2wveaqcqek767kwa0es9rmxe9nmmjq84cpny3fvj6tpg`
- Compressed Public Key (Bech32): `ethpub1pfqnmk6pqnwwuw0h9hj58t2hyzwvqc3truhhp5tl5hfucezcfy2rs8470nkyzju2vmk645fzmw2wveaqcqek767kwa0es9rmxe9nmmjq84cpny3fvj6tpg`

## Next {hide}

Expand Down
2 changes: 1 addition & 1 deletion tests/rpc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -758,7 +758,7 @@ func TestEth_EstimateGas(t *testing.T) {
err := json.Unmarshal(rpcRes.Result, &gas)
require.NoError(t, err, string(rpcRes.Result))

require.Equal(t, "0x1051d", gas)
require.Equal(t, "0xfd40", gas)
}

func TestEth_EstimateGas_ContractDeployment(t *testing.T) {
Expand Down
52 changes: 34 additions & 18 deletions types/account.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@ import (
"github.com/cosmos/cosmos-sdk/x/auth/exported"
authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"

tmamino "github.com/tendermint/tendermint/crypto/encoding/amino"

ethcmn "github.com/ethereum/go-ethereum/common"
ethcrypto "github.com/ethereum/go-ethereum/crypto"
)
Expand Down Expand Up @@ -79,7 +77,7 @@ func (acc *EthAccount) SetBalance(amt sdk.Int) {
type ethermintAccountPretty struct {
Address sdk.AccAddress `json:"address" yaml:"address"`
Coins sdk.Coins `json:"coins" yaml:"coins"`
PubKey []byte `json:"public_key" yaml:"public_key"`
PubKey string `json:"public_key" yaml:"public_key"`
AccountNumber uint64 `json:"account_number" yaml:"account_number"`
Sequence uint64 `json:"sequence" yaml:"sequence"`
CodeHash string `json:"code_hash" yaml:"code_hash"`
Expand All @@ -95,8 +93,13 @@ func (acc EthAccount) MarshalYAML() (interface{}, error) {
CodeHash: ethcmn.Bytes2Hex(acc.CodeHash),
}

var err error

if acc.PubKey != nil {
alias.PubKey = acc.PubKey.Bytes()
alias.PubKey, err = sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeAccPub, acc.PubKey)
if err != nil {
return nil, err
}
}

bz, err := yaml.Marshal(alias)
Expand All @@ -117,35 +120,48 @@ func (acc EthAccount) MarshalJSON() ([]byte, error) {
CodeHash: ethcmn.Bytes2Hex(acc.CodeHash),
}

var err error

if acc.PubKey != nil {
alias.PubKey = acc.PubKey.Bytes()
alias.PubKey, err = sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeAccPub, acc.PubKey)
if err != nil {
return nil, err
}
}

return json.Marshal(alias)
}

// UnmarshalJSON unmarshals raw JSON bytes into an EthAccount.
func (acc *EthAccount) UnmarshalJSON(bz []byte) error {
acc.BaseAccount = &authtypes.BaseAccount{}
var alias ethermintAccountPretty
var (
alias ethermintAccountPretty
err error
)

if err := json.Unmarshal(bz, &alias); err != nil {
return err
}

if alias.PubKey != nil {
pubKey, err := tmamino.PubKeyFromBytes(alias.PubKey)
acc.BaseAccount = &authtypes.BaseAccount{
Coins: alias.Coins,
Address: alias.Address,
AccountNumber: alias.AccountNumber,
Sequence: alias.Sequence,
}
acc.CodeHash = ethcmn.Hex2Bytes(alias.CodeHash)

if alias.PubKey != "" {
acc.BaseAccount.PubKey, err = sdk.GetPubKeyFromBech32(sdk.Bech32PubKeyTypeAccPub, alias.PubKey)
if err != nil {
return err
}

acc.BaseAccount.PubKey = pubKey
}

acc.BaseAccount.Coins = alias.Coins
acc.BaseAccount.Address = alias.Address
acc.BaseAccount.AccountNumber = alias.AccountNumber
acc.BaseAccount.Sequence = alias.Sequence
acc.CodeHash = ethcmn.Hex2Bytes(alias.CodeHash)

return nil
}

// String implements the fmt.Stringer interface
func (acc EthAccount) String() string {
out, _ := yaml.Marshal(acc)
return string(out)
}
55 changes: 54 additions & 1 deletion types/account_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package types

import (
"encoding/json"
"fmt"
"testing"

"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -35,7 +36,7 @@ func TestEthermintAccountJSON(t *testing.T) {
require.Equal(t, string(bz1), string(bz))

var a EthAccount
require.NoError(t, json.Unmarshal(bz, &a))
require.NoError(t, a.UnmarshalJSON(bz))
require.Equal(t, ethAcc.String(), a.String())
require.Equal(t, ethAcc.PubKey, a.PubKey)
}
Expand All @@ -58,3 +59,55 @@ func TestSecpPubKeyJSON(t *testing.T) {
require.NoError(t, err)
require.Equal(t, pubk, pubkey)
}

func TestEthermintAccount_String(t *testing.T) {
pubkey := secp256k1.GenPrivKey().PubKey()
addr := sdk.AccAddress(pubkey.Address())
balance := sdk.NewCoins(sdk.NewCoin(DenomDefault, sdk.OneInt()))
baseAcc := auth.NewBaseAccount(addr, balance, pubkey, 10, 50)
ethAcc := EthAccount{BaseAccount: baseAcc, CodeHash: []byte{1, 2}}

config := sdk.GetConfig()
SetBech32Prefixes(config)

bech32pubkey, err := sdk.Bech32ifyPubKey(sdk.Bech32PubKeyTypeAccPub, pubkey)
require.NoError(t, err)

accountStr := fmt.Sprintf(`|
address: %s
coins:
- denom: aphoton
amount: "1"
public_key: %s
account_number: 10
sequence: 50
code_hash: "0102"
`, addr, bech32pubkey)

require.Equal(t, accountStr, ethAcc.String())

i, err := ethAcc.MarshalYAML()
require.NoError(t, err)

var ok bool
accountStr, ok = i.(string)
require.True(t, ok)
require.Contains(t, accountStr, addr.String())
require.Contains(t, accountStr, bech32pubkey)
}

func TestEthermintAccount_MarshalJSON(t *testing.T) {
pubkey := secp256k1.GenPrivKey().PubKey()
addr := sdk.AccAddress(pubkey.Address())
balance := sdk.NewCoins(sdk.NewCoin(DenomDefault, sdk.OneInt()))
baseAcc := auth.NewBaseAccount(addr, balance, pubkey, 10, 50)
ethAcc := &EthAccount{BaseAccount: baseAcc, CodeHash: []byte{1, 2}}

bz, err := ethAcc.MarshalJSON()
require.NoError(t, err)

res := new(EthAccount)
err = res.UnmarshalJSON(bz)
require.NoError(t, err)
require.Equal(t, ethAcc, res)
}
4 changes: 4 additions & 0 deletions types/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ import (

func TestSetBech32Prefixes(t *testing.T) {
config := sdk.GetConfig()
config = sdk.NewConfig() // reset config values

require.Equal(t, sdk.Bech32PrefixAccAddr, config.GetBech32AccountAddrPrefix())
require.Equal(t, sdk.Bech32PrefixAccPub, config.GetBech32AccountPubPrefix())
require.Equal(t, sdk.Bech32PrefixValAddr, config.GetBech32ValidatorAddrPrefix())
Expand All @@ -36,8 +38,10 @@ func TestSetBech32Prefixes(t *testing.T) {
func TestSetCoinType(t *testing.T) {
config := sdk.GetConfig()
require.Equal(t, sdk.CoinType, int(config.GetCoinType()))
require.Equal(t, sdk.FullFundraiserPath, config.GetFullFundraiserPath())

SetBip44CoinType(config)
require.Equal(t, Bip44CoinType, int(config.GetCoinType()))
require.Equal(t, sdk.GetConfig().GetCoinType(), config.GetCoinType())
require.Equal(t, sdk.GetConfig().GetFullFundraiserPath(), config.GetFullFundraiserPath())
}