github.com/klaytn/klaytn@v1.10.2/cmd/utils/nodecmd/consolecmd.go (about) 1 // Modifications Copyright 2018 The klaytn Authors 2 // Copyright 2016 The go-ethereum Authors 3 // This file is part of go-ethereum. 4 // 5 // go-ethereum is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // (at your option) any later version. 9 // 10 // go-ethereum is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with go-ethereum. If not, see <http://www.gnu.org/licenses/>. 17 // 18 // This file is derived from cmd/geth/consolecmd.go (2018/06/04). 19 // Modified and improved for the klaytn development. 20 21 package nodecmd 22 23 import ( 24 "fmt" 25 "path/filepath" 26 "strings" 27 28 "github.com/klaytn/klaytn/cmd/utils" 29 "github.com/klaytn/klaytn/console" 30 "github.com/klaytn/klaytn/log" 31 "github.com/klaytn/klaytn/networks/rpc" 32 "github.com/klaytn/klaytn/node" 33 "gopkg.in/urfave/cli.v1" 34 "gopkg.in/urfave/cli.v1/altsrc" 35 ) 36 37 var ( 38 ConsoleFlags = []cli.Flag{ 39 altsrc.NewStringFlag(utils.JSpathFlag), 40 altsrc.NewStringFlag(utils.ExecFlag), 41 altsrc.NewStringFlag(utils.PreloadJSFlag), 42 } 43 44 AttachCommand = cli.Command{ 45 Action: utils.MigrateFlags(remoteConsole), 46 Name: "attach", 47 Usage: "Start an interactive JavaScript environment (connect to node)", 48 ArgsUsage: "[endpoint]", 49 Flags: append(ConsoleFlags, utils.DataDirFlag), 50 Category: "CONSOLE COMMANDS", 51 Description: ` 52 The Klaytn 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://github.com/ethereum/go-ethereum/wiki/JavaScript-Console. 55 This command allows to open a console on a running Klaytn node.`, 56 } 57 ) 58 59 // GetConsoleCommand returns cli.Command `console` whose flags are initialized with nodeFlags, rpcFlags, and ConsoleFlags. 60 func GetConsoleCommand(nodeFlags, rpcFlags []cli.Flag) cli.Command { 61 return cli.Command{ 62 Action: utils.MigrateFlags(localConsole), 63 Name: "console", 64 Usage: "Start an interactive JavaScript environment", 65 Flags: append(append(nodeFlags, rpcFlags...), ConsoleFlags...), 66 Category: "CONSOLE COMMANDS", 67 Description: ` 68 The Klaytn console is an interactive shell for the JavaScript runtime environment 69 which exposes a node admin interface as well as the Ðapp JavaScript API. 70 See https://github.com/ethereum/go-ethereum/wiki/JavaScript-Console.`, 71 } 72 } 73 74 // localConsole starts a new Klaytn node, attaching a JavaScript console to it at the 75 // same time. 76 func localConsole(ctx *cli.Context) error { 77 // Create and start the node based on the CLI flags 78 node := MakeFullNode(ctx) 79 startNode(ctx, node) 80 defer node.Stop() 81 82 // Attach to the newly started node and start the JavaScript console 83 client, err := node.Attach() 84 if err != nil { 85 log.Fatalf("Failed to attach to the inproc node: %v", err) 86 } 87 config := console.Config{ 88 DataDir: utils.MakeDataDir(ctx), 89 DocRoot: ctx.GlobalString(utils.JSpathFlag.Name), 90 Client: client, 91 Preload: utils.MakeConsolePreloads(ctx), 92 } 93 94 console, err := console.New(config) 95 if err != nil { 96 log.Fatalf("Failed to start the JavaScript console: %v", err) 97 } 98 defer console.Stop(false) 99 100 // If only a short execution was requested, evaluate and return 101 if script := ctx.GlobalString(utils.ExecFlag.Name); script != "" { 102 console.Evaluate(script) 103 return nil 104 } 105 // Otherwise print the welcome screen and enter interactive mode 106 console.Welcome() 107 console.Interactive() 108 109 return nil 110 } 111 112 // remoteConsole will connect to a remote node instance, attaching a JavaScript 113 // console to it. 114 func remoteConsole(ctx *cli.Context) error { 115 // Attach to a remotely running node instance and start the JavaScript console 116 endpoint := ctx.Args().First() 117 if endpoint == "" { 118 path := node.DefaultDataDir() 119 if ctx.GlobalIsSet(utils.DataDirFlag.Name) { 120 path = ctx.GlobalString(utils.DataDirFlag.Name) 121 } 122 if path != "" { 123 if ctx.GlobalBool(utils.BaobabFlag.Name) { 124 path = filepath.Join(path, "baobab") 125 } 126 } 127 endpoint = fmt.Sprintf("%s/klay.ipc", path) 128 } 129 client, err := dialRPC(endpoint) 130 if err != nil { 131 log.Fatalf("Unable to attach to remote node: %v", err) 132 } 133 config := console.Config{ 134 DataDir: utils.MakeDataDir(ctx), 135 DocRoot: ctx.GlobalString(utils.JSpathFlag.Name), 136 Client: client, 137 Preload: utils.MakeConsolePreloads(ctx), 138 } 139 140 console, err := console.New(config) 141 if err != nil { 142 log.Fatalf("Failed to start the JavaScript console: %v", err) 143 } 144 defer console.Stop(false) 145 146 if script := ctx.GlobalString(utils.ExecFlag.Name); script != "" { 147 console.Evaluate(script) 148 return nil 149 } 150 151 // Otherwise print the welcome screen and enter interactive mode 152 console.Welcome() 153 console.Interactive() 154 155 return nil 156 } 157 158 // dialRPC returns a RPC client which connects to the given endpoint. 159 // The check for empty endpoint implements the defaulting logic 160 // for "ken attach" and "ken monitor" with no argument. 161 func dialRPC(endpoint string) (*rpc.Client, error) { 162 if endpoint == "" { 163 endpoint = node.DefaultIPCEndpoint(utils.ClientIdentifier) 164 } else if strings.HasPrefix(endpoint, "rpc:") || strings.HasPrefix(endpoint, "ipc:") { 165 // TODO-Klaytn-RemoveLater: The below backward compatibility is not related to Klaytn. 166 // Backwards compatibility with klaytn < 1.5 which required 167 // these prefixes. 168 endpoint = endpoint[4:] 169 } 170 return rpc.Dial(endpoint) 171 }