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 }