github.com/ConsenSys/Quorum@v20.10.0+incompatible/accounts/pluggable/wallet.go (about) 1 package pluggable 2 3 import ( 4 "context" 5 "math/big" 6 "sync" 7 "time" 8 9 "github.com/ethereum/go-ethereum" 10 "github.com/ethereum/go-ethereum/accounts" 11 "github.com/ethereum/go-ethereum/common" 12 "github.com/ethereum/go-ethereum/core/types" 13 "github.com/ethereum/go-ethereum/crypto" 14 plugin "github.com/ethereum/go-ethereum/plugin/account" 15 ) 16 17 type wallet struct { 18 url accounts.URL 19 mu sync.Mutex 20 pluginService plugin.Service 21 } 22 23 func (w *wallet) setPluginService(s plugin.Service) error { 24 w.mu.Lock() 25 defer w.mu.Unlock() 26 27 w.pluginService = s 28 29 return nil 30 } 31 32 func (w *wallet) URL() accounts.URL { 33 return w.url 34 } 35 36 func (w *wallet) Status() (string, error) { 37 return w.pluginService.Status(context.Background()) 38 } 39 40 func (w *wallet) Open(passphrase string) error { 41 return w.pluginService.Open(context.Background(), passphrase) 42 } 43 44 func (w *wallet) Close() error { 45 return w.pluginService.Close(context.Background()) 46 } 47 48 func (w *wallet) Accounts() []accounts.Account { 49 return w.pluginService.Accounts(context.Background()) 50 } 51 52 func (w *wallet) Contains(account accounts.Account) bool { 53 return w.pluginService.Contains(context.Background(), account) 54 } 55 56 func (w *wallet) Derive(_ accounts.DerivationPath, _ bool) (accounts.Account, error) { 57 return accounts.Account{}, accounts.ErrNotSupported 58 } 59 60 func (w *wallet) SelfDerive(_ []accounts.DerivationPath, _ ethereum.ChainStateReader) {} 61 62 func (w *wallet) SignData(account accounts.Account, _ string, data []byte) ([]byte, error) { 63 return w.pluginService.Sign(context.Background(), account, crypto.Keccak256(data)) 64 } 65 66 func (w *wallet) SignDataWithPassphrase(account accounts.Account, passphrase, _ string, data []byte) ([]byte, error) { 67 return w.pluginService.UnlockAndSign(context.Background(), account, crypto.Keccak256(data), passphrase) 68 } 69 70 func (w *wallet) SignText(account accounts.Account, text []byte) ([]byte, error) { 71 return w.pluginService.Sign(context.Background(), account, accounts.TextHash(text)) 72 } 73 74 func (w *wallet) SignTextWithPassphrase(account accounts.Account, passphrase string, text []byte) ([]byte, error) { 75 return w.pluginService.UnlockAndSign(context.Background(), account, accounts.TextHash(text), passphrase) 76 } 77 78 func (w *wallet) SignTx(account accounts.Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { 79 toSign, signer := prepareTxForSign(tx, chainID) 80 81 sig, err := w.pluginService.Sign(context.Background(), account, toSign.Bytes()) 82 if err != nil { 83 return nil, err 84 } 85 86 return tx.WithSignature(signer, sig) 87 } 88 89 func (w *wallet) SignTxWithPassphrase(account accounts.Account, passphrase string, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) { 90 toSign, signer := prepareTxForSign(tx, chainID) 91 92 sig, err := w.pluginService.UnlockAndSign(context.Background(), account, toSign.Bytes(), passphrase) 93 if err != nil { 94 return nil, err 95 } 96 97 return tx.WithSignature(signer, sig) 98 } 99 100 func (w *wallet) timedUnlock(account accounts.Account, password string, duration time.Duration) error { 101 return w.pluginService.TimedUnlock(context.Background(), account, password, duration) 102 } 103 104 func (w *wallet) lock(account accounts.Account) error { 105 return w.pluginService.Lock(context.Background(), account) 106 } 107 108 func (w *wallet) newAccount(newAccountConfig interface{}) (accounts.Account, error) { 109 return w.pluginService.NewAccount(context.Background(), newAccountConfig) 110 } 111 112 func (w *wallet) importRawKey(rawKey string, newAccountConfig interface{}) (accounts.Account, error) { 113 return w.pluginService.ImportRawKey(context.Background(), rawKey, newAccountConfig) 114 } 115 116 // prepareTxForSign determines which Signer to use for the given tx and chainID, and returns the Signer's hash of the tx and the Signer itself 117 func prepareTxForSign(tx *types.Transaction, chainID *big.Int) (common.Hash, types.Signer) { 118 var s types.Signer 119 120 if tx.IsPrivate() { 121 s = types.QuorumPrivateTxSigner{} 122 } else if chainID == nil { 123 s = types.HomesteadSigner{} 124 } else { 125 s = types.NewEIP155Signer(chainID) 126 } 127 128 return s.Hash(tx), s 129 }