github.com/gilgames000/kcc-geth@v1.0.6/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 "fmt" 21 "path/filepath" 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(nodeFlags, rpcFlags...), consoleFlags...), 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://geth.ethereum.org/docs/interface/javascript-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://geth.ethereum.org/docs/interface/javascript-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://geth.ethereum.org/docs/interface/javascript-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 prepare(ctx) 78 stack, backend := makeFullNode(ctx) 79 startNode(ctx, stack, backend) 80 defer stack.Close() 81 82 // Attach to the newly started node and start the JavaScript console 83 client, err := stack.Attach() 84 if err != nil { 85 utils.Fatalf("Failed to attach to the inproc geth: %v", err) 86 } 87 config := console.Config{ 88 DataDir: utils.MakeDataDir(ctx), 89 DocRoot: ctx.GlobalString(utils.JSpathFlag.Name), 90 Client: client, 91 Preload: utils.MakeConsolePreloads(ctx), 92 } 93 94 console, err := console.New(config) 95 if err != nil { 96 utils.Fatalf("Failed to start the JavaScript console: %v", err) 97 } 98 defer console.Stop(false) 99 100 // If only a short execution was requested, evaluate and return 101 if script := ctx.GlobalString(utils.ExecFlag.Name); script != "" { 102 console.Evaluate(script) 103 return nil 104 } 105 // Otherwise print the welcome screen and enter interactive mode 106 console.Welcome() 107 console.Interactive() 108 109 return nil 110 } 111 112 // remoteConsole will connect to a remote geth instance, attaching a JavaScript 113 // console to it. 114 func remoteConsole(ctx *cli.Context) error { 115 // Attach to a remotely running geth instance and start the JavaScript console 116 endpoint := ctx.Args().First() 117 if endpoint == "" { 118 path := node.DefaultDataDir() 119 if ctx.GlobalIsSet(utils.DataDirFlag.Name) { 120 path = ctx.GlobalString(utils.DataDirFlag.Name) 121 } 122 if path != "" && ctx.GlobalBool(utils.TestnetFlag.Name) { 123 path = filepath.Join(path, "testnet") 124 } 125 endpoint = fmt.Sprintf("%s/geth.ipc", path) 126 } 127 client, err := dialRPC(endpoint) 128 if err != nil { 129 utils.Fatalf("Unable to attach to remote geth: %v", err) 130 } 131 config := console.Config{ 132 DataDir: utils.MakeDataDir(ctx), 133 DocRoot: ctx.GlobalString(utils.JSpathFlag.Name), 134 Client: client, 135 Preload: utils.MakeConsolePreloads(ctx), 136 } 137 138 console, err := console.New(config) 139 if err != nil { 140 utils.Fatalf("Failed to start the JavaScript console: %v", err) 141 } 142 defer console.Stop(false) 143 144 if script := ctx.GlobalString(utils.ExecFlag.Name); script != "" { 145 console.Evaluate(script) 146 return nil 147 } 148 149 // Otherwise print the welcome screen and enter interactive mode 150 console.Welcome() 151 console.Interactive() 152 153 return nil 154 } 155 156 // dialRPC returns a RPC client which connects to the given endpoint. 157 // The check for empty endpoint implements the defaulting logic 158 // for "geth attach" and "geth monitor" with no argument. 159 func dialRPC(endpoint string) (*rpc.Client, error) { 160 if endpoint == "" { 161 endpoint = node.DefaultIPCEndpoint(clientIdentifier) 162 } else if strings.HasPrefix(endpoint, "rpc:") || strings.HasPrefix(endpoint, "ipc:") { 163 // Backwards compatibility with geth < 1.5 which required 164 // these prefixes. 165 endpoint = endpoint[4:] 166 } 167 return rpc.Dial(endpoint) 168 } 169 170 // ephemeralConsole starts a new geth node, attaches an ephemeral JavaScript 171 // console to it, executes each of the files specified as arguments and tears 172 // everything down. 173 func ephemeralConsole(ctx *cli.Context) error { 174 // Create and start the node based on the CLI flags 175 stack, backend := makeFullNode(ctx) 176 startNode(ctx, stack, backend) 177 defer stack.Close() 178 179 // Attach to the newly started node and start the JavaScript console 180 client, err := stack.Attach() 181 if err != nil { 182 utils.Fatalf("Failed to attach to the inproc geth: %v", err) 183 } 184 config := console.Config{ 185 DataDir: utils.MakeDataDir(ctx), 186 DocRoot: ctx.GlobalString(utils.JSpathFlag.Name), 187 Client: client, 188 Preload: utils.MakeConsolePreloads(ctx), 189 } 190 191 console, err := console.New(config) 192 if err != nil { 193 utils.Fatalf("Failed to start the JavaScript console: %v", err) 194 } 195 defer console.Stop(false) 196 197 // Evaluate each of the specified JavaScript files 198 for _, file := range ctx.Args() { 199 if err = console.Execute(file); err != nil { 200 utils.Fatalf("Failed to execute %s: %v", file, err) 201 } 202 } 203 204 go func() { 205 stack.Wait() 206 console.Stop(false) 207 }() 208 console.Stop(true) 209 210 return nil 211 }