gitlab.com/flarenetwork/coreth@v0.1.1/accounts/keystore/wallet.go (about)

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