Skip to content

Commit

Permalink
improved code readability (base#11)
Browse files Browse the repository at this point in the history
* Update ecdsa_signer.go

added comments to describe each method and rephrased some variable names for clarity.

* Update signer.go

Provided comments for each function describing their purpose  and made some minor improvements for clarity.

* Update wallet_signer.go

 provided comments for each function describing their purpose in and made some minor improvements for clarity.
  • Loading branch information
maxpv026 authored Feb 28, 2024
1 parent 76ae514 commit 6f1cb07
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 11 deletions.
8 changes: 7 additions & 1 deletion signer/ecdsa_signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,29 @@ import (
"github.com/ethereum/go-ethereum/crypto"
)

// ecdsaSigner represents an ECDSA signer.
type ecdsaSigner struct {
*ecdsa.PrivateKey
}

// Address returns the address associated with the ECDSA signer.
func (s *ecdsaSigner) Address() common.Address {
return crypto.PubkeyToAddress(s.PublicKey)
}

// SignerFn returns a signer function using the ECDSA private key and chain ID.
func (s *ecdsaSigner) SignerFn(chainID *big.Int) bind.SignerFn {
return opcrypto.PrivateKeySignerFn(s.PrivateKey, chainID)
}

// SignData signs the given data using the ECDSA private key.
func (s *ecdsaSigner) SignData(data []byte) ([]byte, error) {
sig, err := crypto.Sign(crypto.Keccak256(data), s.PrivateKey)
if err != nil {
return nil, err
}
// Adjust the recovery ID for Ethereum compatibility
sig[crypto.RecoveryIDOffset] += 27
return sig, err
return sig, nil
}

22 changes: 12 additions & 10 deletions signer/signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,12 +11,14 @@ import (
"github.com/ethereum/go-ethereum/crypto"
)

// Signer defines the interface for interacting with different types of signers.
type Signer interface {
Address() common.Address
SignerFn(chainID *big.Int) bind.SignerFn
SignData([]byte) ([]byte, error)
Address() common.Address // Address returns the Ethereum address associated with the signer.
SignerFn(chainID *big.Int) bind.SignerFn // SignerFn returns a signer function used for transaction signing.
SignData([]byte) ([]byte, error) // SignData signs the given data using the signer's private key.
}

// CreateSigner creates a signer based on the provided private key, mnemonic, or hardware wallet.
func CreateSigner(privateKey, mnemonic, hdPath string) (Signer, error) {
if privateKey != "" {
key, err := crypto.HexToECDSA(privateKey)
Expand All @@ -32,31 +34,31 @@ func CreateSigner(privateKey, mnemonic, hdPath string) (Signer, error) {
}

if mnemonic != "" {
key, err := derivePrivateKey(mnemonic, path)
key, err := derivePrivateKeyFromMnemonic(mnemonic, path)
if err != nil {
return nil, fmt.Errorf("error deriving key from mnemonic: %w", err)
}
return &ecdsaSigner{key}, nil
}

// assume using a ledger
// Assume using a hardware wallet (e.g., Ledger)
ledgerHub, err := usbwallet.NewLedgerHub()
if err != nil {
return nil, fmt.Errorf("error starting ledger: %w", err)
return nil, fmt.Errorf("error starting Ledger: %w", err)
}
wallets := ledgerHub.Wallets()
if len(wallets) == 0 {
return nil, fmt.Errorf("no ledgers found, please connect your ledger")
return nil, fmt.Errorf("no Ledger device found, please connect your Ledger")
} else if len(wallets) > 1 {
return nil, fmt.Errorf("multiple ledgers found, please use one ledger at a time")
return nil, fmt.Errorf("multiple Ledger devices found, please use only one at a time")
}
wallet := wallets[0]
if err := wallet.Open(""); err != nil {
return nil, fmt.Errorf("error opening ledger: %w", err)
return nil, fmt.Errorf("error opening Ledger: %w", err)
}
account, err := wallet.Derive(path, true)
if err != nil {
return nil, fmt.Errorf("error deriving ledger account (have you unlocked?): %w", err)
return nil, fmt.Errorf("error deriving Ledger account (have you unlocked?): %w", err)
}
return &walletSigner{
wallet: wallet,
Expand Down
8 changes: 8 additions & 0 deletions signer/wallet_signer.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,32 +13,38 @@ import (
"github.com/tyler-smith/go-bip39"
)

// walletSigner represents a signer based on a wallet account.
type walletSigner struct {
wallet accounts.Wallet
account accounts.Account
}

// Address returns the Ethereum address associated with the signer.
func (s *walletSigner) Address() common.Address {
return s.account.Address
}

// SignerFn returns a signer function used for transaction signing.
func (s *walletSigner) SignerFn(chainID *big.Int) bind.SignerFn {
return func(address common.Address, tx *types.Transaction) (*types.Transaction, error) {
return s.wallet.SignTx(s.account, tx, chainID)
}
}

// SignData signs the given data using the signer's private key.
func (s *walletSigner) SignData(data []byte) ([]byte, error) {
return s.wallet.SignData(s.account, accounts.MimetypeTypedData, data)
}

// derivePrivateKey derives an ECDSA private key from a mnemonic phrase and derivation path.
func derivePrivateKey(mnemonic string, path accounts.DerivationPath) (*ecdsa.PrivateKey, error) {
// Parse the seed string into the master BIP32 key.
seed, err := bip39.NewSeedWithErrorChecking(mnemonic, "")
if err != nil {
return nil, err
}

// Derive the private key based on the derivation path.
privKey, err := hdkeychain.NewMaster(seed, fakeNetworkParams{})
if err != nil {
return nil, err
Expand All @@ -51,6 +57,7 @@ func derivePrivateKey(mnemonic string, path accounts.DerivationPath) (*ecdsa.Pri
}
}

// Serialize the private key and convert it to an ECDSA private key.
rawPrivKey, err := privKey.SerializedPrivKey()
if err != nil {
return nil, err
Expand All @@ -59,6 +66,7 @@ func derivePrivateKey(mnemonic string, path accounts.DerivationPath) (*ecdsa.Pri
return crypto.ToECDSA(rawPrivKey)
}

// fakeNetworkParams is used for HD key derivation and provides fake network parameters.
type fakeNetworkParams struct{}

func (f fakeNetworkParams) HDPrivKeyVersion() [4]byte {
Expand Down

0 comments on commit 6f1cb07

Please sign in to comment.