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