github.com/daethereum/go-dae@v2.2.3+incompatible/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 "strings" 22 23 "github.com/daethereum/go-dae/cmd/utils" 24 "github.com/daethereum/go-dae/console" 25 "github.com/daethereum/go-dae/internal/flags" 26 "github.com/daethereum/go-dae/node" 27 "github.com/daethereum/go-dae/rpc" 28 "github.com/urfave/cli/v2" 29 ) 30 31 var ( 32 consoleFlags = []cli.Flag{utils.JSpathFlag, utils.ExecFlag, utils.PreloadJSFlag} 33 34 consoleCommand = &cli.Command{ 35 Action: localConsole, 36 Name: "console", 37 Usage: "Start an interactive JavaScript environment", 38 Flags: flags.Merge(nodeFlags, rpcFlags, consoleFlags), 39 Description: ` 40 The Geth console is an interactive shell for the JavaScript runtime environment 41 which exposes a node admin interface as well as the Ðapp JavaScript API. 42 See https://geth.ethereum.org/docs/interface/javascript-console.`, 43 } 44 45 attachCommand = &cli.Command{ 46 Action: remoteConsole, 47 Name: "attach", 48 Usage: "Start an interactive JavaScript environment (connect to node)", 49 ArgsUsage: "[endpoint]", 50 Flags: flags.Merge([]cli.Flag{utils.DataDirFlag}, consoleFlags), 51 Description: ` 52 The Geth console is an interactive shell for the JavaScript runtime environment 53 which exposes a node admin interface as well as the Ðapp JavaScript API. 54 See https://geth.ethereum.org/docs/interface/javascript-console. 55 This command allows to open a console on a running geth node.`, 56 } 57 58 javascriptCommand = &cli.Command{ 59 Action: ephemeralConsole, 60 Name: "js", 61 Usage: "(DEPRECATED) Execute the specified JavaScript files", 62 ArgsUsage: "<jsfile> [jsfile...]", 63 Flags: flags.Merge(nodeFlags, consoleFlags), 64 Description: ` 65 The JavaScript VM exposes a node admin interface as well as the Ðapp 66 JavaScript API. See https://geth.ethereum.org/docs/interface/javascript-console`, 67 } 68 ) 69 70 // localConsole starts a new geth node, attaching a JavaScript console to it at the 71 // same time. 72 func localConsole(ctx *cli.Context) error { 73 // Create and start the node based on the CLI flags 74 prepare(ctx) 75 stack, backend := makeFullNode(ctx) 76 startNode(ctx, stack, backend, true) 77 defer stack.Close() 78 79 // Attach to the newly started node and create the JavaScript console. 80 client, err := stack.Attach() 81 if err != nil { 82 return fmt.Errorf("Failed to attach to the inproc geth: %v", err) 83 } 84 config := console.Config{ 85 DataDir: utils.MakeDataDir(ctx), 86 DocRoot: ctx.String(utils.JSpathFlag.Name), 87 Client: client, 88 Preload: utils.MakeConsolePreloads(ctx), 89 } 90 console, err := console.New(config) 91 if err != nil { 92 return fmt.Errorf("Failed to start the JavaScript console: %v", err) 93 } 94 defer console.Stop(false) 95 96 // If only a short execution was requested, evaluate and return. 97 if script := ctx.String(utils.ExecFlag.Name); script != "" { 98 console.Evaluate(script) 99 return nil 100 } 101 102 // Track node shutdown and stop the console when it goes down. 103 // This happens when SIGTERM is sent to the process. 104 go func() { 105 stack.Wait() 106 console.StopInteractive() 107 }() 108 109 // Print the welcome screen and enter interactive mode. 110 console.Welcome() 111 console.Interactive() 112 return nil 113 } 114 115 // remoteConsole will connect to a remote geth instance, attaching a JavaScript 116 // console to it. 117 func remoteConsole(ctx *cli.Context) error { 118 if ctx.Args().Len() > 1 { 119 utils.Fatalf("invalid command-line: too many arguments") 120 } 121 122 endpoint := ctx.Args().First() 123 if endpoint == "" { 124 cfg := defaultNodeConfig() 125 utils.SetDataDir(ctx, &cfg) 126 endpoint = cfg.IPCEndpoint() 127 } 128 client, err := dialRPC(endpoint) 129 if err != nil { 130 utils.Fatalf("Unable to attach to remote geth: %v", err) 131 } 132 config := console.Config{ 133 DataDir: utils.MakeDataDir(ctx), 134 DocRoot: ctx.String(utils.JSpathFlag.Name), 135 Client: client, 136 Preload: utils.MakeConsolePreloads(ctx), 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.String(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 return nil 153 } 154 155 // ephemeralConsole starts a new geth node, attaches an ephemeral JavaScript 156 // console to it, executes each of the files specified as arguments and tears 157 // everything down. 158 func ephemeralConsole(ctx *cli.Context) error { 159 var b strings.Builder 160 for _, file := range ctx.Args().Slice() { 161 b.Write([]byte(fmt.Sprintf("loadScript('%s');", file))) 162 } 163 utils.Fatalf(`The "js" command is deprecated. Please use the following instead: 164 geth --exec "%s" console`, b.String()) 165 return nil 166 } 167 168 // dialRPC returns a RPC client which connects to the given endpoint. 169 // The check for empty endpoint implements the defaulting logic 170 // for "geth attach" with no argument. 171 func dialRPC(endpoint string) (*rpc.Client, error) { 172 if endpoint == "" { 173 endpoint = node.DefaultIPCEndpoint(clientIdentifier) 174 } else if strings.HasPrefix(endpoint, "rpc:") || strings.HasPrefix(endpoint, "ipc:") { 175 // Backwards compatibility with geth < 1.5 which required 176 // these prefixes. 177 endpoint = endpoint[4:] 178 } 179 return rpc.Dial(endpoint) 180 }