| 
									
										
										
										
											2015-01-06 12:13:57 +01:00
										 |  |  | /* | 
					
						
							|  |  |  | 	This file is part of go-ethereum | 
					
						
							| 
									
										
										
										
											2014-10-23 15:48:53 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-01-06 12:13:57 +01:00
										 |  |  | 	go-ethereum is free software: you can redistribute it and/or modify | 
					
						
							|  |  |  | 	it under the terms of the GNU General Public License as published by | 
					
						
							|  |  |  | 	the Free Software Foundation, either version 3 of the License, or | 
					
						
							|  |  |  | 	(at your option) any later version. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	go-ethereum 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 General Public License for more details. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	You should have received a copy of the GNU General Public License | 
					
						
							|  |  |  | 	along with go-ethereum.  If not, see <http://www.gnu.org/licenses/>. | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * @authors | 
					
						
							|  |  |  |  * 	Jeffrey Wilcke <i@jev.io> | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2014-06-23 12:20:59 +01:00
										 |  |  | package main | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2015-03-07 12:39:52 +01:00
										 |  |  | 	"bufio" | 
					
						
							| 
									
										
										
										
											2014-08-06 09:53:12 +02:00
										 |  |  | 	"fmt" | 
					
						
							| 
									
										
										
										
											2015-03-24 16:19:11 +00:00
										 |  |  | 	"io/ioutil" | 
					
						
							| 
									
										
										
										
											2014-08-06 09:53:12 +02:00
										 |  |  | 	"os" | 
					
						
							| 
									
										
										
										
											2014-07-30 01:05:40 +02:00
										 |  |  | 	"runtime" | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | 	"strconv" | 
					
						
							| 
									
										
										
										
											2014-12-23 18:35:36 +01:00
										 |  |  | 	"time" | 
					
						
							| 
									
										
										
										
											2014-07-30 01:05:40 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | 	"github.com/codegangsta/cli" | 
					
						
							| 
									
										
										
										
											2015-03-17 14:12:34 +01:00
										 |  |  | 	"github.com/ethereum/ethash" | 
					
						
							| 
									
										
										
										
											2015-03-23 13:00:06 +00:00
										 |  |  | 	"github.com/ethereum/go-ethereum/accounts" | 
					
						
							| 
									
										
										
										
											2014-10-31 14:20:11 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/cmd/utils" | 
					
						
							| 
									
										
										
										
											2015-03-16 22:49:39 +07:00
										 |  |  | 	"github.com/ethereum/go-ethereum/common" | 
					
						
							| 
									
										
										
										
											2015-03-25 11:54:11 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/core/state" | 
					
						
							| 
									
										
										
										
											2014-12-04 10:53:49 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/core/types" | 
					
						
							| 
									
										
										
										
											2015-01-04 14:20:16 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/eth" | 
					
						
							| 
									
										
										
										
											2014-10-31 12:56:05 +01:00
										 |  |  | 	"github.com/ethereum/go-ethereum/logger" | 
					
						
							| 
									
										
										
										
											2015-03-07 12:39:52 +01:00
										 |  |  | 	"github.com/peterh/liner" | 
					
						
							| 
									
										
										
										
											2014-06-23 12:20:59 +01:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2014-07-03 17:36:24 +01:00
										 |  |  | const ( | 
					
						
							| 
									
										
										
										
											2015-03-26 21:27:52 +01:00
										 |  |  | 	ClientIdentifier = "Geth" | 
					
						
							| 
									
										
										
										
											2015-03-26 17:55:30 +01:00
										 |  |  | 	Version          = "0.9.4" | 
					
						
							| 
									
										
										
										
											2014-07-03 17:36:24 +01:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | var ( | 
					
						
							|  |  |  | 	clilogger = logger.NewLogger("CLI") | 
					
						
							| 
									
										
										
										
											2015-03-09 22:51:50 +01:00
										 |  |  | 	app       = utils.NewApp(Version, "the go-ethereum command line interface") | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | ) | 
					
						
							| 
									
										
										
										
											2014-06-23 12:20:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | func init() { | 
					
						
							|  |  |  | 	app.Action = run | 
					
						
							|  |  |  | 	app.HideVersion = true // we have a command to print the version | 
					
						
							|  |  |  | 	app.Commands = []cli.Command{ | 
					
						
							| 
									
										
										
										
											2015-03-13 18:37:13 +01:00
										 |  |  | 		blocktestCmd, | 
					
						
							| 
									
										
										
										
											2015-03-17 14:12:34 +01:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			Action: makedag, | 
					
						
							|  |  |  | 			Name:   "makedag", | 
					
						
							|  |  |  | 			Usage:  "generate ethash dag (for testing)", | 
					
						
							|  |  |  | 			Description: ` | 
					
						
							|  |  |  | The makedag command generates an ethash DAG in /tmp/dag. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | This command exists to support the system testing project. | 
					
						
							|  |  |  | Regular users do not need to execute it. | 
					
						
							|  |  |  | `, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			Action: version, | 
					
						
							|  |  |  | 			Name:   "version", | 
					
						
							|  |  |  | 			Usage:  "print ethereum version numbers", | 
					
						
							|  |  |  | 			Description: ` | 
					
						
							|  |  |  | The output of this command is supposed to be machine-readable. | 
					
						
							|  |  |  | `, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2015-03-24 16:19:11 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2015-03-26 18:55:39 +00:00
										 |  |  | 			Name:  "wallet", | 
					
						
							|  |  |  | 			Usage: "ethereum presale wallet", | 
					
						
							| 
									
										
										
										
											2015-03-24 16:19:11 +00:00
										 |  |  | 			Subcommands: []cli.Command{ | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					Action: importWallet, | 
					
						
							|  |  |  | 					Name:   "import", | 
					
						
							|  |  |  | 					Usage:  "import ethereum presale wallet", | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2015-03-07 12:39:52 +01:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			Action: accountList, | 
					
						
							|  |  |  | 			Name:   "account", | 
					
						
							|  |  |  | 			Usage:  "manage accounts", | 
					
						
							| 
									
										
										
										
											2015-03-26 18:55:39 +00:00
										 |  |  | 			Description: ` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Manage accounts lets you create new accounts, list all existing accounts, | 
					
						
							|  |  |  | import a private key into a new account. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | It supports interactive mode, when you are prompted for password as well as | 
					
						
							|  |  |  | non-interactive mode where passwords are supplied via a given password file. | 
					
						
							|  |  |  | Non-interactive mode is only meant for scripted use on test networks or known | 
					
						
							|  |  |  | safe environments. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Make sure you remember the password you gave when creating a new account (with | 
					
						
							|  |  |  | either new or import). Without it you are not able to unlock your account. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Note that exporting your key in unencrypted format is NOT supported. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | Keys are stored under <DATADIR>/keys. | 
					
						
							|  |  |  | It is safe to transfer the entire directory or the individual keys therein | 
					
						
							|  |  |  | between ethereum nodes. | 
					
						
							|  |  |  | Make sure you backup your keys regularly. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | And finally. DO NOT FORGET YOUR PASSWORD. | 
					
						
							|  |  |  | `, | 
					
						
							| 
									
										
										
										
											2015-03-07 12:39:52 +01:00
										 |  |  | 			Subcommands: []cli.Command{ | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					Action: accountList, | 
					
						
							|  |  |  | 					Name:   "list", | 
					
						
							|  |  |  | 					Usage:  "print account addresses", | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					Action: accountCreate, | 
					
						
							|  |  |  | 					Name:   "new", | 
					
						
							|  |  |  | 					Usage:  "create a new account", | 
					
						
							| 
									
										
										
										
											2015-03-23 13:00:06 +00:00
										 |  |  | 					Description: ` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ethereum account new | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-26 18:55:39 +00:00
										 |  |  | Creates a new account. Prints the address. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | The account is saved in encrypted format, you are prompted for a passphrase. | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | You must remember this passphrase to unlock your account in the future. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-23 13:00:06 +00:00
										 |  |  | For non-interactive use the passphrase can be specified with the --password flag: | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ethereum --password <passwordfile> account new | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-26 18:55:39 +00:00
										 |  |  | Note, this is meant to be used for testing only, it is a bad idea to save your | 
					
						
							|  |  |  | password to file or expose in any other way. | 
					
						
							| 
									
										
										
										
											2015-03-23 13:00:06 +00:00
										 |  |  | 					`, | 
					
						
							|  |  |  | 				}, | 
					
						
							|  |  |  | 				{ | 
					
						
							|  |  |  | 					Action: accountImport, | 
					
						
							|  |  |  | 					Name:   "import", | 
					
						
							|  |  |  | 					Usage:  "import a private key into a new account", | 
					
						
							|  |  |  | 					Description: ` | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     ethereum account import <keyfile> | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-26 18:55:39 +00:00
										 |  |  | Imports an unencrypted private key from <keyfile> and creates a new account. | 
					
						
							|  |  |  | Prints the address. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-24 16:05:27 +00:00
										 |  |  | The keyfile is assumed to contain an unencrypted private key in canonical EC | 
					
						
							| 
									
										
										
										
											2015-03-26 18:55:39 +00:00
										 |  |  | raw bytes format. | 
					
						
							| 
									
										
										
										
											2015-03-23 13:00:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | The account is saved in encrypted format, you are prompted for a passphrase. | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-26 18:55:39 +00:00
										 |  |  | You must remember this passphrase to unlock your account in the future. | 
					
						
							| 
									
										
										
										
											2015-03-23 13:00:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-26 18:55:39 +00:00
										 |  |  | For non-interactive use the passphrase can be specified with the -password flag: | 
					
						
							| 
									
										
										
										
											2015-03-23 13:00:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-26 18:55:39 +00:00
										 |  |  |     ethereum --password <passwordfile> account import <keyfile> | 
					
						
							| 
									
										
										
										
											2015-03-23 13:00:06 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  | Note: | 
					
						
							| 
									
										
										
										
											2015-03-24 16:05:27 +00:00
										 |  |  | As you can directly copy your encrypted accounts to another ethereum instance, | 
					
						
							| 
									
										
										
										
											2015-03-26 18:55:39 +00:00
										 |  |  | this import mechanism is not needed when you transfer an account between | 
					
						
							| 
									
										
										
										
											2015-03-24 16:05:27 +00:00
										 |  |  | nodes. | 
					
						
							| 
									
										
										
										
											2015-03-23 13:00:06 +00:00
										 |  |  | 					`, | 
					
						
							| 
									
										
										
										
											2015-03-07 12:39:52 +01:00
										 |  |  | 				}, | 
					
						
							|  |  |  | 			}, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			Action: dump, | 
					
						
							|  |  |  | 			Name:   "dump", | 
					
						
							|  |  |  | 			Usage:  `dump a specific block from storage`, | 
					
						
							|  |  |  | 			Description: ` | 
					
						
							|  |  |  | The arguments are interpreted as block numbers or hashes. | 
					
						
							|  |  |  | Use "ethereum dump 0" to dump the genesis block. | 
					
						
							|  |  |  | `, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							| 
									
										
										
										
											2015-03-15 13:31:40 +07:00
										 |  |  | 			Action: console, | 
					
						
							|  |  |  | 			Name:   "console", | 
					
						
							| 
									
										
										
										
											2015-03-26 21:27:52 +01:00
										 |  |  | 			Usage:  `Geth Console: interactive JavaScript environment`, | 
					
						
							| 
									
										
										
										
											2015-03-15 13:31:40 +07:00
										 |  |  | 			Description: ` | 
					
						
							| 
									
										
										
										
											2015-03-26 21:27:52 +01:00
										 |  |  | The Geth console is an interactive shell for the JavaScript runtime environment | 
					
						
							| 
									
										
										
										
											2015-03-24 16:05:27 +00:00
										 |  |  | which exposes a node admin interface as well as the DAPP JavaScript API. | 
					
						
							| 
									
										
										
										
											2015-03-15 13:31:40 +07:00
										 |  |  | See https://github.com/ethereum/go-ethereum/wiki/Frontier-Console | 
					
						
							|  |  |  | `, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			Action: execJSFiles, | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | 			Name:   "js", | 
					
						
							| 
									
										
										
										
											2015-03-26 21:27:52 +01:00
										 |  |  | 			Usage:  `executes the given JavaScript files in the Geth JavaScript VM`, | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | 			Description: ` | 
					
						
							| 
									
										
										
										
											2015-03-26 21:27:52 +01:00
										 |  |  | The JavaScript VM exposes a node admin interface as well as the DAPP | 
					
						
							| 
									
										
										
										
											2015-03-24 16:05:27 +00:00
										 |  |  | JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Console | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | `, | 
					
						
							|  |  |  | 		}, | 
					
						
							|  |  |  | 		{ | 
					
						
							|  |  |  | 			Action: importchain, | 
					
						
							|  |  |  | 			Name:   "import", | 
					
						
							|  |  |  | 			Usage:  `import a blockchain file`, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2015-03-08 22:44:48 +07:00
										 |  |  | 		{ | 
					
						
							|  |  |  | 			Action: exportchain, | 
					
						
							|  |  |  | 			Name:   "export", | 
					
						
							|  |  |  | 			Usage:  `export blockchain into file`, | 
					
						
							|  |  |  | 		}, | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	app.Flags = []cli.Flag{ | 
					
						
							| 
									
										
										
										
											2015-03-11 01:08:42 +01:00
										 |  |  | 		utils.UnlockedAccountFlag, | 
					
						
							| 
									
										
										
										
											2015-03-23 13:00:06 +00:00
										 |  |  | 		utils.PasswordFileFlag, | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | 		utils.BootnodesFlag, | 
					
						
							|  |  |  | 		utils.DataDirFlag, | 
					
						
							| 
									
										
										
										
											2015-03-15 13:31:40 +07:00
										 |  |  | 		utils.JSpathFlag, | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | 		utils.ListenPortFlag, | 
					
						
							|  |  |  | 		utils.LogFileFlag, | 
					
						
							| 
									
										
										
										
											2015-03-21 09:20:47 +00:00
										 |  |  | 		utils.LogJSONFlag, | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | 		utils.LogLevelFlag, | 
					
						
							|  |  |  | 		utils.MaxPeersFlag, | 
					
						
							| 
									
										
										
										
											2015-03-26 21:49:22 +00:00
										 |  |  | 		utils.EtherbaseFlag, | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | 		utils.MinerThreadsFlag, | 
					
						
							|  |  |  | 		utils.MiningEnabledFlag, | 
					
						
							|  |  |  | 		utils.NATFlag, | 
					
						
							|  |  |  | 		utils.NodeKeyFileFlag, | 
					
						
							|  |  |  | 		utils.NodeKeyHexFlag, | 
					
						
							|  |  |  | 		utils.RPCEnabledFlag, | 
					
						
							|  |  |  | 		utils.RPCListenAddrFlag, | 
					
						
							|  |  |  | 		utils.RPCPortFlag, | 
					
						
							| 
									
										
										
										
											2015-03-06 16:58:52 +01:00
										 |  |  | 		utils.VMDebugFlag, | 
					
						
							| 
									
										
										
										
											2015-03-18 14:44:58 +07:00
										 |  |  | 		utils.ProtocolVersionFlag, | 
					
						
							|  |  |  | 		utils.NetworkIdFlag, | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	// missing: | 
					
						
							|  |  |  | 	// flag.StringVar(&ConfigFile, "conf", defaultConfigFile, "config file") | 
					
						
							|  |  |  | 	// flag.BoolVar(&DiffTool, "difftool", false, "creates output for diff'ing. Sets LogLevel=0") | 
					
						
							|  |  |  | 	// flag.StringVar(&DiffType, "diff", "all", "sets the level of diff output [vm, all]. Has no effect if difftool=false") | 
					
						
							| 
									
										
										
										
											2014-06-23 12:20:59 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | 	// potential subcommands: | 
					
						
							|  |  |  | 	// flag.StringVar(&SecretFile, "import", "", "imports the file given (hex or mnemonic formats)") | 
					
						
							|  |  |  | 	// flag.StringVar(&ExportDir, "export", "", "exports the session keyring to files in the directory given") | 
					
						
							|  |  |  | 	// flag.BoolVar(&GenAddr, "genaddr", false, "create a new priv/pub key") | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-12-23 14:33:15 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | func main() { | 
					
						
							|  |  |  | 	runtime.GOMAXPROCS(runtime.NumCPU()) | 
					
						
							|  |  |  | 	defer logger.Flush() | 
					
						
							|  |  |  | 	if err := app.Run(os.Args); err != nil { | 
					
						
							|  |  |  | 		fmt.Fprintln(os.Stderr, err) | 
					
						
							|  |  |  | 		os.Exit(1) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2014-06-26 10:47:45 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | func run(ctx *cli.Context) { | 
					
						
							|  |  |  | 	fmt.Printf("Welcome to the FRONTIER\n") | 
					
						
							| 
									
										
										
										
											2015-03-06 12:18:44 +01:00
										 |  |  | 	utils.HandleInterrupt() | 
					
						
							| 
									
										
										
										
											2015-03-13 18:30:45 +01:00
										 |  |  | 	cfg := utils.MakeEthConfig(ClientIdentifier, Version, ctx) | 
					
						
							|  |  |  | 	ethereum, err := eth.New(cfg) | 
					
						
							| 
									
										
										
										
											2015-03-11 23:41:51 +01:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2015-03-10 15:44:05 +01:00
										 |  |  | 		utils.Fatalf("%v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-13 18:30:45 +01:00
										 |  |  | 	startEth(ctx, ethereum) | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | 	// this blocks the thread | 
					
						
							| 
									
										
										
										
											2015-03-13 18:30:45 +01:00
										 |  |  | 	ethereum.WaitForShutdown() | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2014-07-11 16:04:27 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-15 13:31:40 +07:00
										 |  |  | func console(ctx *cli.Context) { | 
					
						
							| 
									
										
										
										
											2015-03-13 18:30:45 +01:00
										 |  |  | 	cfg := utils.MakeEthConfig(ClientIdentifier, Version, ctx) | 
					
						
							|  |  |  | 	ethereum, err := eth.New(cfg) | 
					
						
							| 
									
										
										
										
											2015-03-11 23:41:51 +01:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2015-03-10 15:44:05 +01:00
										 |  |  | 		utils.Fatalf("%v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-13 18:30:45 +01:00
										 |  |  | 	startEth(ctx, ethereum) | 
					
						
							| 
									
										
										
										
											2015-03-24 14:09:06 +00:00
										 |  |  | 	repl := newJSRE(ethereum, ctx.String(utils.JSpathFlag.Name), true) | 
					
						
							| 
									
										
										
										
											2015-03-15 13:31:40 +07:00
										 |  |  | 	repl.interactive() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	ethereum.Stop() | 
					
						
							|  |  |  | 	ethereum.WaitForShutdown() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func execJSFiles(ctx *cli.Context) { | 
					
						
							|  |  |  | 	cfg := utils.MakeEthConfig(ClientIdentifier, Version, ctx) | 
					
						
							|  |  |  | 	ethereum, err := eth.New(cfg) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		utils.Fatalf("%v", err) | 
					
						
							| 
									
										
										
										
											2015-01-07 01:21:55 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-03-15 13:31:40 +07:00
										 |  |  | 
 | 
					
						
							|  |  |  | 	startEth(ctx, ethereum) | 
					
						
							| 
									
										
										
										
											2015-03-24 14:09:06 +00:00
										 |  |  | 	repl := newJSRE(ethereum, ctx.String(utils.JSpathFlag.Name), false) | 
					
						
							| 
									
										
										
										
											2015-03-15 13:31:40 +07:00
										 |  |  | 	for _, file := range ctx.Args() { | 
					
						
							|  |  |  | 		repl.exec(file) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-13 18:30:45 +01:00
										 |  |  | 	ethereum.Stop() | 
					
						
							|  |  |  | 	ethereum.WaitForShutdown() | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-01-07 01:21:55 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-23 13:00:06 +00:00
										 |  |  | func unlockAccount(ctx *cli.Context, am *accounts.Manager, account string) (passphrase string) { | 
					
						
							| 
									
										
										
										
											2015-03-26 18:55:39 +00:00
										 |  |  | 	var err error | 
					
						
							|  |  |  | 	// Load startup keys. XXX we are going to need a different format | 
					
						
							|  |  |  | 	// Attempt to unlock the account | 
					
						
							|  |  |  | 	passphrase = getPassPhrase(ctx, "", false) | 
					
						
							|  |  |  | 	accbytes := common.FromHex(account) | 
					
						
							|  |  |  | 	if len(accbytes) == 0 { | 
					
						
							|  |  |  | 		utils.Fatalf("Invalid account address '%s'", account) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	err = am.Unlock(accbytes, passphrase) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		utils.Fatalf("Unlock account failed '%v'", err) | 
					
						
							| 
									
										
										
										
											2015-03-11 01:08:42 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-03-23 13:00:06 +00:00
										 |  |  | 	return | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func startEth(ctx *cli.Context, eth *eth.Ethereum) { | 
					
						
							|  |  |  | 	utils.StartEthereum(eth) | 
					
						
							|  |  |  | 	am := eth.AccountManager() | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	account := ctx.GlobalString(utils.UnlockedAccountFlag.Name) | 
					
						
							|  |  |  | 	if len(account) > 0 { | 
					
						
							| 
									
										
										
										
											2015-03-26 21:49:22 +00:00
										 |  |  | 		if account == "primary" { | 
					
						
							|  |  |  | 			accbytes, err := am.Primary() | 
					
						
							| 
									
										
										
										
											2015-03-25 15:45:56 +00:00
										 |  |  | 			if err != nil { | 
					
						
							| 
									
										
										
										
											2015-03-26 21:49:22 +00:00
										 |  |  | 				utils.Fatalf("no primary account: %v", err) | 
					
						
							| 
									
										
										
										
											2015-03-25 15:45:56 +00:00
										 |  |  | 			} | 
					
						
							|  |  |  | 			account = common.ToHex(accbytes) | 
					
						
							| 
									
										
										
										
											2015-03-24 12:37:00 +00:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-03-23 13:00:06 +00:00
										 |  |  | 		unlockAccount(ctx, am, account) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-03-10 16:44:22 +01:00
										 |  |  | 	// Start auxiliary services if enabled. | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | 	if ctx.GlobalBool(utils.RPCEnabledFlag.Name) { | 
					
						
							| 
									
										
										
										
											2015-03-09 23:00:27 +01:00
										 |  |  | 		utils.StartRPC(eth, ctx) | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | 	if ctx.GlobalBool(utils.MiningEnabledFlag.Name) { | 
					
						
							| 
									
										
										
										
											2015-03-11 23:35:34 +01:00
										 |  |  | 		eth.StartMining() | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-01-05 17:10:42 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-07 12:39:52 +01:00
										 |  |  | func accountList(ctx *cli.Context) { | 
					
						
							|  |  |  | 	am := utils.GetAccountManager(ctx) | 
					
						
							|  |  |  | 	accts, err := am.Accounts() | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		utils.Fatalf("Could not list accounts: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	for _, acct := range accts { | 
					
						
							| 
									
										
										
										
											2015-03-20 12:52:03 +01:00
										 |  |  | 		fmt.Printf("Address: %x\n", acct) | 
					
						
							| 
									
										
										
										
											2015-03-07 12:39:52 +01:00
										 |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-24 16:19:11 +00:00
										 |  |  | func getPassPhrase(ctx *cli.Context, desc string, confirmation bool) (passphrase string) { | 
					
						
							| 
									
										
										
										
											2015-03-26 18:55:39 +00:00
										 |  |  | 	passfile := ctx.GlobalString(utils.PasswordFileFlag.Name) | 
					
						
							|  |  |  | 	if len(passfile) == 0 { | 
					
						
							|  |  |  | 		fmt.Println(desc) | 
					
						
							|  |  |  | 		auth, err := readPassword("Passphrase: ", true) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			utils.Fatalf("%v", err) | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 		if confirmation { | 
					
						
							|  |  |  | 			confirm, err := readPassword("Repeat Passphrase: ", false) | 
					
						
							| 
									
										
										
										
											2015-03-23 13:00:06 +00:00
										 |  |  | 			if err != nil { | 
					
						
							|  |  |  | 				utils.Fatalf("%v", err) | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-03-26 18:55:39 +00:00
										 |  |  | 			if auth != confirm { | 
					
						
							|  |  |  | 				utils.Fatalf("Passphrases did not match.") | 
					
						
							| 
									
										
										
										
											2015-03-23 13:00:06 +00:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2015-03-26 18:55:39 +00:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		passphrase = auth | 
					
						
							| 
									
										
										
										
											2015-03-23 13:00:06 +00:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-26 18:55:39 +00:00
										 |  |  | 	} else { | 
					
						
							|  |  |  | 		passbytes, err := ioutil.ReadFile(passfile) | 
					
						
							|  |  |  | 		if err != nil { | 
					
						
							|  |  |  | 			utils.Fatalf("Unable to read password file '%s': %v", passfile, err) | 
					
						
							| 
									
										
										
										
											2015-03-11 13:56:02 +01:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-03-26 18:55:39 +00:00
										 |  |  | 		passphrase = string(passbytes) | 
					
						
							| 
									
										
										
										
											2015-03-07 12:39:52 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-03-23 13:00:06 +00:00
										 |  |  | 	return | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func accountCreate(ctx *cli.Context) { | 
					
						
							|  |  |  | 	am := utils.GetAccountManager(ctx) | 
					
						
							| 
									
										
										
										
											2015-03-24 16:19:11 +00:00
										 |  |  | 	passphrase := getPassPhrase(ctx, "Your new account is locked with a password. Please give a password. Do not forget this password.", true) | 
					
						
							| 
									
										
										
										
											2015-03-11 13:56:02 +01:00
										 |  |  | 	acct, err := am.NewAccount(passphrase) | 
					
						
							| 
									
										
										
										
											2015-03-07 12:39:52 +01:00
										 |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		utils.Fatalf("Could not create the account: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-03-23 13:00:06 +00:00
										 |  |  | 	fmt.Printf("Address: %x\n", acct) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-24 16:19:11 +00:00
										 |  |  | func importWallet(ctx *cli.Context) { | 
					
						
							|  |  |  | 	keyfile := ctx.Args().First() | 
					
						
							|  |  |  | 	if len(keyfile) == 0 { | 
					
						
							|  |  |  | 		utils.Fatalf("keyfile must be given as argument") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	keyJson, err := ioutil.ReadFile(keyfile) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		utils.Fatalf("Could not read wallet file: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	am := utils.GetAccountManager(ctx) | 
					
						
							|  |  |  | 	passphrase := getPassPhrase(ctx, "", false) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	acct, err := am.ImportPreSaleKey(keyJson, passphrase) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		utils.Fatalf("Could not create the account: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	fmt.Printf("Address: %x\n", acct) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-23 13:00:06 +00:00
										 |  |  | func accountImport(ctx *cli.Context) { | 
					
						
							|  |  |  | 	keyfile := ctx.Args().First() | 
					
						
							|  |  |  | 	if len(keyfile) == 0 { | 
					
						
							|  |  |  | 		utils.Fatalf("keyfile must be given as argument") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	am := utils.GetAccountManager(ctx) | 
					
						
							| 
									
										
										
										
											2015-03-24 16:19:11 +00:00
										 |  |  | 	passphrase := getPassPhrase(ctx, "Your new account is locked with a password. Please give a password. Do not forget this password.", true) | 
					
						
							| 
									
										
										
										
											2015-03-23 13:00:06 +00:00
										 |  |  | 	acct, err := am.Import(keyfile, passphrase) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		utils.Fatalf("Could not create the account: %v", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	fmt.Printf("Address: %x\n", acct) | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | func importchain(ctx *cli.Context) { | 
					
						
							|  |  |  | 	if len(ctx.Args()) != 1 { | 
					
						
							|  |  |  | 		utils.Fatalf("This command requires an argument.") | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-03-08 22:44:48 +07:00
										 |  |  | 	chainmgr, _, _ := utils.GetChain(ctx) | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | 	start := time.Now() | 
					
						
							| 
									
										
										
										
											2015-03-08 22:44:48 +07:00
										 |  |  | 	err := utils.ImportChain(chainmgr, ctx.Args().First()) | 
					
						
							| 
									
										
										
										
											2014-08-22 12:14:37 +02:00
										 |  |  | 	if err != nil { | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | 		utils.Fatalf("Import error: %v\n", err) | 
					
						
							| 
									
										
										
										
											2014-08-22 12:14:37 +02:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-03-08 22:44:48 +07:00
										 |  |  | 	fmt.Printf("Import done in %v", time.Since(start)) | 
					
						
							|  |  |  | 	return | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func exportchain(ctx *cli.Context) { | 
					
						
							|  |  |  | 	if len(ctx.Args()) != 1 { | 
					
						
							|  |  |  | 		utils.Fatalf("This command requires an argument.") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	chainmgr, _, _ := utils.GetChain(ctx) | 
					
						
							|  |  |  | 	start := time.Now() | 
					
						
							|  |  |  | 	err := utils.ExportChain(chainmgr, ctx.Args().First()) | 
					
						
							|  |  |  | 	if err != nil { | 
					
						
							|  |  |  | 		utils.Fatalf("Export error: %v\n", err) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	fmt.Printf("Export done in %v", time.Since(start)) | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | 	return | 
					
						
							|  |  |  | } | 
					
						
							| 
									
										
										
										
											2015-01-05 17:10:42 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | func dump(ctx *cli.Context) { | 
					
						
							| 
									
										
										
										
											2015-03-08 22:44:48 +07:00
										 |  |  | 	chainmgr, _, stateDb := utils.GetChain(ctx) | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | 	for _, arg := range ctx.Args() { | 
					
						
							| 
									
										
										
										
											2014-11-18 19:52:45 +01:00
										 |  |  | 		var block *types.Block | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | 		if hashish(arg) { | 
					
						
							| 
									
										
										
										
											2015-03-18 13:00:01 +01:00
										 |  |  | 			block = chainmgr.GetBlock(common.HexToHash(arg)) | 
					
						
							| 
									
										
										
										
											2014-08-06 09:53:12 +02:00
										 |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | 			num, _ := strconv.Atoi(arg) | 
					
						
							| 
									
										
										
										
											2015-03-08 22:44:48 +07:00
										 |  |  | 			block = chainmgr.GetBlockByNumber(uint64(num)) | 
					
						
							| 
									
										
										
										
											2014-08-06 09:53:12 +02:00
										 |  |  | 		} | 
					
						
							|  |  |  | 		if block == nil { | 
					
						
							|  |  |  | 			fmt.Println("{}") | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | 			utils.Fatalf("block not found") | 
					
						
							|  |  |  | 		} else { | 
					
						
							| 
									
										
										
										
											2015-03-06 18:26:16 +01:00
										 |  |  | 			statedb := state.New(block.Root(), stateDb) | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | 			fmt.Printf("%s\n", statedb.Dump()) | 
					
						
							| 
									
										
										
										
											2014-12-23 14:33:15 +01:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2015-02-28 23:01:41 +01:00
										 |  |  | 	} | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-02-28 23:01:41 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-17 14:12:34 +01:00
										 |  |  | func makedag(ctx *cli.Context) { | 
					
						
							|  |  |  | 	chain, _, _ := utils.GetChain(ctx) | 
					
						
							|  |  |  | 	pow := ethash.New(chain) | 
					
						
							|  |  |  | 	fmt.Println("making cache") | 
					
						
							|  |  |  | 	pow.UpdateCache(true) | 
					
						
							|  |  |  | 	fmt.Println("making DAG") | 
					
						
							|  |  |  | 	pow.UpdateDAG() | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-03-06 03:00:41 +01:00
										 |  |  | func version(c *cli.Context) { | 
					
						
							| 
									
										
										
										
											2015-03-08 22:50:27 +07:00
										 |  |  | 	fmt.Printf(`%v | 
					
						
							|  |  |  | Version: %v | 
					
						
							|  |  |  | Protocol Version: %d | 
					
						
							|  |  |  | Network Id: %d | 
					
						
							|  |  |  | GO: %s | 
					
						
							|  |  |  | OS: %s | 
					
						
							| 
									
										
										
										
											2015-01-07 01:21:55 +01:00
										 |  |  | GOPATH=%s | 
					
						
							|  |  |  | GOROOT=%s | 
					
						
							| 
									
										
										
										
											2015-03-18 14:44:58 +07:00
										 |  |  | `, ClientIdentifier, Version, c.GlobalInt(utils.ProtocolVersionFlag.Name), c.GlobalInt(utils.NetworkIdFlag.Name), runtime.Version(), runtime.GOOS, os.Getenv("GOPATH"), runtime.GOROOT()) | 
					
						
							| 
									
										
										
										
											2015-01-07 01:21:55 +01:00
										 |  |  | } | 
					
						
							| 
									
										
										
										
											2015-03-07 12:39:52 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | // hashish returns true for strings that look like hashes. | 
					
						
							|  |  |  | func hashish(x string) bool { | 
					
						
							|  |  |  | 	_, err := strconv.Atoi(x) | 
					
						
							|  |  |  | 	return err != nil | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | func readPassword(prompt string, warnTerm bool) (string, error) { | 
					
						
							|  |  |  | 	if liner.TerminalSupported() { | 
					
						
							|  |  |  | 		lr := liner.NewLiner() | 
					
						
							|  |  |  | 		defer lr.Close() | 
					
						
							|  |  |  | 		return lr.PasswordPrompt(prompt) | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	if warnTerm { | 
					
						
							|  |  |  | 		fmt.Println("!! Unsupported terminal, password will be echoed.") | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | 	fmt.Print(prompt) | 
					
						
							|  |  |  | 	input, err := bufio.NewReader(os.Stdin).ReadString('\n') | 
					
						
							|  |  |  | 	fmt.Println() | 
					
						
							|  |  |  | 	return input, err | 
					
						
							|  |  |  | } |