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