From 7279a485c24de3f0aaf839e1884151322a97dbf7 Mon Sep 17 00:00:00 2001 From: zelig Date: Sun, 15 Mar 2015 13:31:40 +0700 Subject: CLI: - js subcommand for vm - console for Frontier console interactive REPL - jspath in cli - integrate jeth apiBindings --- cmd/ethereum/js.go | 167 +++++++++++++++++------------------------------------ 1 file changed, 53 insertions(+), 114 deletions(-) (limited to 'cmd/ethereum/js.go') 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() } -- cgit v1.2.3