consolecmd.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  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. package main
  17. import (
  18. "os"
  19. "os/signal"
  20. "github.com/codegangsta/cli"
  21. "github.com/ethereum/go-ethereum/cmd/utils"
  22. "github.com/ethereum/go-ethereum/console"
  23. )
  24. var (
  25. consoleCommand = cli.Command{
  26. Action: localConsole,
  27. Name: "console",
  28. Usage: `Geth Console: interactive JavaScript environment`,
  29. Description: `
  30. The Geth console is an interactive shell for the JavaScript runtime environment
  31. which exposes a node admin interface as well as the Ðapp JavaScript API.
  32. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Console
  33. `,
  34. }
  35. attachCommand = cli.Command{
  36. Action: remoteConsole,
  37. Name: "attach",
  38. Usage: `Geth Console: interactive JavaScript environment (connect to node)`,
  39. Description: `
  40. The Geth console is an interactive shell for the JavaScript runtime environment
  41. which exposes a node admin interface as well as the Ðapp JavaScript API.
  42. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Console.
  43. This command allows to open a console on a running geth node.
  44. `,
  45. }
  46. javascriptCommand = cli.Command{
  47. Action: ephemeralConsole,
  48. Name: "js",
  49. Usage: `executes the given JavaScript files in the Geth JavaScript VM`,
  50. Description: `
  51. The JavaScript VM exposes a node admin interface as well as the Ðapp
  52. JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Javascipt-Console
  53. `,
  54. }
  55. )
  56. // localConsole starts a new geth node, attaching a JavaScript console to it at the
  57. // same time.
  58. func localConsole(ctx *cli.Context) {
  59. // Create and start the node based on the CLI flags
  60. node := utils.MakeSystemNode(clientIdentifier, verString, relConfig, makeDefaultExtra(), ctx)
  61. startNode(ctx, node)
  62. defer node.Stop()
  63. // Attach to the newly started node and start the JavaScript console
  64. client, err := node.Attach()
  65. if err != nil {
  66. utils.Fatalf("Failed to attach to the inproc geth: %v", err)
  67. }
  68. config := console.Config{
  69. DataDir: node.DataDir(),
  70. DocRoot: ctx.GlobalString(utils.JSpathFlag.Name),
  71. Client: client,
  72. Preload: utils.MakeConsolePreloads(ctx),
  73. }
  74. console, err := console.New(config)
  75. if err != nil {
  76. utils.Fatalf("Failed to start the JavaScript console: %v", err)
  77. }
  78. defer console.Stop(false)
  79. // If only a short execution was requested, evaluate and return
  80. if script := ctx.GlobalString(utils.ExecFlag.Name); script != "" {
  81. console.Evaluate(script)
  82. return
  83. }
  84. // Otherwise print the welcome screen and enter interactive mode
  85. console.Welcome()
  86. console.Interactive()
  87. }
  88. // remoteConsole will connect to a remote geth instance, attaching a JavaScript
  89. // console to it.
  90. func remoteConsole(ctx *cli.Context) {
  91. // Attach to a remotely running geth instance and start the JavaScript console
  92. client, err := utils.NewRemoteRPCClient(ctx)
  93. if err != nil {
  94. utils.Fatalf("Unable to attach to remote geth: %v", err)
  95. }
  96. config := console.Config{
  97. DataDir: utils.MustMakeDataDir(ctx),
  98. DocRoot: ctx.GlobalString(utils.JSpathFlag.Name),
  99. Client: client,
  100. Preload: utils.MakeConsolePreloads(ctx),
  101. }
  102. console, err := console.New(config)
  103. if err != nil {
  104. utils.Fatalf("Failed to start the JavaScript console: %v", err)
  105. }
  106. defer console.Stop(false)
  107. // If only a short execution was requested, evaluate and return
  108. if script := ctx.GlobalString(utils.ExecFlag.Name); script != "" {
  109. console.Evaluate(script)
  110. return
  111. }
  112. // Otherwise print the welcome screen and enter interactive mode
  113. console.Welcome()
  114. console.Interactive()
  115. }
  116. // ephemeralConsole starts a new geth node, attaches an ephemeral JavaScript
  117. // console to it, and each of the files specified as arguments and tears the
  118. // everything down.
  119. func ephemeralConsole(ctx *cli.Context) {
  120. // Create and start the node based on the CLI flags
  121. node := utils.MakeSystemNode(clientIdentifier, verString, relConfig, makeDefaultExtra(), ctx)
  122. startNode(ctx, node)
  123. defer node.Stop()
  124. // Attach to the newly started node and start the JavaScript console
  125. client, err := node.Attach()
  126. if err != nil {
  127. utils.Fatalf("Failed to attach to the inproc geth: %v", err)
  128. }
  129. config := console.Config{
  130. DataDir: node.DataDir(),
  131. DocRoot: ctx.GlobalString(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. // Evaluate each of the specified JavaScript files
  141. for _, file := range ctx.Args() {
  142. if err = console.Execute(file); err != nil {
  143. utils.Fatalf("Failed to execute %s: %v", file, err)
  144. }
  145. }
  146. // Wait for pending callbacks, but stop for Ctrl-C.
  147. abort := make(chan os.Signal, 1)
  148. signal.Notify(abort, os.Interrupt)
  149. go func() {
  150. <-abort
  151. os.Exit(0)
  152. }()
  153. console.Stop(true)
  154. }