aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorzelig <viktor.tron@gmail.com>2015-03-15 14:31:40 +0800
committerzelig <viktor.tron@gmail.com>2015-03-15 14:31:40 +0800
commit7279a485c24de3f0aaf839e1884151322a97dbf7 (patch)
tree37080072b05021f76850a6c93fb03a46657149f3
parent16ecb1e2eaf5c7a17a29a35d33a02905fd45fe02 (diff)
downloadgo-tangerine-7279a485c24de3f0aaf839e1884151322a97dbf7.tar.gz
go-tangerine-7279a485c24de3f0aaf839e1884151322a97dbf7.tar.zst
go-tangerine-7279a485c24de3f0aaf839e1884151322a97dbf7.zip
CLI:
- js subcommand for vm - console for Frontier console interactive REPL - jspath in cli - integrate jeth apiBindings
-rw-r--r--cmd/ethereum/js.go167
-rw-r--r--cmd/ethereum/main.go50
-rw-r--r--cmd/utils/flags.go5
3 files changed, 92 insertions, 130 deletions
diff --git a/cmd/ethereum/js.go b/cmd/ethereum/js.go
index 3b98b588e..361aaf7ea 100644
--- a/cmd/ethereum/js.go
+++ b/cmd/ethereum/js.go
@@ -20,18 +20,16 @@ package main
import (
"bufio"
"fmt"
- "io/ioutil"
"os"
"path"
"strings"
+ "github.com/ethereum/go-ethereum/cmd/utils"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/eth"
- "github.com/ethereum/go-ethereum/ethutil"
- "github.com/ethereum/go-ethereum/javascript"
- "github.com/ethereum/go-ethereum/state"
+ re "github.com/ethereum/go-ethereum/jsre"
+ "github.com/ethereum/go-ethereum/rpc"
"github.com/ethereum/go-ethereum/xeth"
- "github.com/obscuren/otto"
"github.com/peterh/liner"
)
@@ -59,7 +57,7 @@ func (r dumbterm) PasswordPrompt(p string) (string, error) {
func (r dumbterm) AppendHistory(string) {}
type jsre struct {
- re *javascript.JSRE
+ re *re.JSRE
ethereum *eth.Ethereum
xeth *xeth.XEth
ps1 string
@@ -68,11 +66,11 @@ type jsre struct {
prompter
}
-func newJSRE(ethereum *eth.Ethereum) *jsre {
+func newJSRE(ethereum *eth.Ethereum, libPath string) *jsre {
js := &jsre{ethereum: ethereum, ps1: "> "}
js.xeth = xeth.New(ethereum, js)
- js.re = javascript.NewJSRE(js.xeth)
- js.initStdFuncs()
+ js.re = re.New(libPath)
+ js.apiBindings()
if !liner.TerminalSupported() {
js.prompter = dumbterm{bufio.NewReader(os.Stdin)}
@@ -89,6 +87,49 @@ func newJSRE(ethereum *eth.Ethereum) *jsre {
return js
}
+func (js *jsre) apiBindings() {
+
+ ethApi := rpc.NewEthereumApi(js.xeth, js.ethereum.DataDir)
+ js.re.Bind("jeth", rpc.NewJeth(ethApi, js.re.ToVal))
+
+ _, err := js.re.Eval(re.BigNumber_JS)
+
+ if err != nil {
+ utils.Fatalf("Error loading bignumber.js: %v", err)
+ }
+
+ // we need to declare a dummy setTimeout. Otto does not support it
+ _, err = js.re.Eval("setTimeout = function(cb, delay) {};")
+ if err != nil {
+ utils.Fatalf("Error defining setTimeout: %v", err)
+ }
+
+ _, err = js.re.Eval(re.Ethereum_JS)
+ if err != nil {
+ utils.Fatalf("Error loading ethereum.js: %v", err)
+ }
+
+ _, err = js.re.Eval("var web3 = require('web3');")
+ if err != nil {
+ utils.Fatalf("Error requiring web3: %v", err)
+ }
+
+ _, err = js.re.Eval("web3.setProvider(jeth)")
+ if err != nil {
+ utils.Fatalf("Error setting web3 provider: %v", err)
+ }
+ _, err = js.re.Eval(`
+ var eth = web3.eth;
+ var shh = web3.shh;
+ var db = web3.db;
+ var net = web3.net;
+ `)
+ if err != nil {
+ utils.Fatalf("Error setting namespaces: %v", err)
+ }
+
+}
+
func (self *jsre) ConfirmTransaction(tx *types.Transaction) bool {
p := fmt.Sprintf("Confirm Transaction %v\n[y/n] ", tx)
answer, _ := self.Prompt(p)
@@ -111,15 +152,7 @@ func (self *jsre) UnlockAccount(addr []byte) bool {
}
func (self *jsre) exec(filename string) error {
- file, err := os.Open(filename)
- if err != nil {
- return err
- }
- content, err := ioutil.ReadAll(file)
- if err != nil {
- return err
- }
- if _, err := self.re.Run(string(content)); err != nil {
+ if err := self.re.Exec(filename); err != nil {
return fmt.Errorf("Javascript Error: %v", err)
}
return nil
@@ -193,102 +226,8 @@ func (self *jsre) setIndent() {
}
func (self *jsre) printValue(v interface{}) {
- method, _ := self.re.Vm.Get("prettyPrint")
- v, err := self.re.Vm.ToValue(v)
+ val, err := self.re.PrettyPrint(v)
if err == nil {
- val, err := method.Call(method, v)
- if err == nil {
- fmt.Printf("%v", val)
- }
- }
-}
-
-func (self *jsre) initStdFuncs() {
- t, _ := self.re.Vm.Get("eth")
- eth := t.Object()
- eth.Set("connect", self.connect)
- eth.Set("stopMining", self.stopMining)
- eth.Set("startMining", self.startMining)
- eth.Set("dump", self.dump)
- eth.Set("export", self.export)
-}
-
-/*
- * The following methods are natively implemented javascript functions.
- */
-
-func (self *jsre) dump(call otto.FunctionCall) otto.Value {
- var block *types.Block
-
- if len(call.ArgumentList) > 0 {
- if call.Argument(0).IsNumber() {
- num, _ := call.Argument(0).ToInteger()
- block = self.ethereum.ChainManager().GetBlockByNumber(uint64(num))
- } else if call.Argument(0).IsString() {
- hash, _ := call.Argument(0).ToString()
- block = self.ethereum.ChainManager().GetBlock(ethutil.Hex2Bytes(hash))
- } else {
- fmt.Println("invalid argument for dump. Either hex string or number")
- }
-
- if block == nil {
- fmt.Println("block not found")
-
- return otto.UndefinedValue()
- }
-
- } else {
- block = self.ethereum.ChainManager().CurrentBlock()
- }
-
- statedb := state.New(block.Root(), self.ethereum.StateDb())
-
- v, _ := self.re.Vm.ToValue(statedb.RawDump())
-
- return v
-}
-
-func (self *jsre) stopMining(call otto.FunctionCall) otto.Value {
- self.ethereum.StopMining()
- return otto.TrueValue()
-}
-
-func (self *jsre) startMining(call otto.FunctionCall) otto.Value {
- if err := self.ethereum.StartMining(); err != nil {
- return otto.FalseValue()
- }
- return otto.TrueValue()
-}
-
-func (self *jsre) connect(call otto.FunctionCall) otto.Value {
- nodeURL, err := call.Argument(0).ToString()
- if err != nil {
- return otto.FalseValue()
- }
- if err := self.ethereum.SuggestPeer(nodeURL); err != nil {
- return otto.FalseValue()
- }
- return otto.TrueValue()
-}
-
-func (self *jsre) export(call otto.FunctionCall) otto.Value {
- if len(call.ArgumentList) == 0 {
- fmt.Println("err: require file name")
- return otto.FalseValue()
- }
-
- fn, err := call.Argument(0).ToString()
- if err != nil {
- fmt.Println(err)
- return otto.FalseValue()
- }
-
- data := self.ethereum.ChainManager().Export()
-
- if err := ethutil.WriteFile(fn, data); err != nil {
- fmt.Println(err)
- return otto.FalseValue()
+ fmt.Printf("%v", val)
}
-
- return otto.TrueValue()
}
diff --git a/cmd/ethereum/main.go b/cmd/ethereum/main.go
index 53746627a..0dae5b79b 100644
--- a/cmd/ethereum/main.go
+++ b/cmd/ethereum/main.go
@@ -89,16 +89,20 @@ Use "ethereum dump 0" to dump the genesis block.
`,
},
{
- Action: runjs,
+ Action: console,
+ Name: "console",
+ Usage: `Ethereum Frontier Console: interactive JavaScript environment`,
+ Description: `
+Frontier Console is an interactive shell for the Ethereum Frontier JavaScript runtime environment which exposes a node admin interface as well as the DAPP JavaScript API.
+See https://github.com/ethereum/go-ethereum/wiki/Frontier-Console
+`,
+ },
+ {
+ Action: execJSFiles,
Name: "js",
- Usage: `interactive JavaScript console`,
+ Usage: `executes the given JavaScript files in the Ethereum Frontier JavaScript VM`,
Description: `
-In the console, you can use the eth object to interact
-with the running ethereum stack. The API does not match
-ethereum.js.
-
-A JavaScript file can be provided as the argument. The
-runtime will execute the file and exit.
+The Ethereum Frontier JavaScript VM exposes a node admin interface as well as the DAPP JavaScript API. See https://github.com/ethereum/go-ethereum/wiki/Frontier-Console
`,
},
{
@@ -116,6 +120,7 @@ runtime will execute the file and exit.
utils.UnlockedAccountFlag,
utils.BootnodesFlag,
utils.DataDirFlag,
+ utils.JSpathFlag,
utils.ListenPortFlag,
utils.LogFileFlag,
utils.LogFormatFlag,
@@ -131,6 +136,7 @@ runtime will execute the file and exit.
utils.RPCPortFlag,
utils.UnencryptedKeysFlag,
utils.VMDebugFlag,
+
//utils.VMTypeFlag,
}
@@ -168,7 +174,7 @@ func run(ctx *cli.Context) {
ethereum.WaitForShutdown()
}
-func runjs(ctx *cli.Context) {
+func console(ctx *cli.Context) {
cfg := utils.MakeEthConfig(ClientIdentifier, Version, ctx)
ethereum, err := eth.New(cfg)
if err != nil {
@@ -176,14 +182,26 @@ func runjs(ctx *cli.Context) {
}
startEth(ctx, ethereum)
- repl := newJSRE(ethereum)
- if len(ctx.Args()) == 0 {
- repl.interactive()
- } else {
- for _, file := range ctx.Args() {
- repl.exec(file)
- }
+ repl := newJSRE(ethereum, ctx.String(utils.JSpathFlag.Name))
+ repl.interactive()
+
+ ethereum.Stop()
+ ethereum.WaitForShutdown()
+}
+
+func execJSFiles(ctx *cli.Context) {
+ cfg := utils.MakeEthConfig(ClientIdentifier, Version, ctx)
+ ethereum, err := eth.New(cfg)
+ if err != nil {
+ utils.Fatalf("%v", err)
}
+
+ startEth(ctx, ethereum)
+ repl := newJSRE(ethereum, ctx.String(utils.JSpathFlag.Name))
+ for _, file := range ctx.Args() {
+ repl.exec(file)
+ }
+
ethereum.Stop()
ethereum.WaitForShutdown()
}
diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go
index 6bcd7e811..563654441 100644
--- a/cmd/utils/flags.go
+++ b/cmd/utils/flags.go
@@ -163,6 +163,11 @@ var (
Usage: "Port mapping mechanism (any|none|upnp|pmp|extip:<IP>)",
Value: "any",
}
+ JSpathFlag = cli.StringFlag{
+ Name: "jspath",
+ Usage: "JS library path to be used with console and js subcommands",
+ Value: ".",
+ }
)
func GetNAT(ctx *cli.Context) nat.Interface {