| 
									
										
										
										
											2017-01-24 11:49:20 +02:00
										 |  |  | // Copyright 2017 The go-ethereum Authors | 
					
						
							|  |  |  | // This file is part of the go-ethereum library. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // The go-ethereum library is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  | // it under the terms of the GNU Lesser General Public License as published by | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  | // (at your option) any later version. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // The go-ethereum library is distributed in the hope that it will be useful, | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 
					
						
							|  |  |  | // GNU Lesser General Public License for more details. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // You should have received a copy of the GNU Lesser General Public License | 
					
						
							|  |  |  | // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // Package accounts implements high level Ethereum account management. | 
					
						
							|  |  |  | package accounts | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
											
												accounts, eth, clique, signer: support for external signer API  (#18079)
* accounts, eth, clique: implement external backend + move sighash calc to backend
* signer: implement account_Version on external API
* accounts/external: enable ipc, add copyright
* accounts, internal, signer: formatting
* node: go fmt
* flags: disallow --dev in combo with --externalsigner
* accounts: remove clique-specific signing method, replace with more generic
* accounts, consensus: formatting + fix error in tests
* signer/core: remove (test-) import cycle
* clique: remove unused import
* accounts: remove CliqueHash and avoid dependency on package crypto
* consensus/clique: unduplicate header encoding
											
										 
											2019-02-05 11:23:57 +01:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2017-01-24 11:49:20 +02:00
										 |  |  | 	"math/big" | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-08 20:25:52 +02:00
										 |  |  | 	ethereum "github.com/ethereum/go-ethereum" | 
					
						
							| 
									
										
										
										
											2017-01-24 11:49:20 +02:00
										 |  |  | 	"github.com/ethereum/go-ethereum/common" | 
					
						
							|  |  |  | 	"github.com/ethereum/go-ethereum/core/types" | 
					
						
							| 
									
										
										
										
											2017-02-07 12:47:34 +02:00
										 |  |  | 	"github.com/ethereum/go-ethereum/event" | 
					
						
							| 
									
										
										
											
												accounts, eth, clique, signer: support for external signer API  (#18079)
* accounts, eth, clique: implement external backend + move sighash calc to backend
* signer: implement account_Version on external API
* accounts/external: enable ipc, add copyright
* accounts, internal, signer: formatting
* node: go fmt
* flags: disallow --dev in combo with --externalsigner
* accounts: remove clique-specific signing method, replace with more generic
* accounts, consensus: formatting + fix error in tests
* signer/core: remove (test-) import cycle
* clique: remove unused import
* accounts: remove CliqueHash and avoid dependency on package crypto
* consensus/clique: unduplicate header encoding
											
										 
											2019-02-05 11:23:57 +01:00
										 |  |  | 	"golang.org/x/crypto/sha3" | 
					
						
							| 
									
										
										
										
											2017-01-24 11:49:20 +02:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-07 12:47:34 +02:00
										 |  |  | // Account represents an Ethereum account located at a specific location defined | 
					
						
							|  |  |  | // by the optional URL field. | 
					
						
							| 
									
										
										
										
											2017-01-24 11:49:20 +02:00
										 |  |  | type Account struct { | 
					
						
							| 
									
										
										
										
											2017-02-07 12:47:34 +02:00
										 |  |  | 	Address common.Address `json:"address"` // Ethereum account address derived from the key | 
					
						
							| 
									
										
										
										
											2017-02-08 15:53:02 +02:00
										 |  |  | 	URL     URL            `json:"url"`     // Optional resource locator within a backend | 
					
						
							| 
									
										
										
										
											2017-01-24 11:49:20 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-07 12:47:34 +02:00
										 |  |  | // Wallet represents a software or hardware wallet that might contain one or more | 
					
						
							|  |  |  | // accounts (derived from the same seed). | 
					
						
							|  |  |  | type Wallet interface { | 
					
						
							|  |  |  | 	// URL retrieves the canonical path under which this wallet is reachable. It is | 
					
						
							|  |  |  | 	// user by upper layers to define a sorting order over all wallets from multiple | 
					
						
							|  |  |  | 	// backends. | 
					
						
							| 
									
										
										
										
											2017-02-08 15:53:02 +02:00
										 |  |  | 	URL() URL | 
					
						
							| 
									
										
										
										
											2017-02-07 12:47:34 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Status returns a textual status to aid the user in the current state of the | 
					
						
							| 
									
										
										
										
											2017-08-09 12:51:16 +03:00
										 |  |  | 	// wallet. It also returns an error indicating any failure the wallet might have | 
					
						
							|  |  |  | 	// encountered. | 
					
						
							|  |  |  | 	Status() (string, error) | 
					
						
							| 
									
										
										
										
											2017-02-07 12:47:34 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// Open initializes access to a wallet instance. It is not meant to unlock or | 
					
						
							|  |  |  | 	// decrypt account keys, rather simply to establish a connection to hardware | 
					
						
							|  |  |  | 	// wallets and/or to access derivation seeds. | 
					
						
							|  |  |  | 	// | 
					
						
							|  |  |  | 	// The passphrase parameter may or may not be used by the implementation of a | 
					
						
							|  |  |  | 	// particular wallet instance. The reason there is no passwordless open method | 
					
						
							|  |  |  | 	// is to strive towards a uniform wallet handling, oblivious to the different | 
					
						
							|  |  |  | 	// backend providers. | 
					
						
							|  |  |  | 	// | 
					
						
							|  |  |  | 	// Please note, if you open a wallet, you must close it to release any allocated | 
					
						
							|  |  |  | 	// resources (especially important when working with hardware wallets). | 
					
						
							|  |  |  | 	Open(passphrase string) error | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Close releases any resources held by an open wallet instance. | 
					
						
							|  |  |  | 	Close() error | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Accounts retrieves the list of signing accounts the wallet is currently aware | 
					
						
							|  |  |  | 	// of. For hierarchical deterministic wallets, the list will not be exhaustive, | 
					
						
							|  |  |  | 	// rather only contain the accounts explicitly pinned during account derivation. | 
					
						
							|  |  |  | 	Accounts() []Account | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Contains returns whether an account is part of this particular wallet or not. | 
					
						
							|  |  |  | 	Contains(account Account) bool | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Derive attempts to explicitly derive a hierarchical deterministic account at | 
					
						
							|  |  |  | 	// the specified derivation path. If requested, the derived account will be added | 
					
						
							|  |  |  | 	// to the wallet's tracked account list. | 
					
						
							| 
									
										
										
										
											2017-02-08 20:25:52 +02:00
										 |  |  | 	Derive(path DerivationPath, pin bool) (Account, error) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// SelfDerive sets a base account derivation path from which the wallet attempts | 
					
						
							|  |  |  | 	// to discover non zero accounts and automatically add them to list of tracked | 
					
						
							|  |  |  | 	// accounts. | 
					
						
							|  |  |  | 	// | 
					
						
							|  |  |  | 	// Note, self derivaton will increment the last component of the specified path | 
					
						
							|  |  |  | 	// opposed to decending into a child path to allow discovering accounts starting | 
					
						
							|  |  |  | 	// from non zero components. | 
					
						
							|  |  |  | 	// | 
					
						
							|  |  |  | 	// You can disable automatic account discovery by calling SelfDerive with a nil | 
					
						
							|  |  |  | 	// chain state reader. | 
					
						
							|  |  |  | 	SelfDerive(base DerivationPath, chain ethereum.ChainStateReader) | 
					
						
							| 
									
										
										
										
											2017-02-07 12:47:34 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
											
												accounts, eth, clique, signer: support for external signer API  (#18079)
* accounts, eth, clique: implement external backend + move sighash calc to backend
* signer: implement account_Version on external API
* accounts/external: enable ipc, add copyright
* accounts, internal, signer: formatting
* node: go fmt
* flags: disallow --dev in combo with --externalsigner
* accounts: remove clique-specific signing method, replace with more generic
* accounts, consensus: formatting + fix error in tests
* signer/core: remove (test-) import cycle
* clique: remove unused import
* accounts: remove CliqueHash and avoid dependency on package crypto
* consensus/clique: unduplicate header encoding
											
										 
											2019-02-05 11:23:57 +01:00
										 |  |  | 	// SignData requests the wallet to sign the hash of the given data | 
					
						
							|  |  |  | 	// It looks up the account specified either solely via its address contained within, | 
					
						
							|  |  |  | 	// or optionally with the aid of any location metadata from the embedded URL field. | 
					
						
							| 
									
										
										
										
											2017-02-07 12:47:34 +02:00
										 |  |  | 	// | 
					
						
							| 
									
										
										
											
												accounts, eth, clique, signer: support for external signer API  (#18079)
* accounts, eth, clique: implement external backend + move sighash calc to backend
* signer: implement account_Version on external API
* accounts/external: enable ipc, add copyright
* accounts, internal, signer: formatting
* node: go fmt
* flags: disallow --dev in combo with --externalsigner
* accounts: remove clique-specific signing method, replace with more generic
* accounts, consensus: formatting + fix error in tests
* signer/core: remove (test-) import cycle
* clique: remove unused import
* accounts: remove CliqueHash and avoid dependency on package crypto
* consensus/clique: unduplicate header encoding
											
										 
											2019-02-05 11:23:57 +01:00
										 |  |  | 	// If the wallet requires additional authentication to sign the request (e.g. | 
					
						
							|  |  |  | 	// a password to decrypt the account, or a PIN code o verify the transaction), | 
					
						
							|  |  |  | 	// an AuthNeededError instance will be returned, containing infos for the user | 
					
						
							|  |  |  | 	// about which fields or actions are needed. The user may retry by providing | 
					
						
							|  |  |  | 	// the needed details via SignHashWithPassphrase, or by other means (e.g. unlock | 
					
						
							|  |  |  | 	// the account in a keystore). | 
					
						
							|  |  |  | 	SignData(account Account, mimeType string, data []byte) ([]byte, error) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Signtext requests the wallet to sign the hash of a given piece of data, prefixed | 
					
						
							|  |  |  | 	// by the Ethereum prefix scheme | 
					
						
							| 
									
										
										
										
											2017-02-07 12:47:34 +02:00
										 |  |  | 	// It looks up the account specified either solely via its address contained within, | 
					
						
							|  |  |  | 	// or optionally with the aid of any location metadata from the embedded URL field. | 
					
						
							|  |  |  | 	// | 
					
						
							|  |  |  | 	// If the wallet requires additional authentication to sign the request (e.g. | 
					
						
							|  |  |  | 	// a password to decrypt the account, or a PIN code o verify the transaction), | 
					
						
							|  |  |  | 	// an AuthNeededError instance will be returned, containing infos for the user | 
					
						
							|  |  |  | 	// about which fields or actions are needed. The user may retry by providing | 
					
						
							|  |  |  | 	// the needed details via SignHashWithPassphrase, or by other means (e.g. unlock | 
					
						
							|  |  |  | 	// the account in a keystore). | 
					
						
							| 
									
										
										
											
												accounts, eth, clique, signer: support for external signer API  (#18079)
* accounts, eth, clique: implement external backend + move sighash calc to backend
* signer: implement account_Version on external API
* accounts/external: enable ipc, add copyright
* accounts, internal, signer: formatting
* node: go fmt
* flags: disallow --dev in combo with --externalsigner
* accounts: remove clique-specific signing method, replace with more generic
* accounts, consensus: formatting + fix error in tests
* signer/core: remove (test-) import cycle
* clique: remove unused import
* accounts: remove CliqueHash and avoid dependency on package crypto
* consensus/clique: unduplicate header encoding
											
										 
											2019-02-05 11:23:57 +01:00
										 |  |  | 	SignText(account Account, text []byte) ([]byte, error) | 
					
						
							| 
									
										
										
										
											2017-02-07 12:47:34 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// SignTx requests the wallet to sign the given transaction. | 
					
						
							|  |  |  | 	// | 
					
						
							|  |  |  | 	// It looks up the account specified either solely via its address contained within, | 
					
						
							|  |  |  | 	// or optionally with the aid of any location metadata from the embedded URL field. | 
					
						
							|  |  |  | 	// | 
					
						
							|  |  |  | 	// If the wallet requires additional authentication to sign the request (e.g. | 
					
						
							| 
									
										
										
										
											2018-08-17 02:38:02 -05:00
										 |  |  | 	// a password to decrypt the account, or a PIN code to verify the transaction), | 
					
						
							| 
									
										
										
										
											2017-02-07 12:47:34 +02:00
										 |  |  | 	// an AuthNeededError instance will be returned, containing infos for the user | 
					
						
							|  |  |  | 	// about which fields or actions are needed. The user may retry by providing | 
					
						
							|  |  |  | 	// the needed details via SignTxWithPassphrase, or by other means (e.g. unlock | 
					
						
							|  |  |  | 	// the account in a keystore). | 
					
						
							|  |  |  | 	SignTx(account Account, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												accounts, eth, clique, signer: support for external signer API  (#18079)
* accounts, eth, clique: implement external backend + move sighash calc to backend
* signer: implement account_Version on external API
* accounts/external: enable ipc, add copyright
* accounts, internal, signer: formatting
* node: go fmt
* flags: disallow --dev in combo with --externalsigner
* accounts: remove clique-specific signing method, replace with more generic
* accounts, consensus: formatting + fix error in tests
* signer/core: remove (test-) import cycle
* clique: remove unused import
* accounts: remove CliqueHash and avoid dependency on package crypto
* consensus/clique: unduplicate header encoding
											
										 
											2019-02-05 11:23:57 +01:00
										 |  |  | 	// SignTextWithPassphrase requests the wallet to sign the given text with the | 
					
						
							| 
									
										
										
										
											2017-02-07 12:47:34 +02:00
										 |  |  | 	// given passphrase as extra authentication information. | 
					
						
							|  |  |  | 	// | 
					
						
							|  |  |  | 	// It looks up the account specified either solely via its address contained within, | 
					
						
							|  |  |  | 	// or optionally with the aid of any location metadata from the embedded URL field. | 
					
						
							| 
									
										
										
											
												accounts, eth, clique, signer: support for external signer API  (#18079)
* accounts, eth, clique: implement external backend + move sighash calc to backend
* signer: implement account_Version on external API
* accounts/external: enable ipc, add copyright
* accounts, internal, signer: formatting
* node: go fmt
* flags: disallow --dev in combo with --externalsigner
* accounts: remove clique-specific signing method, replace with more generic
* accounts, consensus: formatting + fix error in tests
* signer/core: remove (test-) import cycle
* clique: remove unused import
* accounts: remove CliqueHash and avoid dependency on package crypto
* consensus/clique: unduplicate header encoding
											
										 
											2019-02-05 11:23:57 +01:00
										 |  |  | 	SignTextWithPassphrase(account Account, passphrase string, hash []byte) ([]byte, error) | 
					
						
							| 
									
										
										
										
											2017-02-07 12:47:34 +02:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	// SignTxWithPassphrase requests the wallet to sign the given transaction, with the | 
					
						
							|  |  |  | 	// given passphrase as extra authentication information. | 
					
						
							|  |  |  | 	// | 
					
						
							|  |  |  | 	// It looks up the account specified either solely via its address contained within, | 
					
						
							|  |  |  | 	// or optionally with the aid of any location metadata from the embedded URL field. | 
					
						
							|  |  |  | 	SignTxWithPassphrase(account Account, passphrase string, tx *types.Transaction, chainID *big.Int) (*types.Transaction, error) | 
					
						
							| 
									
										
										
										
											2017-01-24 11:49:20 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-07 12:47:34 +02:00
										 |  |  | // Backend is a "wallet provider" that may contain a batch of accounts they can | 
					
						
							|  |  |  | // sign transactions with and upon request, do so. | 
					
						
							|  |  |  | type Backend interface { | 
					
						
							|  |  |  | 	// Wallets retrieves the list of wallets the backend is currently aware of. | 
					
						
							|  |  |  | 	// | 
					
						
							|  |  |  | 	// The returned wallets are not opened by default. For software HD wallets this | 
					
						
							|  |  |  | 	// means that no base seeds are decrypted, and for hardware wallets that no actual | 
					
						
							|  |  |  | 	// connection is established. | 
					
						
							|  |  |  | 	// | 
					
						
							|  |  |  | 	// The resulting wallet list will be sorted alphabetically based on its internal | 
					
						
							|  |  |  | 	// URL assigned by the backend. Since wallets (especially hardware) may come and | 
					
						
							|  |  |  | 	// go, the same wallet might appear at a different positions in the list during | 
					
						
							|  |  |  | 	// subsequent retrievals. | 
					
						
							|  |  |  | 	Wallets() []Wallet | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// Subscribe creates an async subscription to receive notifications when the | 
					
						
							|  |  |  | 	// backend detects the arrival or departure of a wallet. | 
					
						
							|  |  |  | 	Subscribe(sink chan<- WalletEvent) event.Subscription | 
					
						
							| 
									
										
										
										
											2017-01-24 11:49:20 +02:00
										 |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
											
												accounts, eth, clique, signer: support for external signer API  (#18079)
* accounts, eth, clique: implement external backend + move sighash calc to backend
* signer: implement account_Version on external API
* accounts/external: enable ipc, add copyright
* accounts, internal, signer: formatting
* node: go fmt
* flags: disallow --dev in combo with --externalsigner
* accounts: remove clique-specific signing method, replace with more generic
* accounts, consensus: formatting + fix error in tests
* signer/core: remove (test-) import cycle
* clique: remove unused import
* accounts: remove CliqueHash and avoid dependency on package crypto
* consensus/clique: unduplicate header encoding
											
										 
											2019-02-05 11:23:57 +01:00
										 |  |  | // TextHash is a helper function that calculates a hash for the given message that can be | 
					
						
							|  |  |  | // safely used to calculate a signature from. | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // The hash is calulcated as | 
					
						
							|  |  |  | //   keccak256("\x19Ethereum Signed Message:\n"${message length}${message}). | 
					
						
							|  |  |  | // | 
					
						
							|  |  |  | // This gives context to the signed message and prevents signing of transactions. | 
					
						
							|  |  |  | func TextHash(data []byte) []byte { | 
					
						
							|  |  |  | 	hash := sha3.NewLegacyKeccak256() | 
					
						
							|  |  |  | 	fmt.Fprintf(hash, "\x19Ethereum Signed Message:\n%d%s", len(data), data) | 
					
						
							|  |  |  | 	return hash.Sum(nil) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-01 17:45:17 +02:00
										 |  |  | // WalletEventType represents the different event types that can be fired by | 
					
						
							|  |  |  | // the wallet subscription subsystem. | 
					
						
							|  |  |  | type WalletEventType int | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | const ( | 
					
						
							|  |  |  | 	// WalletArrived is fired when a new wallet is detected either via USB or via | 
					
						
							|  |  |  | 	// a filesystem event in the keystore. | 
					
						
							|  |  |  | 	WalletArrived WalletEventType = iota | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// WalletOpened is fired when a wallet is successfully opened with the purpose | 
					
						
							|  |  |  | 	// of starting any background processes such as automatic key derivation. | 
					
						
							|  |  |  | 	WalletOpened | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// WalletDropped | 
					
						
							|  |  |  | 	WalletDropped | 
					
						
							|  |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-02-07 12:47:34 +02:00
										 |  |  | // WalletEvent is an event fired by an account backend when a wallet arrival or | 
					
						
							|  |  |  | // departure is detected. | 
					
						
							|  |  |  | type WalletEvent struct { | 
					
						
							| 
									
										
										
										
											2017-08-01 17:45:17 +02:00
										 |  |  | 	Wallet Wallet          // Wallet instance arrived or departed | 
					
						
							|  |  |  | 	Kind   WalletEventType // Event type that happened in the system | 
					
						
							| 
									
										
										
										
											2017-01-24 11:49:20 +02:00
										 |  |  | } |