github.com/tuotoo/go-ethereum@v1.7.4-0.20171121184211-049797d40a24/cmd/geth/consolecmd.go (about) 1 // Copyright 2016 The go-ethereum Authors 2 // This file is part of go-ethereum. 3 // 4 // go-ethereum is free software: you can redistribute it and/or modify 5 // it under the terms of the GNU General Public License as published by 6 // the Free Software Foundation, either version 3 of the License, or 7 // (at your option) any later version. 8 // 9 // go-ethereum is distributed in the hope that it will be useful, 10 // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 // GNU General Public License for more details. 13 // 14 // You should have received a copy of the GNU General Public License 15 // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. 16 17 package main 18 19 import ( 20 "os" 21 "os/signal" 22 "strings" 23 24 "github.com/ethereum/go-ethereum/cmd/utils" 25 "github.com/ethereum/go-ethereum/console" 26 "github.com/ethereum/go-ethereum/node" 27 "github.com/ethereum/go-ethereum/rpc" 28 "gopkg.in/urfave/cli.v1" 29 ) 30 31 var ( 32 consoleFlags = []cli.Flag{utils.JSpathFlag, utils.ExecFlag, utils.PreloadJSFlag} 33 34 consoleCommand = cli.Command{ 35 Action: utils.MigrateFlags(localConsole), 36 Name: "console", 37 Usage: "Start an interactive JavaScript environment", 38 Flags: append(append(append(nodeFlags, rpcFlags...), consoleFlags...), whisperFlags...), 39 Category: "CONSOLE COMMANDS", 40 Description: ` 41 The Geth console is an interactive shell for the JavaScript runtime environment 42 which exposes a node admin interface as well as the Ðapp JavaScript API. 43 See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Console.`, 44 } 45 46 attachCommand = cli.Command{ 47 Action: utils.MigrateFlags(remoteConsole), 48 Name: "attach", 49 Usage: "Start an interactive JavaScript environment (connect to node)", 50 ArgsUsage: "[endpoint]", 51 Flags: append(consoleFlags, utils.DataDirFlag), 52 Category: "CONSOLE COMMANDS", 53 Description: ` 54 The Geth console is an interactive shell for the JavaScript runtime environment 55 which exposes a node admin interface as well as the Ðapp JavaScript API. 56 See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Console. 57 This command allows to open a console on a running geth node.`, 58 } 59 60 javascriptCommand = cli.Command{ 61 Action: utils.MigrateFlags(ephemeralConsole), 62 Name: "js", 63 Usage: "Execute the specified JavaScript files", 64 ArgsUsage: "<jsfile> [jsfile...]", 65 Flags: append(nodeFlags, consoleFlags...), 66 Category: "CONSOLE COMMANDS", 67 Description: ` 68 The JavaScript VM exposes a node admin interface as well as the Ðapp 69 JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Console`, 70 } 71 ) 72 73 // localConsole starts a new geth node, attaching a JavaScript console to it at the 74 // same time. 75 func localConsole(ctx *cli.Context) error { 76 // Create and start the node based on the CLI flags 77 node := makeFullNode(ctx) 78 startNode(ctx, node) 79 defer node.Stop() 80 81 // Attach to the newly started node and start the JavaScript console 82 client, err := node.Attach() 83 if err != nil { 84 utils.Fatalf("Failed to attach to the inproc geth: %v", err) 85 } 86 config := console.Config{ 87 DataDir: utils.MakeDataDir(ctx), 88 DocRoot: ctx.GlobalString(utils.JSpathFlag.Name), 89 Client: client, 90 Preload: utils.MakeConsolePreloads(ctx), 91 } 92 93 console, err := console.New(config) 94 if err != nil { 95 utils.Fatalf("Failed to start the JavaScript console: %v", err) 96 } 97 defer console.Stop(false) 98 99 // If only a short execution was requested, evaluate and return 100 if script := ctx.GlobalString(utils.ExecFlag.Name); script != "" { 101 console.Evaluate(script) 102 return nil 103 } 104 // Otherwise print the welcome screen and enter interactive mode 105 console.Welcome() 106 console.Interactive() 107 108 return nil 109 } 110 111 // remoteConsole will connect to a remote geth instance, attaching a JavaScript 112 // console to it. 113 func remoteConsole(ctx *cli.Context) error { 114 // Attach to a remotely running geth instance and start the JavaScript console 115 client, err := dialRPC(ctx.Args().First()) 116 if err != nil { 117 utils.Fatalf("Unable to attach to remote geth: %v", err) 118 } 119 config := console.Config{ 120 DataDir: utils.MakeDataDir(ctx), 121 DocRoot: ctx.GlobalString(utils.JSpathFlag.Name), 122 Client: client, 123 Preload: utils.MakeConsolePreloads(ctx), 124 } 125 126 console, err := console.New(config) 127 if err != nil { 128 utils.Fatalf("Failed to start the JavaScript console: %v", err) 129 } 130 defer console.Stop(false) 131 132 if script := ctx.GlobalString(utils.ExecFlag.Name); script != "" { 133 console.Evaluate(script) 134 return nil 135 } 136 137 // Otherwise print the welcome screen and enter interactive mode 138 console.Welcome() 139 console.Interactive() 140 141 return nil 142 } 143 144 // dialRPC returns a RPC client which connects to the given endpoint. 145 // The check for empty endpoint implements the defaulting logic 146 // for "geth attach" and "geth monitor" with no argument. 147 func dialRPC(endpoint string) (*rpc.Client, error) { 148 if endpoint == "" { 149 endpoint = node.DefaultIPCEndpoint(clientIdentifier) 150 } else if strings.HasPrefix(endpoint, "rpc:") || strings.HasPrefix(endpoint, "ipc:") { 151 // Backwards compatibility with geth < 1.5 which required 152 // these prefixes. 153 endpoint = endpoint[4:] 154 } 155 return rpc.Dial(endpoint) 156 } 157 158 // ephemeralConsole starts a new geth node, attaches an ephemeral JavaScript 159 // console to it, executes each of the files specified as arguments and tears 160 // everything down. 161 func ephemeralConsole(ctx *cli.Context) error { 162 // Create and start the node based on the CLI flags 163 node := makeFullNode(ctx) 164 startNode(ctx, node) 165 defer node.Stop() 166 167 // Attach to the newly started node and start the JavaScript console 168 client, err := node.Attach() 169 if err != nil { 170 utils.Fatalf("Failed to attach to the inproc geth: %v", err) 171 } 172 config := console.Config{ 173 DataDir: utils.MakeDataDir(ctx), 174 DocRoot: ctx.GlobalString(utils.JSpathFlag.Name), 175 Client: client, 176 Preload: utils.MakeConsolePreloads(ctx), 177 } 178 179 console, err := console.New(config) 180 if err != nil { 181 utils.Fatalf("Failed to start the JavaScript console: %v", err) 182 } 183 defer console.Stop(false) 184 185 // Evaluate each of the specified JavaScript files 186 for _, file := range ctx.Args() { 187 if err = console.Execute(file); err != nil { 188 utils.Fatalf("Failed to execute %s: %v", file, err) 189 } 190 } 191 // Wait for pending callbacks, but stop for Ctrl-C. 192 abort := make(chan os.Signal, 1) 193 signal.Notify(abort, os.Interrupt) 194 195 go func() { 196 <-abort 197 os.Exit(0) 198 }() 199 console.Stop(true) 200 201 return nil 202 }