2015-07-06 19:54:22 -05:00
// Copyright 2014 The go-ethereum Authors
// This file is part of go-ethereum.
//
// 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
2015-07-22 11:48:40 -05:00
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2015-07-06 19:54:22 -05:00
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
2015-07-22 11:48:40 -05:00
// along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
2014-10-23 08:48:53 -05:00
2015-07-06 22:08:16 -05:00
// geth is the official command-line client for Ethereum.
2014-06-23 06:20:59 -05:00
package main
import (
2014-08-06 02:53:12 -05:00
"fmt"
2015-03-24 11:19:11 -05:00
"io/ioutil"
2014-08-06 02:53:12 -05:00
"os"
2015-05-05 01:24:15 -05:00
"path/filepath"
2014-07-29 18:05:40 -05:00
"runtime"
2015-03-05 20:00:41 -06:00
"strconv"
2015-05-05 01:24:15 -05:00
"strings"
2015-06-25 05:47:06 -05:00
"time"
2014-07-29 18:05:40 -05:00
2015-03-05 20:00:41 -06:00
"github.com/codegangsta/cli"
2015-03-17 08:12:34 -05:00
"github.com/ethereum/ethash"
2015-03-23 08:00:06 -05:00
"github.com/ethereum/go-ethereum/accounts"
2014-10-31 08:20:11 -05:00
"github.com/ethereum/go-ethereum/cmd/utils"
2015-03-16 10:49:39 -05:00
"github.com/ethereum/go-ethereum/common"
2016-03-01 16:32:43 -06:00
"github.com/ethereum/go-ethereum/core"
2015-01-04 07:20:16 -06:00
"github.com/ethereum/go-ethereum/eth"
2016-03-01 16:32:43 -06:00
"github.com/ethereum/go-ethereum/ethdb"
2016-01-26 07:39:21 -06:00
"github.com/ethereum/go-ethereum/internal/debug"
2014-10-31 06:56:05 -05:00
"github.com/ethereum/go-ethereum/logger"
2015-06-30 17:52:44 -05:00
"github.com/ethereum/go-ethereum/logger/glog"
2015-06-27 10:12:58 -05:00
"github.com/ethereum/go-ethereum/metrics"
2015-11-17 10:33:25 -06:00
"github.com/ethereum/go-ethereum/node"
2015-08-06 04:20:15 -05:00
"github.com/ethereum/go-ethereum/params"
"github.com/ethereum/go-ethereum/rlp"
2014-06-23 06:20:59 -05:00
)
2014-07-03 11:36:24 -05:00
const (
2015-08-12 06:32:52 -05:00
ClientIdentifier = "Geth"
2015-11-03 04:48:04 -06:00
Version = "1.4.0-unstable"
2015-08-06 04:20:15 -05:00
VersionMajor = 1
2015-11-03 04:48:04 -06:00
VersionMinor = 4
2015-08-20 14:43:36 -05:00
VersionPatch = 0
2014-07-03 11:36:24 -05:00
)
2015-04-28 06:14:53 -05:00
var (
2015-08-05 11:41:00 -05:00
gitCommit string // set via linker flagg
2015-04-28 06:14:53 -05:00
nodeNameVersion string
app * cli . App
)
2014-06-23 06:20:59 -05:00
2015-03-05 20:00:41 -06:00
func init ( ) {
2015-04-28 06:14:53 -05:00
if gitCommit == "" {
nodeNameVersion = Version
} else {
nodeNameVersion = Version + "-" + gitCommit [ : 8 ]
}
app = utils . NewApp ( Version , "the go-ethereum command line interface" )
2015-11-17 10:33:25 -06:00
app . Action = geth
2015-03-05 20:00:41 -06:00
app . HideVersion = true // we have a command to print the version
app . Commands = [ ] cli . Command {
2015-05-27 06:43:49 -05:00
importCommand ,
exportCommand ,
upgradedbCommand ,
removedbCommand ,
dumpCommand ,
2015-06-25 02:36:47 -05:00
monitorCommand ,
2015-03-17 08:12:34 -05: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-06-12 00:45:23 -05:00
` ,
} ,
{
Action : gpuinfo ,
Name : "gpuinfo" ,
Usage : "gpuinfo" ,
Description : `
Prints OpenCL device info for all found GPUs .
` ,
} ,
{
Action : gpubench ,
Name : "gpubench" ,
Usage : "benchmark GPU" ,
Description : `
Runs quick benchmark on first GPU found .
2015-03-17 08:12:34 -05:00
` ,
} ,
2015-03-05 20:00:41 -06: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 11:19:11 -05:00
{
2015-03-26 13:55:39 -05:00
Name : "wallet" ,
Usage : "ethereum presale wallet" ,
2015-03-24 11:19:11 -05:00
Subcommands : [ ] cli . Command {
{
Action : importWallet ,
Name : "import" ,
Usage : "import ethereum presale wallet" ,
} ,
} ,
2015-05-19 20:42:10 -05:00
Description : `
get wallet import / path / to / my / presale . wallet
will prompt for your password and imports your ether presale account .
It can be used non - interactively with the -- password option taking a
passwordfile as argument containing the wallet password in plaintext .
` } ,
2015-03-07 05:39:52 -06:00
{
Action : accountList ,
Name : "account" ,
Usage : "manage accounts" ,
2015-03-26 13:55:39 -05:00
Description : `
Manage accounts lets you create new accounts , list all existing accounts ,
import a private key into a new account .
2015-05-20 10:56:17 -05:00
' help ' shows a list of subcommands or help for one subcommand .
2015-04-21 18:41:34 -05:00
2015-03-26 13:55:39 -05:00
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
2015-06-18 10:20:00 -05:00
between ethereum nodes by simply copying .
2015-03-26 13:55:39 -05:00
Make sure you backup your keys regularly .
2015-09-22 03:34:58 -05:00
In order to use your account to send transactions , you need to unlock them using
the ' -- unlock ' option . The argument is a space separated list of addresses or
indexes . If used non - interactively with a passwordfile , the file should contain
the respective passwords one per line . If you unlock n accounts and the password
file contains less than n entries , then the last password is meant to apply to
all remaining accounts .
2015-06-18 10:20:00 -05:00
2015-03-26 13:55:39 -05:00
And finally . DO NOT FORGET YOUR PASSWORD .
` ,
2015-03-07 05:39:52 -06:00
Subcommands : [ ] cli . Command {
{
Action : accountList ,
Name : "list" ,
Usage : "print account addresses" ,
} ,
{
Action : accountCreate ,
Name : "new" ,
Usage : "create a new account" ,
2015-03-23 08:00:06 -05:00
Description : `
ethereum account new
2015-03-26 13:55:39 -05: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 08:00:06 -05:00
For non - interactive use the passphrase can be specified with the -- password flag :
ethereum -- password < passwordfile > account new
2015-03-26 13:55:39 -05: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 08:00:06 -05:00
` ,
} ,
2015-07-02 22:56:20 -05:00
{
Action : accountUpdate ,
Name : "update" ,
Usage : "update an existing account" ,
Description : `
ethereum account update < address >
Update an existing account .
The account is saved in the newest version in encrypted format , you are prompted
for a passphrase to unlock the account and another to save the updated file .
This same command can therefore be used to migrate an account of a deprecated
format to the newest format or change the password for an account .
For non - interactive use the passphrase can be specified with the -- password flag :
2015-09-22 03:34:58 -05:00
ethereum -- password < passwordfile > account update < address >
2015-07-02 22:56:20 -05:00
Since only one password can be given , only format update can be performed ,
changing your password is only possible interactively .
Note that account update has the a side effect that the order of your accounts
changes .
` ,
} ,
2015-03-23 08:00:06 -05:00
{
Action : accountImport ,
Name : "import" ,
Usage : "import a private key into a new account" ,
Description : `
ethereum account import < keyfile >
2015-03-26 13:55:39 -05:00
Imports an unencrypted private key from < keyfile > and creates a new account .
Prints the address .
2015-04-08 16:03:47 -05:00
The keyfile is assumed to contain an unencrypted private key in hexadecimal format .
2015-03-23 08:00:06 -05:00
The account is saved in encrypted format , you are prompted for a passphrase .
2015-03-26 13:55:39 -05:00
You must remember this passphrase to unlock your account in the future .
2015-03-23 08:00:06 -05:00
2015-03-26 13:55:39 -05:00
For non - interactive use the passphrase can be specified with the - password flag :
2015-03-23 08:00:06 -05:00
2015-03-26 13:55:39 -05:00
ethereum -- password < passwordfile > account import < keyfile >
2015-03-23 08:00:06 -05:00
Note :
2015-03-24 11:05:27 -05:00
As you can directly copy your encrypted accounts to another ethereum instance ,
2015-03-26 13:55:39 -05:00
this import mechanism is not needed when you transfer an account between
2015-03-24 11:05:27 -05:00
nodes .
2015-03-23 08:00:06 -05:00
` ,
2015-03-07 05:39:52 -06:00
} ,
} ,
} ,
2016-03-01 16:32:43 -06:00
{
Action : initGenesis ,
Name : "init" ,
Usage : "bootstraps and initialises a new genesis block (JSON)" ,
Description : `
The init command initialises a new genesis block and definition for the network .
This is a destructive action and changes the network in which you will be
participating .
` ,
} ,
2015-03-05 20:00:41 -06:00
{
2015-03-15 01:31:40 -05:00
Action : console ,
Name : "console" ,
2015-03-26 15:27:52 -05:00
Usage : ` Geth Console: interactive JavaScript environment ` ,
2015-03-15 01:31:40 -05:00
Description : `
2015-03-26 15:27:52 -05:00
The Geth console is an interactive shell for the JavaScript runtime environment
2015-04-21 18:41:34 -05:00
which exposes a node admin interface as well as the Ðapp JavaScript API .
See https : //github.com/ethereum/go-ethereum/wiki/Javascipt-Console
2016-03-01 16:32:43 -06:00
` ,
} ,
2015-06-18 11:23:13 -05:00
{
Action : attach ,
Name : "attach" ,
2015-06-23 02:11:57 -05:00
Usage : ` Geth Console: interactive JavaScript environment (connect to node) ` ,
2015-06-18 11:23:13 -05:00
Description : `
2015-12-16 03:58:01 -06:00
The Geth console is an interactive shell for the JavaScript runtime environment
which exposes a node admin interface as well as the Ðapp JavaScript API .
See https : //github.com/ethereum/go-ethereum/wiki/Javascipt-Console.
This command allows to open a console on a running geth node .
` ,
2015-03-15 01:31:40 -05:00
} ,
{
2015-11-17 10:33:25 -06:00
Action : execScripts ,
2015-03-05 20:00:41 -06:00
Name : "js" ,
2015-03-26 15:27:52 -05:00
Usage : ` executes the given JavaScript files in the Geth JavaScript VM ` ,
2015-03-05 20:00:41 -06:00
Description : `
2015-04-21 18:41:34 -05:00
The JavaScript VM exposes a node admin interface as well as the Ðapp
2015-03-24 11:05:27 -05:00
JavaScript API . See https : //github.com/ethereum/go-ethereum/wiki/Javascipt-Console
2015-03-05 20:00:41 -06:00
` ,
} ,
}
app . Flags = [ ] cli . Flag {
2015-04-18 16:53:30 -05:00
utils . IdentityFlag ,
2015-03-10 19:08:42 -05:00
utils . UnlockedAccountFlag ,
2015-03-23 08:00:06 -05:00
utils . PasswordFileFlag ,
2015-07-10 07:29:40 -05:00
utils . GenesisFileFlag ,
2015-03-05 20:00:41 -06:00
utils . BootnodesFlag ,
utils . DataDirFlag ,
2016-03-07 16:38:56 -06:00
utils . KeyStoreDirFlag ,
2015-04-13 03:13:52 -05:00
utils . BlockchainVersionFlag ,
2015-08-03 10:48:24 -05:00
utils . OlympicFlag ,
2015-10-09 10:36:31 -05:00
utils . FastSyncFlag ,
2015-07-22 05:46:20 -05:00
utils . CacheFlag ,
2015-11-10 07:47:19 -06:00
utils . LightKDFFlag ,
2015-03-15 01:31:40 -05:00
utils . JSpathFlag ,
2015-03-05 20:00:41 -06:00
utils . ListenPortFlag ,
utils . MaxPeersFlag ,
2015-05-04 09:35:49 -05:00
utils . MaxPendingPeersFlag ,
2015-03-26 16:49:22 -05:00
utils . EtherbaseFlag ,
2015-05-09 05:00:51 -05:00
utils . GasPriceFlag ,
2015-03-05 20:00:41 -06:00
utils . MinerThreadsFlag ,
utils . MiningEnabledFlag ,
2015-06-12 00:45:23 -05:00
utils . MiningGPUFlag ,
2015-05-20 10:56:17 -05:00
utils . AutoDAGFlag ,
2016-04-04 04:04:04 -05:00
utils . TargetGasLimitFlag ,
2015-03-05 20:00:41 -06:00
utils . NATFlag ,
2015-04-08 06:22:31 -05:00
utils . NatspecEnabledFlag ,
2015-05-26 11:07:24 -05:00
utils . NoDiscoverFlag ,
2015-03-05 20:00:41 -06:00
utils . NodeKeyFileFlag ,
utils . NodeKeyHexFlag ,
utils . RPCEnabledFlag ,
utils . RPCListenAddrFlag ,
utils . RPCPortFlag ,
2015-12-16 03:58:01 -06:00
utils . RPCApiFlag ,
utils . WSEnabledFlag ,
utils . WSListenAddrFlag ,
utils . WSPortFlag ,
utils . WSApiFlag ,
2016-02-09 05:24:42 -06:00
utils . WSAllowedDomainsFlag ,
2015-06-08 04:01:02 -05:00
utils . IPCDisabledFlag ,
utils . IPCApiFlag ,
utils . IPCPathFlag ,
2015-06-19 07:04:18 -05:00
utils . ExecFlag ,
2015-04-20 10:45:37 -05:00
utils . WhisperEnabledFlag ,
2015-09-06 08:46:54 -05:00
utils . DevModeFlag ,
2015-10-05 06:01:34 -05:00
utils . TestNetFlag ,
2015-07-17 16:09:36 -05:00
utils . VMForceJitFlag ,
utils . VMJitCacheFlag ,
utils . VMEnableJitFlag ,
2015-03-18 02:44:58 -05:00
utils . NetworkIdFlag ,
2015-03-29 14:21:14 -05:00
utils . RPCCORSDomainFlag ,
2015-06-29 08:11:01 -05:00
utils . MetricsEnabledFlag ,
2015-04-22 17:11:11 -05:00
utils . SolcPathFlag ,
2015-05-26 07:17:43 -05:00
utils . GpoMinGasPriceFlag ,
utils . GpoMaxGasPriceFlag ,
utils . GpoFullBlockRatioFlag ,
utils . GpobaseStepDownFlag ,
utils . GpobaseStepUpFlag ,
utils . GpobaseCorrectionFactorFlag ,
2015-09-22 03:34:58 -05:00
utils . ExtraDataFlag ,
2015-03-05 20:00:41 -06:00
}
2016-01-26 07:39:21 -06:00
app . Flags = append ( app . Flags , debug . Flags ... )
2015-04-20 10:59:41 -05:00
app . Before = func ( ctx * cli . Context ) error {
2015-12-08 10:05:43 -06:00
runtime . GOMAXPROCS ( runtime . NumCPU ( ) )
2016-01-26 07:39:21 -06:00
if err := debug . Setup ( ctx ) ; err != nil {
return err
}
// Start system runtime metrics collection
go metrics . CollectProcessMetrics ( 3 * time . Second )
2015-12-08 10:05:43 -06:00
2015-10-07 10:21:13 -05:00
utils . SetupNetwork ( ctx )
2016-04-01 14:55:30 -05:00
// Deprecation warning.
if ctx . GlobalIsSet ( utils . GenesisFileFlag . Name ) {
common . PrintDepricationWarning ( "--genesis is deprecated. Switch to use 'geth init /path/to/file'" )
}
2015-04-20 10:59:41 -05:00
return nil
2015-03-05 20:00:41 -06:00
}
2016-01-26 07:39:21 -06:00
app . After = func ( ctx * cli . Context ) error {
logger . Flush ( )
debug . Exit ( )
return nil
}
2015-03-05 20:00:41 -06:00
}
2014-12-23 07:33:15 -06:00
2015-03-05 20:00:41 -06:00
func main ( ) {
if err := app . Run ( os . Args ) ; err != nil {
fmt . Fprintln ( os . Stderr , err )
os . Exit ( 1 )
}
}
2014-06-26 04:47:45 -05:00
2015-08-06 04:20:15 -05:00
func makeDefaultExtra ( ) [ ] byte {
var clientInfo = struct {
Version uint
Name string
GoVersion string
Os string
} { uint ( VersionMajor << 16 | VersionMinor << 8 | VersionPatch ) , ClientIdentifier , runtime . Version ( ) , runtime . GOOS }
extra , err := rlp . EncodeToBytes ( clientInfo )
if err != nil {
glog . V ( logger . Warn ) . Infoln ( "error setting canonical miner information:" , err )
}
if uint64 ( len ( extra ) ) > params . MaximumExtraDataSize . Uint64 ( ) {
glog . V ( logger . Warn ) . Infoln ( "error setting canonical miner information: extra exceeds" , params . MaximumExtraDataSize )
glog . V ( logger . Debug ) . Infof ( "extra: %x\n" , extra )
return nil
}
return extra
}
2015-11-17 10:33:25 -06:00
// geth is the main entry point into the system if no special subcommand is ran.
// It creates a default node based on the command line arguments and runs it in
// blocking mode, waiting for it to be shut down.
func geth ( ctx * cli . Context ) {
node := utils . MakeSystemNode ( ClientIdentifier , nodeNameVersion , makeDefaultExtra ( ) , ctx )
startNode ( ctx , node )
node . Wait ( )
2015-03-05 20:00:41 -06:00
}
2014-07-11 09:04:27 -05:00
2015-12-16 03:58:01 -06:00
// attach will connect to a running geth instance attaching a JavaScript console and to it.
2015-06-18 11:23:13 -05:00
func attach ( ctx * cli . Context ) {
2015-12-16 03:58:01 -06:00
// attach to a running geth instance
client , err := utils . NewRemoteRPCClient ( ctx )
2015-06-18 11:23:13 -05:00
if err != nil {
2016-02-05 07:08:48 -06:00
utils . Fatalf ( "Unable to attach to geth: %v" , err )
2015-06-18 11:23:13 -05:00
}
repl := newLightweightJSRE (
2015-06-23 02:38:30 -05:00
ctx . GlobalString ( utils . JSpathFlag . Name ) ,
2015-06-18 11:23:13 -05:00
client ,
2015-09-25 06:08:48 -05:00
ctx . GlobalString ( utils . DataDirFlag . Name ) ,
2015-06-18 11:23:13 -05:00
true ,
2015-08-07 02:56:49 -05:00
)
2015-06-18 11:23:13 -05:00
2015-06-19 07:04:18 -05:00
if ctx . GlobalString ( utils . ExecFlag . Name ) != "" {
repl . batch ( ctx . GlobalString ( utils . ExecFlag . Name ) )
} else {
repl . welcome ( )
repl . interactive ( )
}
2015-06-18 11:23:13 -05:00
}
2016-03-01 16:32:43 -06:00
// initGenesis will initialise the given JSON format genesis file and writes it as
// the zero'd block (i.e. genesis) or will fail hard if it can't succeed.
func initGenesis ( ctx * cli . Context ) {
genesisPath := ctx . Args ( ) . First ( )
if len ( genesisPath ) == 0 {
utils . Fatalf ( "must supply path to genesis JSON file" )
}
chainDb , err := ethdb . NewLDBDatabase ( filepath . Join ( utils . MustMakeDataDir ( ctx ) , "chaindata" ) , 0 , 0 )
if err != nil {
utils . Fatalf ( "could not open database: %v" , err )
}
genesisFile , err := os . Open ( genesisPath )
if err != nil {
utils . Fatalf ( "failed to read genesis file: %v" , err )
}
block , err := core . WriteGenesisBlock ( chainDb , genesisFile )
if err != nil {
utils . Fatalf ( "failed to write genesis block: %v" , err )
}
glog . V ( logger . Info ) . Infof ( "successfully wrote genesis block and/or chain rule set: %x" , block . Hash ( ) )
}
2015-11-17 10:33:25 -06:00
// console starts a new geth node, attaching a JavaScript console to it at the
// same time.
2015-03-15 01:31:40 -05:00
func console ( ctx * cli . Context ) {
2015-11-17 10:33:25 -06:00
// Create and start the node based on the CLI flags
node := utils . MakeSystemNode ( ClientIdentifier , nodeNameVersion , makeDefaultExtra ( ) , ctx )
startNode ( ctx , node )
2015-03-10 09:44:05 -05:00
2015-11-17 10:33:25 -06:00
// Attach to the newly started node, and either execute script or become interactive
2016-02-09 06:10:40 -06:00
client , err := node . Attach ( )
2016-02-05 07:08:48 -06:00
if err != nil {
utils . Fatalf ( "Failed to attach to the inproc geth: %v" , err )
}
2015-11-17 10:33:25 -06:00
repl := newJSRE ( node ,
2015-06-23 02:38:30 -05:00
ctx . GlobalString ( utils . JSpathFlag . Name ) ,
2015-04-22 17:11:11 -05:00
ctx . GlobalString ( utils . RPCCORSDomainFlag . Name ) ,
2015-12-16 03:58:01 -06:00
client , true )
2015-06-18 11:23:13 -05:00
2015-11-17 10:33:25 -06:00
if script := ctx . GlobalString ( utils . ExecFlag . Name ) ; script != "" {
repl . batch ( script )
2015-06-19 07:04:18 -05:00
} else {
repl . welcome ( )
repl . interactive ( )
}
2015-11-17 10:33:25 -06:00
node . Stop ( )
2015-03-15 01:31:40 -05:00
}
2015-11-17 10:33:25 -06:00
// execScripts starts a new geth node based on the CLI flags, and executes each
// of the JavaScript files specified as command arguments.
func execScripts ( ctx * cli . Context ) {
// Create and start the node based on the CLI flags
node := utils . MakeSystemNode ( ClientIdentifier , nodeNameVersion , makeDefaultExtra ( ) , ctx )
startNode ( ctx , node )
2015-03-15 01:31:40 -05:00
2015-11-17 10:33:25 -06:00
// Attach to the newly started node and execute the given scripts
2016-02-09 06:10:40 -06:00
client , err := node . Attach ( )
2016-02-05 07:08:48 -06:00
if err != nil {
utils . Fatalf ( "Failed to attach to the inproc geth: %v" , err )
}
2015-11-17 10:33:25 -06:00
repl := newJSRE ( node ,
2015-06-23 02:38:30 -05:00
ctx . GlobalString ( utils . JSpathFlag . Name ) ,
2015-04-22 17:11:11 -05:00
ctx . GlobalString ( utils . RPCCORSDomainFlag . Name ) ,
2015-12-16 03:58:01 -06:00
client , false )
2015-11-17 10:33:25 -06:00
2015-03-15 01:31:40 -05:00
for _ , file := range ctx . Args ( ) {
repl . exec ( file )
}
2015-11-17 10:33:25 -06:00
node . Stop ( )
2015-03-05 20:00:41 -06:00
}
2015-01-06 18:21:55 -06:00
2015-12-01 04:20:49 -06:00
// tries unlocking the specified account a few times.
2015-11-17 10:33:25 -06:00
func unlockAccount ( ctx * cli . Context , accman * accounts . Manager , address string , i int , passwords [ ] string ) ( common . Address , string ) {
2015-12-01 04:20:49 -06:00
account , err := utils . MakeAddress ( accman , address )
if err != nil {
utils . Fatalf ( "Unlock error: %v" , err )
}
2015-07-07 05:53:36 -05:00
2015-11-17 10:33:25 -06:00
for trials := 0 ; trials < 3 ; trials ++ {
prompt := fmt . Sprintf ( "Unlocking account %s | Attempt %d/%d" , address , trials + 1 , 3 )
password := getPassPhrase ( prompt , false , i , passwords )
if err := accman . Unlock ( account , password ) ; err == nil {
return account , password
}
2015-03-10 19:08:42 -05:00
}
2015-11-17 10:33:25 -06:00
// All trials expended to unlock account, bail out
utils . Fatalf ( "Failed to unlock account: %s" , address )
return common . Address { } , ""
2015-03-23 08:00:06 -05:00
}
2015-11-17 10:33:25 -06:00
// startNode boots up the system node and all registered protocols, after which
// it unlocks any requested accounts, and starts the RPC/IPC interfaces and the
// miner.
func startNode ( ctx * cli . Context , stack * node . Node ) {
// Start up the node itself
utils . StartNode ( stack )
2015-07-01 09:15:02 -05:00
2015-11-17 10:33:25 -06:00
// Unlock any account specifically requested
var ethereum * eth . Ethereum
2015-11-26 10:35:44 -06:00
if err := stack . Service ( & ethereum ) ; err != nil {
2015-11-17 10:33:25 -06:00
utils . Fatalf ( "ethereum service not running: %v" , err )
2015-06-30 17:52:44 -05:00
}
2015-11-17 10:33:25 -06:00
accman := ethereum . AccountManager ( )
passwords := utils . MakePasswordList ( ctx )
2015-03-23 08:00:06 -05:00
2015-11-17 10:33:25 -06:00
accounts := strings . Split ( ctx . GlobalString ( utils . UnlockedAccountFlag . Name ) , "," )
2015-06-18 10:20:00 -05:00
for i , account := range accounts {
2015-11-17 10:33:25 -06:00
if trimmed := strings . TrimSpace ( account ) ; trimmed != "" {
unlockAccount ( ctx , accman , trimmed , i , passwords )
2015-03-24 07:37:00 -05:00
}
2015-03-23 08:00:06 -05:00
}
2016-02-02 11:06:43 -06:00
// Start auxiliary services if enabled
2015-03-05 20:00:41 -06:00
if ctx . GlobalBool ( utils . MiningEnabledFlag . Name ) {
2015-11-17 10:33:25 -06:00
if err := ethereum . StartMining ( ctx . GlobalInt ( utils . MinerThreadsFlag . Name ) , ctx . GlobalString ( utils . MiningGPUFlag . Name ) ) ; err != nil {
utils . Fatalf ( "Failed to start mining: %v" , err )
2015-04-21 19:36:28 -05:00
}
2015-03-05 20:00:41 -06:00
}
}
2015-01-05 10:10:42 -06:00
2015-03-07 05:39:52 -06:00
func accountList ( ctx * cli . Context ) {
2015-11-17 10:33:25 -06:00
accman := utils . MakeAccountManager ( ctx )
accts , err := accman . Accounts ( )
2015-03-07 05:39:52 -06:00
if err != nil {
utils . Fatalf ( "Could not list accounts: %v" , err )
}
2015-04-21 18:41:34 -05:00
for i , acct := range accts {
2015-06-20 22:01:12 -05:00
fmt . Printf ( "Account #%d: %x\n" , i , acct )
2015-03-07 05:39:52 -06:00
}
}
2015-11-17 10:33:25 -06:00
// getPassPhrase retrieves the passwor associated with an account, either fetched
// from a list of preloaded passphrases, or requested interactively from the user.
func getPassPhrase ( prompt string , confirmation bool , i int , passwords [ ] string ) string {
// If a list of passwords was supplied, retrieve from them
if len ( passwords ) > 0 {
if i < len ( passwords ) {
return passwords [ i ]
2015-03-26 13:55:39 -05:00
}
2015-11-17 10:33:25 -06:00
return passwords [ len ( passwords ) - 1 ]
}
// Otherwise prompt the user for the password
fmt . Println ( prompt )
password , err := utils . PromptPassword ( "Passphrase: " , true )
if err != nil {
utils . Fatalf ( "Failed to read passphrase: %v" , err )
}
if confirmation {
confirm , err := utils . PromptPassword ( "Repeat passphrase: " , false )
if err != nil {
utils . Fatalf ( "Failed to read passphrase confirmation: %v" , err )
2015-03-11 07:56:02 -05:00
}
2015-11-17 10:33:25 -06:00
if password != confirm {
utils . Fatalf ( "Passphrases do not match" )
2015-06-18 10:20:00 -05:00
}
2015-03-07 05:39:52 -06:00
}
2015-11-17 10:33:25 -06:00
return password
2015-03-23 08:00:06 -05:00
}
2015-11-17 10:33:25 -06:00
// accountCreate creates a new account into the keystore defined by the CLI flags.
2015-03-23 08:00:06 -05:00
func accountCreate ( ctx * cli . Context ) {
2015-11-17 10:33:25 -06:00
accman := utils . MakeAccountManager ( ctx )
password := getPassPhrase ( "Your new account is locked with a password. Please give a password. Do not forget this password." , true , 0 , utils . MakePasswordList ( ctx ) )
account , err := accman . NewAccount ( password )
2015-03-07 05:39:52 -06:00
if err != nil {
2015-11-17 10:33:25 -06:00
utils . Fatalf ( "Failed to create account: %v" , err )
2015-03-07 05:39:52 -06:00
}
2015-11-17 10:33:25 -06:00
fmt . Printf ( "Address: %x\n" , account )
2015-03-23 08:00:06 -05:00
}
2015-11-17 10:33:25 -06:00
// accountUpdate transitions an account from a previous format to the current
// one, also providing the possibility to change the pass-phrase.
2015-07-02 22:56:20 -05:00
func accountUpdate ( ctx * cli . Context ) {
2015-11-17 10:33:25 -06:00
if len ( ctx . Args ( ) ) == 0 {
utils . Fatalf ( "No accounts specified to update" )
2015-07-02 22:56:20 -05:00
}
2015-11-17 10:33:25 -06:00
accman := utils . MakeAccountManager ( ctx )
2015-07-02 22:56:20 -05:00
2015-11-17 10:33:25 -06:00
account , oldPassword := unlockAccount ( ctx , accman , ctx . Args ( ) . First ( ) , 0 , nil )
newPassword := getPassPhrase ( "Please give a new password. Do not forget this password." , true , 0 , nil )
if err := accman . Update ( account , oldPassword , newPassword ) ; err != nil {
2015-07-02 22:56:20 -05:00
utils . Fatalf ( "Could not update the account: %v" , err )
}
}
2015-03-24 11:19:11 -05: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 )
}
2015-11-17 10:33:25 -06:00
accman := utils . MakeAccountManager ( ctx )
passphrase := getPassPhrase ( "" , false , 0 , utils . MakePasswordList ( ctx ) )
2015-03-24 11:19:11 -05:00
2015-11-17 10:33:25 -06:00
acct , err := accman . ImportPreSaleKey ( keyJson , passphrase )
2015-03-24 11:19:11 -05:00
if err != nil {
utils . Fatalf ( "Could not create the account: %v" , err )
}
fmt . Printf ( "Address: %x\n" , acct )
}
2015-03-23 08:00:06 -05:00
func accountImport ( ctx * cli . Context ) {
keyfile := ctx . Args ( ) . First ( )
if len ( keyfile ) == 0 {
utils . Fatalf ( "keyfile must be given as argument" )
}
2015-11-17 10:33:25 -06:00
accman := utils . MakeAccountManager ( ctx )
passphrase := getPassPhrase ( "Your new account is locked with a password. Please give a password. Do not forget this password." , true , 0 , utils . MakePasswordList ( ctx ) )
acct , err := accman . Import ( keyfile , passphrase )
2015-03-23 08:00:06 -05:00
if err != nil {
utils . Fatalf ( "Could not create the account: %v" , err )
}
fmt . Printf ( "Address: %x\n" , acct )
}
2015-03-17 08:12:34 -05:00
func makedag ( ctx * cli . Context ) {
2015-05-05 01:24:15 -05:00
args := ctx . Args ( )
wrongArgs := func ( ) {
utils . Fatalf ( ` Usage: geth makedag <block number> <outputdir> ` )
}
switch {
case len ( args ) == 2 :
blockNum , err := strconv . ParseUint ( args [ 0 ] , 0 , 64 )
dir := args [ 1 ]
if err != nil {
wrongArgs ( )
} else {
dir = filepath . Clean ( dir )
// seems to require a trailing slash
if ! strings . HasSuffix ( dir , "/" ) {
dir = dir + "/"
}
_ , err = ioutil . ReadDir ( dir )
if err != nil {
utils . Fatalf ( "Can't find dir" )
}
fmt . Println ( "making DAG, this could take awhile..." )
ethash . MakeDAG ( blockNum , dir )
}
default :
wrongArgs ( )
}
2015-03-17 08:12:34 -05:00
}
2015-06-12 00:45:23 -05:00
func gpuinfo ( ctx * cli . Context ) {
eth . PrintOpenCLDevices ( )
}
func gpubench ( ctx * cli . Context ) {
args := ctx . Args ( )
wrongArgs := func ( ) {
utils . Fatalf ( ` Usage: geth gpubench <gpu number> ` )
}
switch {
case len ( args ) == 1 :
n , err := strconv . ParseUint ( args [ 0 ] , 0 , 64 )
if err != nil {
wrongArgs ( )
}
eth . GPUBench ( n )
case len ( args ) == 0 :
eth . GPUBench ( 0 )
default :
wrongArgs ( )
}
}
2015-03-05 20:00:41 -06:00
func version ( c * cli . Context ) {
2015-04-28 06:14:53 -05:00
fmt . Println ( ClientIdentifier )
fmt . Println ( "Version:" , Version )
if gitCommit != "" {
fmt . Println ( "Git Commit:" , gitCommit )
}
2015-06-26 08:54:27 -05:00
fmt . Println ( "Protocol Versions:" , eth . ProtocolVersions )
2015-04-28 06:14:53 -05:00
fmt . Println ( "Network Id:" , c . GlobalInt ( utils . NetworkIdFlag . Name ) )
fmt . Println ( "Go Version:" , runtime . Version ( ) )
fmt . Println ( "OS:" , runtime . GOOS )
fmt . Printf ( "GOPATH=%s\n" , os . Getenv ( "GOPATH" ) )
fmt . Printf ( "GOROOT=%s\n" , runtime . GOROOT ( ) )
2015-01-06 18:21:55 -06:00
}