github.com/cheng762/platon-go@v1.8.17-0.20190529111256-7deff2d7be26/cmd/platon/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 "os/signal" 23 "path/filepath" 24 "strings" 25 "syscall" 26 27 "github.com/PlatONnetwork/PlatON-Go/cmd/utils" 28 "github.com/PlatONnetwork/PlatON-Go/console" 29 "github.com/PlatONnetwork/PlatON-Go/node" 30 "github.com/PlatONnetwork/PlatON-Go/rpc" 31 "gopkg.in/urfave/cli.v1" 32 ) 33 34 var ( 35 consoleFlags = []cli.Flag{utils.JSpathFlag, utils.ExecFlag, utils.PreloadJSFlag} 36 37 consoleCommand = cli.Command{ 38 Action: utils.MigrateFlags(localConsole), 39 Name: "console", 40 Usage: "Start an interactive JavaScript environment", 41 Flags: append(append(append(nodeFlags, rpcFlags...), consoleFlags...), whisperFlags...), 42 Category: "CONSOLE COMMANDS", 43 Description: ` 44 The Geth console is an interactive shell for the JavaScript runtime environment 45 which exposes a node admin interface as well as the Ðapp JavaScript API. 46 See https://github.com/ethereum/go-ethereum/wiki/JavaScript-Console.`, 47 } 48 49 attachCommand = cli.Command{ 50 Action: utils.MigrateFlags(remoteConsole), 51 Name: "attach", 52 Usage: "Start an interactive JavaScript environment (connect to node)", 53 ArgsUsage: "[endpoint]", 54 Flags: append(consoleFlags, utils.DataDirFlag), 55 Category: "CONSOLE COMMANDS", 56 Description: ` 57 The Geth console is an interactive shell for the JavaScript runtime environment 58 which exposes a node admin interface as well as the Ðapp JavaScript API. 59 See https://github.com/ethereum/go-ethereum/wiki/JavaScript-Console. 60 This command allows to open a console on a running platon node.`, 61 } 62 63 javascriptCommand = cli.Command{ 64 Action: utils.MigrateFlags(ephemeralConsole), 65 Name: "js", 66 Usage: "Execute the specified JavaScript files", 67 ArgsUsage: "<jsfile> [jsfile...]", 68 Flags: append(nodeFlags, consoleFlags...), 69 Category: "CONSOLE COMMANDS", 70 Description: ` 71 The JavaScript VM exposes a node admin interface as well as the Ðapp 72 JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/JavaScript-Console`, 73 } 74 ) 75 76 // localConsole starts a new platon node, attaching a JavaScript console to it at the 77 // same time. 78 func localConsole(ctx *cli.Context) error { 79 // Create and start the node based on the CLI flags 80 node := makeFullNode(ctx) 81 startNode(ctx, node) 82 defer node.Stop() 83 84 // Attach to the newly started node and start the JavaScript console 85 client, err := node.Attach() 86 if err != nil { 87 utils.Fatalf("Failed to attach to the inproc platon: %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 platon instance, attaching a JavaScript 115 // console to it. 116 func remoteConsole(ctx *cli.Context) error { 117 // Attach to a remotely running platon 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.TestnetFlag.Name) { 126 path = filepath.Join(path, "testnet") 127 } else if ctx.GlobalBool(utils.BetanetFlag.Name) { 128 path = filepath.Join(path, "betanet") 129 } else if ctx.GlobalBool(utils.InnerTestnetFlag.Name) { 130 path = filepath.Join(path, "innertestnet") 131 } else if ctx.GlobalBool(utils.InnerDevnetFlag.Name) { 132 path = filepath.Join(path, "innerdevnet") 133 } 134 } 135 endpoint = fmt.Sprintf("%s/platon.ipc", path) 136 } 137 client, err := dialRPC(endpoint) 138 if err != nil { 139 utils.Fatalf("Unable to attach to remote platon: %v", err) 140 } 141 config := console.Config{ 142 DataDir: utils.MakeDataDir(ctx), 143 DocRoot: ctx.GlobalString(utils.JSpathFlag.Name), 144 Client: client, 145 Preload: utils.MakeConsolePreloads(ctx), 146 } 147 148 console, err := console.New(config) 149 if err != nil { 150 utils.Fatalf("Failed to start the JavaScript console: %v", err) 151 } 152 defer console.Stop(false) 153 154 if script := ctx.GlobalString(utils.ExecFlag.Name); script != "" { 155 console.Evaluate(script) 156 return nil 157 } 158 159 // Otherwise print the welcome screen and enter interactive mode 160 console.Welcome() 161 console.Interactive() 162 163 return nil 164 } 165 166 // dialRPC returns a RPC client which connects to the given endpoint. 167 // The check for empty endpoint implements the defaulting logic 168 // for "platon attach" and "platon monitor" with no argument. 169 func dialRPC(endpoint string) (*rpc.Client, error) { 170 if endpoint == "" { 171 endpoint = node.DefaultIPCEndpoint(clientIdentifier) 172 } else if strings.HasPrefix(endpoint, "rpc:") || strings.HasPrefix(endpoint, "ipc:") { 173 // Backwards compatibility with platon < 1.5 which required 174 // these prefixes. 175 endpoint = endpoint[4:] 176 } 177 return rpc.Dial(endpoint) 178 } 179 180 // ephemeralConsole starts a new platon node, attaches an ephemeral JavaScript 181 // console to it, executes each of the files specified as arguments and tears 182 // everything down. 183 func ephemeralConsole(ctx *cli.Context) error { 184 // Create and start the node based on the CLI flags 185 node := makeFullNode(ctx) 186 startNode(ctx, node) 187 defer node.Stop() 188 189 // Attach to the newly started node and start the JavaScript console 190 client, err := node.Attach() 191 if err != nil { 192 utils.Fatalf("Failed to attach to the inproc platon: %v", err) 193 } 194 config := console.Config{ 195 DataDir: utils.MakeDataDir(ctx), 196 DocRoot: ctx.GlobalString(utils.JSpathFlag.Name), 197 Client: client, 198 Preload: utils.MakeConsolePreloads(ctx), 199 } 200 201 console, err := console.New(config) 202 if err != nil { 203 utils.Fatalf("Failed to start the JavaScript console: %v", err) 204 } 205 defer console.Stop(false) 206 207 // Evaluate each of the specified JavaScript files 208 for _, file := range ctx.Args() { 209 if err = console.Execute(file); err != nil { 210 utils.Fatalf("Failed to execute %s: %v", file, err) 211 } 212 } 213 // Wait for pending callbacks, but stop for Ctrl-C. 214 abort := make(chan os.Signal, 1) 215 signal.Notify(abort, syscall.SIGINT, syscall.SIGTERM) 216 217 go func() { 218 <-abort 219 os.Exit(0) 220 }() 221 console.Stop(true) 222 223 return nil 224 }