github.com/klaytn/klaytn@v1.12.1/accounts/keystore/keystore_wallet.go (about)

     1  // Modifications Copyright 2018 The klaytn Authors
     2  // Copyright 2017 The go-ethereum Authors
     3  // This file is part of the go-ethereum library.
     4  //
     5  // The go-ethereum library is free software: you can redistribute it and/or modify
     6  // it under the terms of the GNU Lesser General Public License as published by
     7  // the Free Software Foundation, either version 3 of the License, or
     8  // (at your option) any later version.
     9  //
    10  // The go-ethereum library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    13  // GNU Lesser General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Lesser General Public License
    16  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    17  //
    18  // This file is derived from accounts/keystore/keystore_wallet.go (2018/06/04).
    19  // Modified and improved for the klaytn development.
    20  
    21  package keystore
    22  
    23  import (
    24  	"math/big"
    25  
    26  	"github.com/klaytn/klaytn"
    27  	"github.com/klaytn/klaytn/accounts"
    28  	"github.com/klaytn/klaytn/blockchain/types"
    29  )
    30  
    31  // keystoreWallet implements the accounts.Wallet interface for the original
    32  // keystore.
    33  type keystoreWallet struct {
    34  	account  accounts.Account // Single account contained in this wallet
    35  	keystore *KeyStore        // Keystore where the account originates from
    36  }
    37  
    38  // URL implements accounts.Wallet, returning the URL of the account within.
    39  func (w *keystoreWallet) URL() accounts.URL {
    40  	return w.account.URL
    41  }
    42  
    43  // Status implements accounts.Wallet, returning whether the account held by the
    44  // keystore wallet is unlocked or not.
    45  func (w *keystoreWallet) Status() (string, error) {
    46  	w.keystore.mu.RLock()
    47  	defer w.keystore.mu.RUnlock()
    48  
    49  	if _, ok := w.keystore.unlocked[w.account.Address]; ok {
    50  		return "Unlocked", nil
    51  	}
    52  	return "Locked", nil
    53  }
    54  
    55  // Open implements accounts.Wallet, but is a noop for plain wallets since there
    56  // is no connection or decryption step necessary to access the list of accounts.
    57  func (w *keystoreWallet) Open(passphrase string) error { return nil }
    58  
    59  // Close implements accounts.Wallet, but is a noop for plain wallets since is no
    60  // meaningful open operation.
    61  func (w *keystoreWallet) Close() error { return nil }
    62  
    63  // Accounts implements accounts.Wallet, returning an account list consisting of
    64  // a single account that the plain kestore wallet contains.
    65  func (w *keystoreWallet) Accounts() []accounts.Account {
    66  	return []accounts.Account{w.account}
    67  }
    68  
    69  // Contains implements accounts.Wallet, returning whether a particular account is
    70  // or is not wrapped by this wallet instance.
    71  func (w *keystoreWallet) Contains(account accounts.Account) bool {
    72  	return account.Address == w.account.Address && (account.URL == (accounts.URL{}) || account.URL == w.account.URL)
    73  }
    74  
    75  // Derive implements accounts.Wallet, but is a noop for plain wallets since there
    76  // is no notion of hierarchical account derivation for plain keystore accounts.
    77  func (w *keystoreWallet) Derive(path accounts.DerivationPath, pin bool) (accounts.Account, error) {
    78  	return accounts.Account{}, accounts.ErrNotSupported
    79  }
    80  
    81  // SelfDerive implements accounts.Wallet, but is a noop for plain wallets since
    82  // there is no notion of hierarchical account derivation for plain keystore accounts.
    83  func (w *keystoreWallet) SelfDerive(base accounts.DerivationPath, chain klaytn.ChainReader) {}
    84  
    85  // SignHash implements accounts.Wallet, attempting to sign the given hash with
    86  // the given account. If the wallet does not wrap this particular account, an
    87  // error is returned to avoid account leakage (even though in theory we may be
    88  // able to sign via our shared keystore backend).
    89  func (w *keystoreWallet) SignHash(account accounts.Account, hash []byte) ([]byte, error) {
    90  	// Make sure the requested account is contained within
    91  	if account.Address != w.account.Address {
    92  		return nil, accounts.ErrUnknownAccount
    93  	}
    94  	if account.URL != (accounts.URL{}) && account.URL != w.account.URL {
    95  		return nil, accounts.ErrUnknownAccount
    96  	}
    97  	// Account seems valid, request the keystore to sign
    98  	return w.keystore.SignHash(account, hash)
    99  }
   100  
   101  // SignTx implements accounts.Wallet, attempting to sign the given transaction
   102  // with the given account. If the wallet does not wrap this particular account,
   103  // an error is returned to avoid account leakage (even though in theory we may
   104  // be able to sign via our shared keystore backend).
   105  func (w *keystoreWallet) SignTx(account accounts.Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) {
   106  	// Make sure the requested account is contained within
   107  	if account.Address != w.account.Address {
   108  		return nil, accounts.ErrUnknownAccount
   109  	}
   110  	if account.URL != (accounts.URL{}) && account.URL != w.account.URL {
   111  		return nil, accounts.ErrUnknownAccount
   112  	}
   113  	// Account seems valid, request the keystore to sign
   114  	return w.keystore.SignTx(account, tx, chainID)
   115  }
   116  
   117  // SignTxAsFeePayer implements accounts.Wallet, attempting to sign the given
   118  // transaction as a fee payer with the given account. If the wallet does not
   119  // wrap this particular account, an error is returned to avoid account leakage
   120  // (even though in theory we may be able to sign via our shared keystore backend).
   121  func (w *keystoreWallet) SignTxAsFeePayer(account accounts.Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) {
   122  	// Make sure the requested account is contained within
   123  	if account.Address != w.account.Address {
   124  		return nil, accounts.ErrUnknownAccount
   125  	}
   126  	if account.URL != (accounts.URL{}) && account.URL != w.account.URL {
   127  		return nil, accounts.ErrUnknownAccount
   128  	}
   129  	// Account seems valid, request the keystore to sign
   130  	return w.keystore.SignTxAsFeePayer(account, tx, chainID)
   131  }
   132  
   133  // SignHashWithPassphrase implements accounts.Wallet, attempting to sign the
   134  // given hash with the given account using passphrase as extra authentication.
   135  func (w *keystoreWallet) SignHashWithPassphrase(account accounts.Account, passphrase string, hash []byte) ([]byte, error) {
   136  	// Make sure the requested account is contained within
   137  	if account.Address != w.account.Address {
   138  		return nil, accounts.ErrUnknownAccount
   139  	}
   140  	if account.URL != (accounts.URL{}) && account.URL != w.account.URL {
   141  		return nil, accounts.ErrUnknownAccount
   142  	}
   143  	// Account seems valid, request the keystore to sign
   144  	return w.keystore.SignHashWithPassphrase(account, passphrase, hash)
   145  }
   146  
   147  // SignTxWithPassphrase implements accounts.Wallet, attempting to sign the given
   148  // transaction with the given account using passphrase as extra authentication.
   149  func (w *keystoreWallet) SignTxWithPassphrase(account accounts.Account, passphrase string, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) {
   150  	// Make sure the requested account is contained within
   151  	if account.Address != w.account.Address {
   152  		return nil, accounts.ErrUnknownAccount
   153  	}
   154  	if account.URL != (accounts.URL{}) && account.URL != w.account.URL {
   155  		return nil, accounts.ErrUnknownAccount
   156  	}
   157  	// Account seems valid, request the keystore to sign
   158  	return w.keystore.SignTxWithPassphrase(account, passphrase, tx, chainID)
   159  }
   160  
   161  // SignTxAsFeePayerWithPassphrase implements accounts.Wallet, attempting to sign the given
   162  // transaction as a fee payer with the given account using passphrase as extra authentication.
   163  func (w *keystoreWallet) SignTxAsFeePayerWithPassphrase(account accounts.Account, passphrase string, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) {
   164  	// Make sure the requested account is contained within
   165  	if account.Address != w.account.Address {
   166  		return nil, accounts.ErrUnknownAccount
   167  	}
   168  	if account.URL != (accounts.URL{}) && account.URL != w.account.URL {
   169  		return nil, accounts.ErrUnknownAccount
   170  	}
   171  	// Account seems valid, request the keystore to sign
   172  	return w.keystore.SignTxAsFeePayerWithPassphrase(account, passphrase, tx, chainID)
   173  }