github.com/cryptotooltop/go-ethereum@v0.0.0-20231103184714-151d1922f3e5/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 "os" 22 "path/filepath" 23 "strings" 24 25 "gopkg.in/urfave/cli.v1" 26 27 "github.com/scroll-tech/go-ethereum/cmd/utils" 28 "github.com/scroll-tech/go-ethereum/console" 29 "github.com/scroll-tech/go-ethereum/node" 30 "github.com/scroll-tech/go-ethereum/rpc" 31 ) 32 33 var ( 34 consoleFlags = []cli.Flag{utils.JSpathFlag, utils.ExecFlag, utils.PreloadJSFlag} 35 36 consoleCommand = cli.Command{ 37 Action: utils.MigrateFlags(localConsole), 38 Name: "console", 39 Usage: "Start an interactive JavaScript environment", 40 Flags: append(append(nodeFlags, rpcFlags...), consoleFlags...), 41 Category: "CONSOLE COMMANDS", 42 Description: ` 43 The Geth console is an interactive shell for the JavaScript runtime environment 44 which exposes a node admin interface as well as the Ðapp JavaScript API. 45 See https://geth.ethereum.org/docs/interface/javascript-console.`, 46 } 47 48 attachCommand = cli.Command{ 49 Action: utils.MigrateFlags(remoteConsole), 50 Name: "attach", 51 Usage: "Start an interactive JavaScript environment (connect to node)", 52 ArgsUsage: "[endpoint]", 53 Flags: append(consoleFlags, utils.DataDirFlag), 54 Category: "CONSOLE COMMANDS", 55 Description: ` 56 The Geth console is an interactive shell for the JavaScript runtime environment 57 which exposes a node admin interface as well as the Ðapp JavaScript API. 58 See https://geth.ethereum.org/docs/interface/javascript-console. 59 This command allows to open a console on a running geth node.`, 60 } 61 62 javascriptCommand = cli.Command{ 63 Action: utils.MigrateFlags(ephemeralConsole), 64 Name: "js", 65 Usage: "Execute the specified JavaScript files", 66 ArgsUsage: "<jsfile> [jsfile...]", 67 Flags: append(nodeFlags, consoleFlags...), 68 Category: "CONSOLE COMMANDS", 69 Description: ` 70 The JavaScript VM exposes a node admin interface as well as the Ðapp 71 JavaScript API. See https://geth.ethereum.org/docs/interface/javascript-console`, 72 } 73 ) 74 75 // localConsole starts a new geth node, attaching a JavaScript console to it at the 76 // same time. 77 func localConsole(ctx *cli.Context) error { 78 // Create and start the node based on the CLI flags 79 prepare(ctx) 80 stack, backend := makeFullNode(ctx) 81 startNode(ctx, stack, backend) 82 defer stack.Close() 83 84 // Attach to the newly started node and start the JavaScript console 85 client, err := stack.Attach() 86 if err != nil { 87 utils.Fatalf("Failed to attach to the inproc geth: %v", err) 88 } 89 config := console.Config{ 90 DataDir: utils.MakeDataDir(ctx), 91 DocRoot: ctx.GlobalString(utils.JSpathFlag.Name), 92 Client: client, 93 Preload: utils.MakeConsolePreloads(ctx), 94 } 95 96 console, err := console.New(config) 97 if err != nil { 98 utils.Fatalf("Failed to start the JavaScript console: %v", err) 99 } 100 defer console.Stop(false) 101 102 // If only a short execution was requested, evaluate and return 103 if script := ctx.GlobalString(utils.ExecFlag.Name); script != "" { 104 console.Evaluate(script) 105 return nil 106 } 107 // Otherwise print the welcome screen and enter interactive mode 108 console.Welcome() 109 console.Interactive() 110 111 return nil 112 } 113 114 // remoteConsole will connect to a remote geth instance, attaching a JavaScript 115 // console to it. 116 func remoteConsole(ctx *cli.Context) error { 117 // Attach to a remotely running geth instance and start the JavaScript console 118 endpoint := ctx.Args().First() 119 if endpoint == "" { 120 path := node.DefaultDataDir() 121 if ctx.GlobalIsSet(utils.DataDirFlag.Name) { 122 path = ctx.GlobalString(utils.DataDirFlag.Name) 123 } 124 if path != "" { 125 if ctx.GlobalBool(utils.RopstenFlag.Name) { 126 // Maintain compatibility with older Geth configurations storing the 127 // Ropsten database in `testnet` instead of `ropsten`. 128 legacyPath := filepath.Join(path, "testnet") 129 if _, err := os.Stat(legacyPath); !os.IsNotExist(err) { 130 path = legacyPath 131 } else { 132 path = filepath.Join(path, "ropsten") 133 } 134 } else if ctx.GlobalBool(utils.RinkebyFlag.Name) { 135 path = filepath.Join(path, "rinkeby") 136 } else if ctx.GlobalBool(utils.GoerliFlag.Name) { 137 path = filepath.Join(path, "goerli") 138 } else if ctx.GlobalBool(utils.SepoliaFlag.Name) { 139 path = filepath.Join(path, "sepolia") 140 } else if ctx.GlobalBool(utils.ScrollAlphaFlag.Name) { 141 path = filepath.Join(path, "scroll-alpha") 142 } else if ctx.GlobalBool(utils.ScrollSepoliaFlag.Name) { 143 path = filepath.Join(path, "scroll-sepolia") 144 } else if ctx.GlobalBool(utils.ScrollFlag.Name) { 145 path = filepath.Join(path, "scroll") 146 } 147 } 148 endpoint = fmt.Sprintf("%s/geth.ipc", path) 149 } 150 client, err := dialRPC(endpoint) 151 if err != nil { 152 utils.Fatalf("Unable to attach to remote geth: %v", err) 153 } 154 config := console.Config{ 155 DataDir: utils.MakeDataDir(ctx), 156 DocRoot: ctx.GlobalString(utils.JSpathFlag.Name), 157 Client: client, 158 Preload: utils.MakeConsolePreloads(ctx), 159 } 160 161 console, err := console.New(config) 162 if err != nil { 163 utils.Fatalf("Failed to start the JavaScript console: %v", err) 164 } 165 defer console.Stop(false) 166 167 if script := ctx.GlobalString(utils.ExecFlag.Name); script != "" { 168 console.Evaluate(script) 169 return nil 170 } 171 172 // Otherwise print the welcome screen and enter interactive mode 173 console.Welcome() 174 console.Interactive() 175 176 return nil 177 } 178 179 // dialRPC returns a RPC client which connects to the given endpoint. 180 // The check for empty endpoint implements the defaulting logic 181 // for "geth attach" with no argument. 182 func dialRPC(endpoint string) (*rpc.Client, error) { 183 if endpoint == "" { 184 endpoint = node.DefaultIPCEndpoint(clientIdentifier) 185 } else if strings.HasPrefix(endpoint, "rpc:") || strings.HasPrefix(endpoint, "ipc:") { 186 // Backwards compatibility with geth < 1.5 which required 187 // these prefixes. 188 endpoint = endpoint[4:] 189 } 190 return rpc.Dial(endpoint) 191 } 192 193 // ephemeralConsole starts a new geth node, attaches an ephemeral JavaScript 194 // console to it, executes each of the files specified as arguments and tears 195 // everything down. 196 func ephemeralConsole(ctx *cli.Context) error { 197 // Create and start the node based on the CLI flags 198 stack, backend := makeFullNode(ctx) 199 startNode(ctx, stack, backend) 200 defer stack.Close() 201 202 // Attach to the newly started node and start the JavaScript console 203 client, err := stack.Attach() 204 if err != nil { 205 utils.Fatalf("Failed to attach to the inproc geth: %v", err) 206 } 207 config := console.Config{ 208 DataDir: utils.MakeDataDir(ctx), 209 DocRoot: ctx.GlobalString(utils.JSpathFlag.Name), 210 Client: client, 211 Preload: utils.MakeConsolePreloads(ctx), 212 } 213 214 console, err := console.New(config) 215 if err != nil { 216 utils.Fatalf("Failed to start the JavaScript console: %v", err) 217 } 218 defer console.Stop(false) 219 220 // Evaluate each of the specified JavaScript files 221 for _, file := range ctx.Args() { 222 if err = console.Execute(file); err != nil { 223 utils.Fatalf("Failed to execute %s: %v", file, err) 224 } 225 } 226 227 go func() { 228 stack.Wait() 229 console.Stop(false) 230 }() 231 console.Stop(true) 232 233 return nil 234 }