From cbce882f5e35300016055cde81eeccb3ae052671 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 15 May 2014 20:45:19 +0200 Subject: [PATCH 1/3] Basic javascript console --- ethereum/config.go | 2 + ethereum/ethereum.go | 7 ++++ ethereum/javascript_console.go | 76 ++++++++++++++++++++++++++++++++++ 3 files changed, 85 insertions(+) create mode 100644 ethereum/javascript_console.go diff --git a/ethereum/config.go b/ethereum/config.go index 7ca1a9801..4d7ea6310 100644 --- a/ethereum/config.go +++ b/ethereum/config.go @@ -20,6 +20,7 @@ var ExportKey bool var LogFile string var DataDir string var NonInteractive bool +var StartExp bool func Init() { flag.BoolVar(&StartConsole, "c", false, "debug and testing console") @@ -38,6 +39,7 @@ func Init() { flag.StringVar(&DataDir, "dir", ".ethereum", "ethereum data directory") flag.StringVar(&ImportKey, "import", "", "imports the given private key (hex)") flag.IntVar(&MaxPeer, "x", 5, "maximum desired peers") + flag.BoolVar(&StartExp, "ex", false, "exp") flag.Parse() } diff --git a/ethereum/ethereum.go b/ethereum/ethereum.go index 2abf6da42..8b42c2a2c 100644 --- a/ethereum/ethereum.go +++ b/ethereum/ethereum.go @@ -146,6 +146,13 @@ save these words so you can restore your account later: %s console := NewConsole(ethereum) go console.Start() } + + if StartExp { + c := NewJSConsole(ethereum) + + go c.Start() + } + if StartRpc { utils.DoRpc(ethereum, RpcPort) } diff --git a/ethereum/javascript_console.go b/ethereum/javascript_console.go new file mode 100644 index 000000000..a6449af8f --- /dev/null +++ b/ethereum/javascript_console.go @@ -0,0 +1,76 @@ +package main + +import ( + "bufio" + "fmt" + "github.com/ethereum/eth-go" + "github.com/ethereum/eth-go/ethpub" + "github.com/robertkrimen/otto" + "os" +) + +type JSConsole struct { + vm *otto.Otto + lib *ethpub.PEthereum +} + +func NewJSConsole(ethereum *eth.Ethereum) *JSConsole { + return &JSConsole{vm: otto.New(), lib: ethpub.NewPEthereum(ethereum)} +} + +func (self *JSConsole) Start() { + self.initBindings() + + fmt.Println("Eth JS Console") + reader := bufio.NewReader(os.Stdin) + for { + fmt.Printf("eth >>> ") + str, _, err := reader.ReadLine() + if err != nil { + fmt.Println("Error reading input", err) + } else { + if string(str) == "quit" { + return + } + + self.ParseInput(string(str)) + } + } +} + +func (self *JSConsole) ParseInput(code string) { + value, err := self.vm.Run(code) + if err != nil { + fmt.Println(err) + return + } + + fmt.Println(value) +} + +type OtherStruct struct { + Test string +} + +type JSWrapper struct { + pub *ethpub.PEthereum + vm *otto.Otto +} + +func (self *JSWrapper) GetKey() otto.Value { + result, err := self.vm.ToValue(self.pub.GetKey()) + if err != nil { + fmt.Println(err) + + return otto.UndefinedValue() + } + + return result + +} + +func (self *JSConsole) initBindings() { + t := &JSWrapper{self.lib, self.vm} + + self.vm.Set("eth", t) +} From 0a03484188dc23707b343bb512ec341afc744a2e Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 15 May 2014 22:15:14 +0200 Subject: [PATCH 2/3] Implemented JavaScript console --- ethereum/ethereum.go | 11 +++--- ethereum/javascript_console.go | 66 +++++++++++++++++++++++++--------- 2 files changed, 56 insertions(+), 21 deletions(-) diff --git a/ethereum/ethereum.go b/ethereum/ethereum.go index 8b42c2a2c..128e11139 100644 --- a/ethereum/ethereum.go +++ b/ethereum/ethereum.go @@ -52,7 +52,12 @@ func main() { var logSys *log.Logger flags := log.LstdFlags - ethutil.ReadConfig(DataDir) + if StartJsConsole { + ethutil.ReadConfig(DataDir, ethutil.LogFile) + } else { + ethutil.ReadConfig(DataDir, ethutil.LogFile|ethutil.LogStd) + } + logger := ethutil.Config.Log if LogFile != "" { @@ -145,9 +150,7 @@ save these words so you can restore your account later: %s console := NewConsole(ethereum) go console.Start() - } - - if StartExp { + } else if StartJsConsole { c := NewJSConsole(ethereum) go c.Start() diff --git a/ethereum/javascript_console.go b/ethereum/javascript_console.go index a6449af8f..9adf51bcc 100644 --- a/ethereum/javascript_console.go +++ b/ethereum/javascript_console.go @@ -21,7 +21,7 @@ func NewJSConsole(ethereum *eth.Ethereum) *JSConsole { func (self *JSConsole) Start() { self.initBindings() - fmt.Println("Eth JS Console") + fmt.Println("Eth JavaScript console") reader := bufio.NewReader(os.Stdin) for { fmt.Printf("eth >>> ") @@ -29,16 +29,18 @@ func (self *JSConsole) Start() { if err != nil { fmt.Println("Error reading input", err) } else { - if string(str) == "quit" { - return - } - self.ParseInput(string(str)) } } } func (self *JSConsole) ParseInput(code string) { + defer func() { + if r := recover(); r != nil { + fmt.Println("[native] error", r) + } + }() + value, err := self.vm.Run(code) if err != nil { fmt.Println(err) @@ -48,17 +50,54 @@ func (self *JSConsole) ParseInput(code string) { fmt.Println(value) } -type OtherStruct struct { - Test string +func (self *JSConsole) initBindings() { + t := &JSWrapper{self.lib, self.vm} + + self.vm.Set("eth", t) } +// The JS wrapper attempts to wrap the PEthereum object and returns +// proper javascript objects type JSWrapper struct { - pub *ethpub.PEthereum - vm *otto.Otto + *ethpub.PEthereum + vm *otto.Otto } func (self *JSWrapper) GetKey() otto.Value { - result, err := self.vm.ToValue(self.pub.GetKey()) + return self.toVal(self.PEthereum.GetKey()) +} + +func (self *JSWrapper) GetStateObject(addr string) otto.Value { + return self.toVal(self.PEthereum.GetStateObject(addr)) +} + +func (self *JSWrapper) Transact(key, recipient, valueStr, gasStr, gasPriceStr, dataStr string) otto.Value { + r, err := self.PEthereum.Transact(key, recipient, valueStr, gasStr, gasPriceStr, dataStr) + if err != nil { + fmt.Println(err) + + return otto.UndefinedValue() + } + + return self.toVal(r) +} + +func (self *JSWrapper) Create(key, valueStr, gasStr, gasPriceStr, initStr, bodyStr string) otto.Value { + r, err := self.PEthereum.Create(key, valueStr, gasStr, gasPriceStr, initStr, bodyStr) + + if err != nil { + fmt.Println(err) + + return otto.UndefinedValue() + } + + return self.toVal(r) +} + +// Wrapper function +func (self *JSWrapper) toVal(v interface{}) otto.Value { + result, err := self.vm.ToValue(v) + if err != nil { fmt.Println(err) @@ -66,11 +105,4 @@ func (self *JSWrapper) GetKey() otto.Value { } return result - -} - -func (self *JSConsole) initBindings() { - t := &JSWrapper{self.lib, self.vm} - - self.vm.Set("eth", t) } From 6a78e080e645753ffe3e3bef0b09e71a2469c564 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 15 May 2014 22:17:09 +0200 Subject: [PATCH 3/3] Tell config which loggers to use --- ethereal/ethereum.go | 2 +- ethereum/config.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/ethereal/ethereum.go b/ethereal/ethereum.go index 98fab18e3..206971b41 100644 --- a/ethereal/ethereum.go +++ b/ethereal/ethereum.go @@ -39,7 +39,7 @@ func main() { runtime.GOMAXPROCS(runtime.NumCPU()) ethchain.InitFees() - ethutil.ReadConfig(DataDir) + ethutil.ReadConfig(DataDir, ethutil.LogFile|ethutil.LogStd) // Instantiated a eth stack ethereum, err := eth.New(eth.CapDefault, UseUPnP) diff --git a/ethereum/config.go b/ethereum/config.go index 4d7ea6310..5ddc8e635 100644 --- a/ethereum/config.go +++ b/ethereum/config.go @@ -20,7 +20,7 @@ var ExportKey bool var LogFile string var DataDir string var NonInteractive bool -var StartExp bool +var StartJsConsole bool func Init() { flag.BoolVar(&StartConsole, "c", false, "debug and testing console") @@ -39,7 +39,7 @@ func Init() { flag.StringVar(&DataDir, "dir", ".ethereum", "ethereum data directory") flag.StringVar(&ImportKey, "import", "", "imports the given private key (hex)") flag.IntVar(&MaxPeer, "x", 5, "maximum desired peers") - flag.BoolVar(&StartExp, "ex", false, "exp") + flag.BoolVar(&StartJsConsole, "js", false, "exp") flag.Parse() }