From de1dfae7170a946d255a9b4932e08f887d48947c Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 20 May 2014 17:49:12 +0200 Subject: [PATCH 1/9] Forked version of otto so we can support lowerCased methods --- ethereum/javascript_runtime.go | 2 +- ethereum/repl.go | 2 +- ethereum/repl_darwin.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ethereum/javascript_runtime.go b/ethereum/javascript_runtime.go index b06fb9460..cc8fe370f 100644 --- a/ethereum/javascript_runtime.go +++ b/ethereum/javascript_runtime.go @@ -6,7 +6,7 @@ import ( "github.com/ethereum/eth-go/ethchain" "github.com/ethereum/eth-go/ethpub" "github.com/ethereum/eth-go/ethutil" - "github.com/robertkrimen/otto" + "github.com/obscuren/otto" ) type JSRE struct { diff --git a/ethereum/repl.go b/ethereum/repl.go index c0b63c0a5..29d38afef 100644 --- a/ethereum/repl.go +++ b/ethereum/repl.go @@ -4,7 +4,7 @@ import ( "fmt" "github.com/ethereum/eth-go" "github.com/ethereum/eth-go/ethpub" - "github.com/robertkrimen/otto" + "github.com/obscuren/otto" ) type Repl interface { diff --git a/ethereum/repl_darwin.go b/ethereum/repl_darwin.go index 87da3df1d..cf6e24e18 100644 --- a/ethereum/repl_darwin.go +++ b/ethereum/repl_darwin.go @@ -8,7 +8,7 @@ package main import "C" import ( - "github.com/robertkrimen/otto" + "github.com/obscuren/otto" "strings" "unsafe" ) From 563c035eb57a0507979a84f3dd22411be2a4cad1 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 20 May 2014 19:28:48 +0200 Subject: [PATCH 2/9] Refactored some of the functions --- ethereum/javascript_runtime.go | 93 ++++++++++++++++++++++++++++------ ethereum/repl_darwin.go | 8 +-- 2 files changed, 83 insertions(+), 18 deletions(-) diff --git a/ethereum/javascript_runtime.go b/ethereum/javascript_runtime.go index cc8fe370f..76ced3f3d 100644 --- a/ethereum/javascript_runtime.go +++ b/ethereum/javascript_runtime.go @@ -7,6 +7,9 @@ import ( "github.com/ethereum/eth-go/ethpub" "github.com/ethereum/eth-go/ethutil" "github.com/obscuren/otto" + "io/ioutil" + "os" + "path/filepath" ) type JSRE struct { @@ -53,6 +56,22 @@ func (self *JSRE) Run(code string) (otto.Value, error) { return self.vm.Run(code) } +func (self *JSRE) Require(file string) error { + if len(filepath.Ext(file)) == 0 { + file += ".js" + } + + fh, err := os.Open(file) + if err != nil { + return err + } + + content, _ := ioutil.ReadAll(fh) + self.Run("exports = {};(function() {" + string(content) + "})();") + + return nil +} + func (self *JSRE) Stop() { // Kill the main loop self.quitChan <- true @@ -82,7 +101,10 @@ out: cb.Call(cb, val) } } else if storageObject, ok := object.Resource.(*ethchain.StorageState); ok { - fmt.Println(storageObject) + for _, cb := range self.objectCb[ethutil.Hex(storageObject.Address)+ethutil.Hex(storageObject.StateAddress)] { + val, _ := self.vm.ToValue(ethpub.NewPStorageState(storageObject)) + cb.Call(cb, val) + } } } } @@ -91,24 +113,65 @@ out: func (self *JSRE) initStdFuncs() { t, _ := self.vm.Get("eth") eth := t.Object() - eth.Set("watch", func(call otto.FunctionCall) otto.Value { - addr, _ := call.Argument(0).ToString() - cb := call.Argument(1) + eth.Set("watch", self.watch) + eth.Set("addPeer", self.addPeer) + self.Set("require", self.require) +} +/* + * The following methods are natively implemented javascript functions + */ + +// eth.watch +func (self JSRE) watch(call otto.FunctionCall) otto.Value { + addr, _ := call.Argument(0).ToString() + var storageAddr string + var cb otto.Value + var storageCallback bool + if len(call.ArgumentList) > 2 { + storageCallback = true + storageAddr, _ = call.Argument(1).ToString() + cb = call.Argument(2) + } else { + cb = call.Argument(1) + } + + if storageCallback { + self.objectCb[addr+storageAddr] = append(self.objectCb[addr+storageAddr], cb) + + event := "storage:" + string(ethutil.FromHex(addr)) + ":" + string(ethutil.FromHex(storageAddr)) + self.ethereum.Reactor().Subscribe(event, self.changeChan) + } else { self.objectCb[addr] = append(self.objectCb[addr], cb) event := "object:" + string(ethutil.FromHex(addr)) self.ethereum.Reactor().Subscribe(event, self.changeChan) + } - return otto.UndefinedValue() - }) - eth.Set("addPeer", func(call otto.FunctionCall) otto.Value { - host, err := call.Argument(0).ToString() - if err != nil { - return otto.FalseValue() - } - self.ethereum.ConnectToPeer(host) - - return otto.TrueValue() - }) + return otto.UndefinedValue() +} + +func (self *JSRE) addPeer(call otto.FunctionCall) otto.Value { + host, err := call.Argument(0).ToString() + if err != nil { + return otto.FalseValue() + } + self.ethereum.ConnectToPeer(host) + + return otto.TrueValue() +} + +func (self *JSRE) require(call otto.FunctionCall) otto.Value { + file, err := call.Argument(0).ToString() + if err != nil { + return otto.UndefinedValue() + } + if err := self.Require(file); err != nil { + fmt.Println("err:", err) + return otto.UndefinedValue() + } + + t, _ := self.vm.Get("exports") + + return t } diff --git a/ethereum/repl_darwin.go b/ethereum/repl_darwin.go index cf6e24e18..1b98c2150 100644 --- a/ethereum/repl_darwin.go +++ b/ethereum/repl_darwin.go @@ -8,7 +8,6 @@ package main import "C" import ( - "github.com/obscuren/otto" "strings" "unsafe" ) @@ -87,7 +86,10 @@ L: } } -func (self *JSRepl) PrintValue(value otto.Value) { +func (self *JSRepl) PrintValue(v interface{}) { method, _ := self.re.vm.Get("prettyPrint") - method.Call(method, value) + v, err := self.re.vm.ToValue(v) + if err == nil { + method.Call(method, v) + } } From f4551a7e9f90dd10b22ccfcdaf59d1a6a35283cf Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 20 May 2014 22:12:22 +0200 Subject: [PATCH 3/9] Changed flag parsing --- ethereum/config.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/ethereum/config.go b/ethereum/config.go index 97e8687d8..f25f2fb66 100644 --- a/ethereum/config.go +++ b/ethereum/config.go @@ -2,6 +2,8 @@ package main import ( "flag" + "fmt" + "os" ) var StartMining bool @@ -23,6 +25,11 @@ var StartJsConsole bool var InputFile string func Init() { + flag.Usage = func() { + fmt.Fprintf(os.Stderr, "%s [options] [filename]:\n", os.Args[0]) + flag.PrintDefaults() + } + flag.BoolVar(&StartMining, "m", false, "start dagger mining") flag.BoolVar(&ShowGenesis, "g", false, "prints genesis header and exits") flag.BoolVar(&StartRpc, "r", false, "start rpc server") @@ -38,7 +45,9 @@ func Init() { flag.StringVar(&ImportKey, "import", "", "imports the given private key (hex)") flag.IntVar(&MaxPeer, "x", 10, "maximum desired peers") flag.BoolVar(&StartJsConsole, "js", false, "exp") - flag.StringVar(&InputFile, "e", "", "Run javascript file") + //flag.StringVar(&InputFile, "e", "", "Run javascript file") flag.Parse() + + InputFile = flag.Arg(0) } From 93e12250c702521807247a66d74cc0792370d83b Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 20 May 2014 22:12:42 +0200 Subject: [PATCH 4/9] Switch variables as intended --- ethereum/javascript_runtime.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ethereum/javascript_runtime.go b/ethereum/javascript_runtime.go index 76ced3f3d..fa01c7005 100644 --- a/ethereum/javascript_runtime.go +++ b/ethereum/javascript_runtime.go @@ -101,7 +101,7 @@ out: cb.Call(cb, val) } } else if storageObject, ok := object.Resource.(*ethchain.StorageState); ok { - for _, cb := range self.objectCb[ethutil.Hex(storageObject.Address)+ethutil.Hex(storageObject.StateAddress)] { + for _, cb := range self.objectCb[ethutil.Hex(storageObject.StateAddress)+ethutil.Hex(storageObject.Address)] { val, _ := self.vm.ToValue(ethpub.NewPStorageState(storageObject)) cb.Call(cb, val) } @@ -115,7 +115,7 @@ func (self *JSRE) initStdFuncs() { eth := t.Object() eth.Set("watch", self.watch) eth.Set("addPeer", self.addPeer) - self.Set("require", self.require) + eth.Set("require", self.require) } /* From d16d56d39f99aab6022291a28df288736e789985 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 20 May 2014 22:13:39 +0200 Subject: [PATCH 5/9] Updated readme to reflect options --- README.md | 28 ++++++++++------------ ethereal/assets/samplecoin/samplecoin.html | 2 +- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index 3a73f8ac9..30db835f2 100644 --- a/README.md +++ b/README.md @@ -26,28 +26,24 @@ General command line options ==================== ``` --c Launch the developer console (node only) +Shared between ethereum and ethereal -m Start mining blocks -genaddr Generates a new address and private key (destructive action) --p Port on which the server will accept incomming connections (= 30303) --upnp Enable UPnP (= false) --x Desired amount of peers (= 5) --h This help +-p Port on which the server will accept incomming connections +-upnp Enable UPnP +-x Desired amount of peers -r Start JSON RPC --dir Data directory used to store configs and databases (=".ethereum") --import Import a private key (hex) -``` +-dir Data directory used to store configs and databases +-import Import a private key +-h This -Developer console commands -========================== +Ethereum only +ethereum [options] [filename] +-js Start the JavaScript REPL +Etheral only +-asset_path absolute path to GUI assets directory ``` -addp : Connect to the given host -tx Send Wei to the specified -contract Creates a new contract and launches the editor -``` - -See the "help" command for *developer* options. Contribution ============ diff --git a/ethereal/assets/samplecoin/samplecoin.html b/ethereal/assets/samplecoin/samplecoin.html index d47c6323c..3892141cd 100644 --- a/ethereal/assets/samplecoin/samplecoin.html +++ b/ethereal/assets/samplecoin/samplecoin.html @@ -9,7 +9,7 @@