admin.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. package main
  2. import (
  3. "fmt"
  4. "net"
  5. "net/http"
  6. "os"
  7. "time"
  8. "github.com/ethereum/go-ethereum/cmd/utils"
  9. "github.com/ethereum/go-ethereum/common"
  10. "github.com/ethereum/go-ethereum/core/types"
  11. "github.com/ethereum/go-ethereum/rlp"
  12. "github.com/ethereum/go-ethereum/rpc"
  13. "github.com/ethereum/go-ethereum/state"
  14. "github.com/ethereum/go-ethereum/xeth"
  15. "github.com/obscuren/otto"
  16. )
  17. /*
  18. node admin bindings
  19. */
  20. func (js *jsre) adminBindings() {
  21. js.re.Set("admin", struct{}{})
  22. t, _ := js.re.Get("admin")
  23. admin := t.Object()
  24. admin.Set("suggestPeer", js.suggestPeer)
  25. admin.Set("startRPC", js.startRPC)
  26. admin.Set("startMining", js.startMining)
  27. admin.Set("stopMining", js.stopMining)
  28. admin.Set("nodeInfo", js.nodeInfo)
  29. admin.Set("peers", js.peers)
  30. admin.Set("newAccount", js.newAccount)
  31. admin.Set("unlock", js.unlock)
  32. admin.Set("import", js.importChain)
  33. admin.Set("export", js.exportChain)
  34. admin.Set("dumpBlock", js.dumpBlock)
  35. }
  36. func (js *jsre) startMining(call otto.FunctionCall) otto.Value {
  37. _, err := call.Argument(0).ToInteger()
  38. if err != nil {
  39. fmt.Println(err)
  40. return otto.FalseValue()
  41. }
  42. // threads now ignored
  43. err = js.ethereum.StartMining()
  44. if err != nil {
  45. fmt.Println(err)
  46. return otto.FalseValue()
  47. }
  48. return otto.TrueValue()
  49. }
  50. func (js *jsre) stopMining(call otto.FunctionCall) otto.Value {
  51. js.ethereum.StopMining()
  52. return otto.TrueValue()
  53. }
  54. func (js *jsre) startRPC(call otto.FunctionCall) otto.Value {
  55. addr, err := call.Argument(0).ToString()
  56. if err != nil {
  57. fmt.Println(err)
  58. return otto.FalseValue()
  59. }
  60. port, err := call.Argument(1).ToInteger()
  61. if err != nil {
  62. fmt.Println(err)
  63. return otto.FalseValue()
  64. }
  65. dataDir := js.ethereum.DataDir
  66. l, err := net.Listen("tcp", fmt.Sprintf("%s:%d", addr, port))
  67. if err != nil {
  68. fmt.Printf("Can't listen on %s:%d: %v", addr, port, err)
  69. return otto.FalseValue()
  70. }
  71. go http.Serve(l, rpc.JSONRPC(xeth.New(js.ethereum, nil), dataDir))
  72. return otto.TrueValue()
  73. }
  74. func (js *jsre) suggestPeer(call otto.FunctionCall) otto.Value {
  75. nodeURL, err := call.Argument(0).ToString()
  76. if err != nil {
  77. fmt.Println(err)
  78. return otto.FalseValue()
  79. }
  80. err = js.ethereum.SuggestPeer(nodeURL)
  81. if err != nil {
  82. fmt.Println(err)
  83. return otto.FalseValue()
  84. }
  85. return otto.TrueValue()
  86. }
  87. func (js *jsre) unlock(call otto.FunctionCall) otto.Value {
  88. addr, err := call.Argument(0).ToString()
  89. if err != nil {
  90. fmt.Println(err)
  91. return otto.FalseValue()
  92. }
  93. seconds, err := call.Argument(2).ToInteger()
  94. if err != nil {
  95. fmt.Println(err)
  96. return otto.FalseValue()
  97. }
  98. arg := call.Argument(1)
  99. var passphrase string
  100. if arg.IsUndefined() {
  101. fmt.Println("Please enter a passphrase now.")
  102. passphrase, err = readPassword("Passphrase: ", true)
  103. if err != nil {
  104. utils.Fatalf("%v", err)
  105. }
  106. } else {
  107. passphrase, err = arg.ToString()
  108. if err != nil {
  109. fmt.Println(err)
  110. return otto.FalseValue()
  111. }
  112. }
  113. am := js.ethereum.AccountManager()
  114. // err := am.Unlock(common.FromHex(split[0]), split[1])
  115. // if err != nil {
  116. // utils.Fatalf("Unlock account failed '%v'", err)
  117. // }
  118. err = am.TimedUnlock(common.FromHex(addr), passphrase, time.Duration(seconds)*time.Second)
  119. if err != nil {
  120. fmt.Printf("Unlock account failed '%v'\n", err)
  121. return otto.FalseValue()
  122. }
  123. return otto.TrueValue()
  124. }
  125. func (js *jsre) newAccount(call otto.FunctionCall) otto.Value {
  126. arg := call.Argument(0)
  127. var passphrase string
  128. if arg.IsUndefined() {
  129. fmt.Println("The new account will be encrypted with a passphrase.")
  130. fmt.Println("Please enter a passphrase now.")
  131. auth, err := readPassword("Passphrase: ", true)
  132. if err != nil {
  133. utils.Fatalf("%v", err)
  134. }
  135. confirm, err := readPassword("Repeat Passphrase: ", false)
  136. if err != nil {
  137. utils.Fatalf("%v", err)
  138. }
  139. if auth != confirm {
  140. utils.Fatalf("Passphrases did not match.")
  141. }
  142. passphrase = auth
  143. } else {
  144. var err error
  145. passphrase, err = arg.ToString()
  146. if err != nil {
  147. fmt.Println(err)
  148. return otto.FalseValue()
  149. }
  150. }
  151. acct, err := js.ethereum.AccountManager().NewAccount(passphrase)
  152. if err != nil {
  153. fmt.Printf("Could not create the account: %v", err)
  154. return otto.UndefinedValue()
  155. }
  156. return js.re.ToVal(common.Bytes2Hex(acct.Address))
  157. }
  158. func (js *jsre) nodeInfo(call otto.FunctionCall) otto.Value {
  159. return js.re.ToVal(js.ethereum.NodeInfo())
  160. }
  161. func (js *jsre) peers(call otto.FunctionCall) otto.Value {
  162. return js.re.ToVal(js.ethereum.PeersInfo())
  163. }
  164. func (js *jsre) importChain(call otto.FunctionCall) otto.Value {
  165. if len(call.ArgumentList) == 0 {
  166. fmt.Println("err: require file name")
  167. return otto.FalseValue()
  168. }
  169. fn, err := call.Argument(0).ToString()
  170. if err != nil {
  171. fmt.Println(err)
  172. return otto.FalseValue()
  173. }
  174. var fh *os.File
  175. fh, err = os.OpenFile(fn, os.O_RDONLY, os.ModePerm)
  176. if err != nil {
  177. fmt.Println(err)
  178. return otto.FalseValue()
  179. }
  180. defer fh.Close()
  181. var blocks types.Blocks
  182. if err = rlp.Decode(fh, &blocks); err != nil {
  183. fmt.Println(err)
  184. return otto.FalseValue()
  185. }
  186. js.ethereum.ChainManager().Reset()
  187. if err = js.ethereum.ChainManager().InsertChain(blocks); err != nil {
  188. fmt.Println(err)
  189. return otto.FalseValue()
  190. }
  191. return otto.TrueValue()
  192. }
  193. func (js *jsre) exportChain(call otto.FunctionCall) otto.Value {
  194. if len(call.ArgumentList) == 0 {
  195. fmt.Println("err: require file name")
  196. return otto.FalseValue()
  197. }
  198. fn, err := call.Argument(0).ToString()
  199. if err != nil {
  200. fmt.Println(err)
  201. return otto.FalseValue()
  202. }
  203. if err := utils.ExportChain(js.ethereum.ChainManager(), fn); err != nil {
  204. fmt.Println(err)
  205. return otto.FalseValue()
  206. }
  207. return otto.TrueValue()
  208. }
  209. func (js *jsre) dumpBlock(call otto.FunctionCall) otto.Value {
  210. var block *types.Block
  211. if len(call.ArgumentList) > 0 {
  212. if call.Argument(0).IsNumber() {
  213. num, _ := call.Argument(0).ToInteger()
  214. block = js.ethereum.ChainManager().GetBlockByNumber(uint64(num))
  215. } else if call.Argument(0).IsString() {
  216. hash, _ := call.Argument(0).ToString()
  217. block = js.ethereum.ChainManager().GetBlock(common.HexToHash(hash))
  218. } else {
  219. fmt.Println("invalid argument for dump. Either hex string or number")
  220. }
  221. } else {
  222. block = js.ethereum.ChainManager().CurrentBlock()
  223. }
  224. if block == nil {
  225. fmt.Println("block not found")
  226. return otto.UndefinedValue()
  227. }
  228. statedb := state.New(block.Root(), js.ethereum.StateDb())
  229. dump := statedb.RawDump()
  230. return js.re.ToVal(dump)
  231. }