wallet.go 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. package pluggable
  2. import (
  3. "context"
  4. "math/big"
  5. "sync"
  6. "time"
  7. "github.com/ethereum/go-ethereum"
  8. "github.com/ethereum/go-ethereum/accounts"
  9. "github.com/ethereum/go-ethereum/common"
  10. "github.com/ethereum/go-ethereum/core/types"
  11. "github.com/ethereum/go-ethereum/crypto"
  12. plugin "github.com/ethereum/go-ethereum/plugin/account"
  13. )
  14. type wallet struct {
  15. url accounts.URL
  16. mu sync.Mutex
  17. pluginService plugin.Service
  18. }
  19. func (w *wallet) setPluginService(s plugin.Service) error {
  20. w.mu.Lock()
  21. defer w.mu.Unlock()
  22. w.pluginService = s
  23. return nil
  24. }
  25. func (w *wallet) URL() accounts.URL {
  26. return w.url
  27. }
  28. func (w *wallet) Status() (string, error) {
  29. return w.pluginService.Status(context.Background())
  30. }
  31. func (w *wallet) Open(passphrase string) error {
  32. return w.pluginService.Open(context.Background(), passphrase)
  33. }
  34. func (w *wallet) Close() error {
  35. return w.pluginService.Close(context.Background())
  36. }
  37. func (w *wallet) Accounts() []accounts.Account {
  38. if w.pluginService == nil {
  39. return []accounts.Account{}
  40. }
  41. return w.pluginService.Accounts(context.Background())
  42. }
  43. func (w *wallet) Contains(account accounts.Account) bool {
  44. return w.pluginService.Contains(context.Background(), account)
  45. }
  46. func (w *wallet) Derive(_ accounts.DerivationPath, _ bool) (accounts.Account, error) {
  47. return accounts.Account{}, accounts.ErrNotSupported
  48. }
  49. func (w *wallet) SelfDerive(_ []accounts.DerivationPath, _ ethereum.ChainStateReader) {}
  50. func (w *wallet) SignData(account accounts.Account, _ string, data []byte) ([]byte, error) {
  51. return w.pluginService.Sign(context.Background(), account, crypto.Keccak256(data))
  52. }
  53. func (w *wallet) SignDataWithPassphrase(account accounts.Account, passphrase, _ string, data []byte) ([]byte, error) {
  54. return w.pluginService.UnlockAndSign(context.Background(), account, crypto.Keccak256(data), passphrase)
  55. }
  56. func (w *wallet) SignText(account accounts.Account, text []byte) ([]byte, error) {
  57. return w.pluginService.Sign(context.Background(), account, accounts.TextHash(text))
  58. }
  59. func (w *wallet) SignTextWithPassphrase(account accounts.Account, passphrase string, text []byte) ([]byte, error) {
  60. return w.pluginService.UnlockAndSign(context.Background(), account, accounts.TextHash(text), passphrase)
  61. }
  62. func (w *wallet) SignTx(account accounts.Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) {
  63. toSign, signer := prepareTxForSign(tx, chainID)
  64. sig, err := w.pluginService.Sign(context.Background(), account, toSign.Bytes())
  65. if err != nil {
  66. return nil, err
  67. }
  68. return tx.WithSignature(signer, sig)
  69. }
  70. func (w *wallet) SignTxWithPassphrase(account accounts.Account, passphrase string, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) {
  71. toSign, signer := prepareTxForSign(tx, chainID)
  72. sig, err := w.pluginService.UnlockAndSign(context.Background(), account, toSign.Bytes(), passphrase)
  73. if err != nil {
  74. return nil, err
  75. }
  76. return tx.WithSignature(signer, sig)
  77. }
  78. func (w *wallet) timedUnlock(account accounts.Account, password string, duration time.Duration) error {
  79. return w.pluginService.TimedUnlock(context.Background(), account, password, duration)
  80. }
  81. func (w *wallet) lock(account accounts.Account) error {
  82. return w.pluginService.Lock(context.Background(), account)
  83. }
  84. func (w *wallet) newAccount(newAccountConfig interface{}) (accounts.Account, error) {
  85. return w.pluginService.NewAccount(context.Background(), newAccountConfig)
  86. }
  87. func (w *wallet) importRawKey(rawKey string, newAccountConfig interface{}) (accounts.Account, error) {
  88. return w.pluginService.ImportRawKey(context.Background(), rawKey, newAccountConfig)
  89. }
  90. // 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
  91. func prepareTxForSign(tx *types.Transaction, chainID *big.Int) (common.Hash, types.Signer) {
  92. var s types.Signer
  93. if tx.IsPrivate() {
  94. s = types.QuorumPrivateTxSigner{}
  95. } else {
  96. s = types.LatestSignerForChainID(chainID)
  97. }
  98. return s.Hash(tx), s
  99. }