From cbce882f5e35300016055cde81eeccb3ae052671 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 15 May 2014 20:45:19 +0200 Subject: 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 (limited to 'ethereum') 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) +} -- cgit v1.2.3 From 0a03484188dc23707b343bb512ec341afc744a2e Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 15 May 2014 22:15:14 +0200 Subject: Implemented JavaScript console --- ethereum/ethereum.go | 11 +++++--- ethereum/javascript_console.go | 60 ++++++++++++++++++++++++++++++++---------- 2 files changed, 53 insertions(+), 18 deletions(-) (limited to 'ethereum') 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,29 +50,59 @@ 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 result + 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) } -func (self *JSConsole) initBindings() { - t := &JSWrapper{self.lib, self.vm} +// Wrapper function +func (self *JSWrapper) toVal(v interface{}) otto.Value { + result, err := self.vm.ToValue(v) - self.vm.Set("eth", t) + if err != nil { + fmt.Println(err) + + return otto.UndefinedValue() + } + + return result } -- cgit v1.2.3 From 6a78e080e645753ffe3e3bef0b09e71a2469c564 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 15 May 2014 22:17:09 +0200 Subject: Tell config which loggers to use --- ethereum/config.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'ethereum') 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() } -- cgit v1.2.3 From 770808ce0d44cadfedbe01694c836be2eaf0e82c Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 17 May 2014 15:15:46 +0200 Subject: Readline repl for linux & osx --- ethereum/ethereum.go | 4 +-- ethereum/javascript_console.go | 71 ++++++++++++++++++++++-------------------- ethereum/repl_darwin.go | 55 ++++++++++++++++++++++++++++++++ ethereum/repl_linux.go | 1 + ethereum/repl_windows.go | 20 ++++++++++++ 5 files changed, 116 insertions(+), 35 deletions(-) create mode 100644 ethereum/repl_darwin.go create mode 120000 ethereum/repl_linux.go create mode 100644 ethereum/repl_windows.go (limited to 'ethereum') diff --git a/ethereum/ethereum.go b/ethereum/ethereum.go index 128e11139..04933ef8e 100644 --- a/ethereum/ethereum.go +++ b/ethereum/ethereum.go @@ -151,9 +151,9 @@ save these words so you can restore your account later: %s console := NewConsole(ethereum) go console.Start() } else if StartJsConsole { - c := NewJSConsole(ethereum) + repl := NewJSRepl(ethereum) - go c.Start() + go repl.Start() } if StartRpc { diff --git a/ethereum/javascript_console.go b/ethereum/javascript_console.go index 9adf51bcc..9a10ca236 100644 --- a/ethereum/javascript_console.go +++ b/ethereum/javascript_console.go @@ -1,47 +1,58 @@ package main import ( - "bufio" "fmt" "github.com/ethereum/eth-go" "github.com/ethereum/eth-go/ethpub" "github.com/robertkrimen/otto" - "os" ) -type JSConsole struct { +type Repl interface { + Start() +} + +type JSRE struct { vm *otto.Otto lib *ethpub.PEthereum } -func NewJSConsole(ethereum *eth.Ethereum) *JSConsole { - return &JSConsole{vm: otto.New(), lib: ethpub.NewPEthereum(ethereum)} +func NewJSRE(ethereum *eth.Ethereum) *JSRE { + re := &JSRE{vm: otto.New(), lib: ethpub.NewPEthereum(ethereum)} + + re.Bind("eth", &JSEthereum{re.lib, re.vm}) + + return re +} + +func (self *JSRE) Bind(name string, v interface{}) { + self.vm.Set(name, v) +} + +func (self *JSRE) Run(code string) (otto.Value, error) { + return self.vm.Run(code) } -func (self *JSConsole) Start() { - self.initBindings() +type JSRepl struct { + re *JSRE +} + +func NewJSRepl(ethereum *eth.Ethereum) *JSRepl { + return &JSRepl{re: NewJSRE(ethereum)} +} +func (self *JSRepl) Start() { fmt.Println("Eth JavaScript console") - reader := bufio.NewReader(os.Stdin) - for { - fmt.Printf("eth >>> ") - str, _, err := reader.ReadLine() - if err != nil { - fmt.Println("Error reading input", err) - } else { - self.ParseInput(string(str)) - } - } + self.read() } -func (self *JSConsole) ParseInput(code string) { +func (self *JSRepl) parseInput(code string) { defer func() { if r := recover(); r != nil { fmt.Println("[native] error", r) } }() - value, err := self.vm.Run(code) + value, err := self.re.Run(code) if err != nil { fmt.Println(err) return @@ -50,28 +61,22 @@ func (self *JSConsole) ParseInput(code string) { fmt.Println(value) } -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 { +// The JSEthereum object attempts to wrap the PEthereum object and returns +// meaningful javascript objects +type JSEthereum struct { *ethpub.PEthereum vm *otto.Otto } -func (self *JSWrapper) GetKey() otto.Value { +func (self *JSEthereum) GetKey() otto.Value { return self.toVal(self.PEthereum.GetKey()) } -func (self *JSWrapper) GetStateObject(addr string) otto.Value { +func (self *JSEthereum) 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 { +func (self *JSEthereum) 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) @@ -82,7 +87,7 @@ func (self *JSWrapper) Transact(key, recipient, valueStr, gasStr, gasPriceStr, d return self.toVal(r) } -func (self *JSWrapper) Create(key, valueStr, gasStr, gasPriceStr, initStr, bodyStr string) otto.Value { +func (self *JSEthereum) Create(key, valueStr, gasStr, gasPriceStr, initStr, bodyStr string) otto.Value { r, err := self.PEthereum.Create(key, valueStr, gasStr, gasPriceStr, initStr, bodyStr) if err != nil { @@ -95,7 +100,7 @@ func (self *JSWrapper) Create(key, valueStr, gasStr, gasPriceStr, initStr, bodyS } // Wrapper function -func (self *JSWrapper) toVal(v interface{}) otto.Value { +func (self *JSEthereum) toVal(v interface{}) otto.Value { result, err := self.vm.ToValue(v) if err != nil { diff --git a/ethereum/repl_darwin.go b/ethereum/repl_darwin.go new file mode 100644 index 000000000..b6de190e4 --- /dev/null +++ b/ethereum/repl_darwin.go @@ -0,0 +1,55 @@ +package main + +// #cgo LDFLAGS: -lreadline +// #include +// #include +// #include +// #include +import "C" +import "unsafe" + +func readLine(prompt *string) *string { + var p *C.char + + //readline allows an empty prompt(NULL) + if prompt != nil { + p = C.CString(*prompt) + } + + ret := C.readline(p) + + if p != nil { + C.free(unsafe.Pointer(p)) + } + + if ret == nil { + return nil + } //EOF + + s := C.GoString(ret) + C.free(unsafe.Pointer(ret)) + return &s +} + +func addHistory(s string) { + p := C.CString(s) + C.add_history(p) + C.free(unsafe.Pointer(p)) +} + +func (self *JSRepl) read() { + prompt := "eth >>> " + +L: + for { + switch result := readLine(&prompt); true { + case result == nil: + break L //exit loop + + case *result != "": //ignore blank lines + addHistory(*result) //allow user to recall this line + + self.parseInput(*result) + } + } +} diff --git a/ethereum/repl_linux.go b/ethereum/repl_linux.go new file mode 120000 index 000000000..276f135d7 --- /dev/null +++ b/ethereum/repl_linux.go @@ -0,0 +1 @@ +repl_darwin.go \ No newline at end of file diff --git a/ethereum/repl_windows.go b/ethereum/repl_windows.go new file mode 100644 index 000000000..c65bb1cb4 --- /dev/null +++ b/ethereum/repl_windows.go @@ -0,0 +1,20 @@ +package main + +import ( + "bufio" + "fmt" + "os" +) + +func (self *JSRepl) read() { + reader := bufio.NewReader(os.Stdin) + for { + fmt.Printf("eth >>> ") + str, _, err := reader.ReadLine() + if err != nil { + fmt.Println("Error reading input", err) + } else { + self.parseInput(string(str)) + } + } +} -- cgit v1.2.3 From 3b7707c3fd2f99ee1019b8214cba1784af519f53 Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 19 May 2014 12:15:03 +0200 Subject: Improved console * Added watch --- ethereum/javascript_console.go | 74 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 70 insertions(+), 4 deletions(-) (limited to 'ethereum') diff --git a/ethereum/javascript_console.go b/ethereum/javascript_console.go index 9a10ca236..884b9a629 100644 --- a/ethereum/javascript_console.go +++ b/ethereum/javascript_console.go @@ -3,7 +3,9 @@ package main import ( "fmt" "github.com/ethereum/eth-go" + "github.com/ethereum/eth-go/ethchain" "github.com/ethereum/eth-go/ethpub" + "github.com/ethereum/eth-go/ethutil" "github.com/robertkrimen/otto" ) @@ -12,18 +14,83 @@ type Repl interface { } type JSRE struct { - vm *otto.Otto - lib *ethpub.PEthereum + ethereum *eth.Ethereum + vm *otto.Otto + lib *ethpub.PEthereum + + blockChan chan ethutil.React + changeChan chan ethutil.React + quitChan chan bool + + objectCb map[string][]otto.Value } func NewJSRE(ethereum *eth.Ethereum) *JSRE { - re := &JSRE{vm: otto.New(), lib: ethpub.NewPEthereum(ethereum)} + re := &JSRE{ + ethereum, + otto.New(), + ethpub.NewPEthereum(ethereum), + make(chan ethutil.React, 1), + make(chan ethutil.React, 1), + make(chan bool), + make(map[string][]otto.Value), + } + + // We have to make sure that, whoever calls this, calls "Stop" + go re.mainLoop() re.Bind("eth", &JSEthereum{re.lib, re.vm}) + t, _ := re.vm.Get("eth") + t.Object().Set("watch", func(call otto.FunctionCall) otto.Value { + addr, _ := call.Argument(0).ToString() + cb := call.Argument(1) + + re.objectCb[addr] = append(re.objectCb[addr], cb) + + event := "object:" + string(ethutil.FromHex(addr)) + ethereum.Reactor().Subscribe(event, re.changeChan) + + return otto.UndefinedValue() + }) return re } +func (self *JSRE) Stop() { + // Kill the main loop + self.quitChan <- true + + close(self.blockChan) + close(self.quitChan) + close(self.changeChan) +} + +func (self *JSRE) mainLoop() { + // Subscribe to events + reactor := self.ethereum.Reactor() + reactor.Subscribe("newBlock", self.blockChan) + +out: + for { + select { + case <-self.quitChan: + break out + case block := <-self.blockChan: + if _, ok := block.Resource.(*ethchain.Block); ok { + } + case object := <-self.changeChan: + if stateObject, ok := object.Resource.(*ethchain.StateObject); ok { + for _, cb := range self.objectCb[ethutil.Hex(stateObject.Address())] { + val, _ := self.vm.ToValue(ethpub.NewPStateObject(stateObject)) + cb.Call(cb, val) + } + } else if storageObject, ok := object.Resource.(*ethchain.StorageState); ok { + fmt.Println(storageObject) + } + } + } +} + func (self *JSRE) Bind(name string, v interface{}) { self.vm.Set(name, v) } @@ -99,7 +166,6 @@ func (self *JSEthereum) Create(key, valueStr, gasStr, gasPriceStr, initStr, body return self.toVal(r) } -// Wrapper function func (self *JSEthereum) toVal(v interface{}) otto.Value { result, err := self.vm.ToValue(v) -- cgit v1.2.3 From 16421106d47efb65331ed9f0499f12038158cbf1 Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 19 May 2014 13:04:31 +0200 Subject: Added multi-line support --- ethereum/javascript_console.go | 5 +++-- ethereum/repl_darwin.go | 37 +++++++++++++++++++++++++++++++------ ethereum/repl_windows.go | 2 +- 3 files changed, 35 insertions(+), 9 deletions(-) (limited to 'ethereum') diff --git a/ethereum/javascript_console.go b/ethereum/javascript_console.go index 884b9a629..1e1ae0e48 100644 --- a/ethereum/javascript_console.go +++ b/ethereum/javascript_console.go @@ -101,14 +101,15 @@ func (self *JSRE) Run(code string) (otto.Value, error) { type JSRepl struct { re *JSRE + + prompt string } func NewJSRepl(ethereum *eth.Ethereum) *JSRepl { - return &JSRepl{re: NewJSRE(ethereum)} + return &JSRepl{re: NewJSRE(ethereum), prompt: "> "} } func (self *JSRepl) Start() { - fmt.Println("Eth JavaScript console") self.read() } diff --git a/ethereum/repl_darwin.go b/ethereum/repl_darwin.go index b6de190e4..483d4cedf 100644 --- a/ethereum/repl_darwin.go +++ b/ethereum/repl_darwin.go @@ -6,7 +6,11 @@ package main // #include // #include import "C" -import "unsafe" + +import ( + "strings" + "unsafe" +) func readLine(prompt *string) *string { var p *C.char @@ -37,19 +41,40 @@ func addHistory(s string) { C.free(unsafe.Pointer(p)) } -func (self *JSRepl) read() { - prompt := "eth >>> " +var indentCount = 0 +var str = "" + +func (self *JSRepl) setIndent() { + open := strings.Count(str, "{") + open += strings.Count(str, "(") + closed := strings.Count(str, "}") + closed += strings.Count(str, ")") + indentCount = open - closed + if indentCount <= 0 { + self.prompt = "> " + } else { + self.prompt = strings.Join(make([]string, indentCount*2), "..") + self.prompt += " " + } +} +func (self *JSRepl) read() { L: for { - switch result := readLine(&prompt); true { + switch result := readLine(&self.prompt); true { case result == nil: break L //exit loop case *result != "": //ignore blank lines - addHistory(*result) //allow user to recall this line + str += *result + "\n" + + self.setIndent() + + if indentCount <= 0 { + addHistory(str) //allow user to recall this line - self.parseInput(*result) + self.parseInput(str) + } } } } diff --git a/ethereum/repl_windows.go b/ethereum/repl_windows.go index c65bb1cb4..c42fd6e6a 100644 --- a/ethereum/repl_windows.go +++ b/ethereum/repl_windows.go @@ -9,7 +9,7 @@ import ( func (self *JSRepl) read() { reader := bufio.NewReader(os.Stdin) for { - fmt.Printf("eth >>> ") + fmt.Printf(self.prompt) str, _, err := reader.ReadLine() if err != nil { fmt.Println("Error reading input", err) -- cgit v1.2.3 From 017bbbb582b09a3264b4ff996f35275d381f284f Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 19 May 2014 16:32:45 +0200 Subject: Improved REPL output --- ethereum/ethereum.go | 24 +++++++++++++--------- ethereum/javascript_console.go | 10 ++++++++- ethereum/js_lib.go | 46 ++++++++++++++++++++++++++++++++++++++++++ ethereum/repl_darwin.go | 17 ++++++++++++++-- ethereum/repl_windows.go | 4 ++++ 5 files changed, 89 insertions(+), 12 deletions(-) create mode 100644 ethereum/js_lib.go (limited to 'ethereum') diff --git a/ethereum/ethereum.go b/ethereum/ethereum.go index 04933ef8e..1cbb61002 100644 --- a/ethereum/ethereum.go +++ b/ethereum/ethereum.go @@ -15,16 +15,15 @@ import ( const Debug = true -// Register interrupt handlers so we can stop the ethereum -func RegisterInterrupts(s *eth.Ethereum) { - // Buffered chan of one is enough - c := make(chan os.Signal, 1) - // Notify about interrupts for now - signal.Notify(c, os.Interrupt) +func RegisterInterrupt(cb func(os.Signal)) { go func() { + // Buffered chan of one is enough + c := make(chan os.Signal, 1) + // Notify about interrupts for now + signal.Notify(c, os.Interrupt) + for sig := range c { - fmt.Printf("Shutting down (%v) ... \n", sig) - s.Stop() + cb(sig) } }() } @@ -154,13 +153,20 @@ save these words so you can restore your account later: %s repl := NewJSRepl(ethereum) go repl.Start() + + RegisterInterrupt(func(os.Signal) { + repl.Stop() + }) } if StartRpc { utils.DoRpc(ethereum, RpcPort) } - RegisterInterrupts(ethereum) + RegisterInterrupt(func(sig os.Signal) { + fmt.Printf("Shutting down (%v) ... \n", sig) + ethereum.Stop() + }) ethereum.Start(UseSeed) diff --git a/ethereum/javascript_console.go b/ethereum/javascript_console.go index 1e1ae0e48..07d69dafc 100644 --- a/ethereum/javascript_console.go +++ b/ethereum/javascript_console.go @@ -11,6 +11,7 @@ import ( type Repl interface { Start() + Stop() } type JSRE struct { @@ -36,6 +37,9 @@ func NewJSRE(ethereum *eth.Ethereum) *JSRE { make(map[string][]otto.Value), } + // Init the JS lib + re.vm.Run(jsLib) + // We have to make sure that, whoever calls this, calls "Stop" go re.mainLoop() @@ -113,6 +117,10 @@ func (self *JSRepl) Start() { self.read() } +func (self *JSRepl) Stop() { + self.re.Stop() +} + func (self *JSRepl) parseInput(code string) { defer func() { if r := recover(); r != nil { @@ -126,7 +134,7 @@ func (self *JSRepl) parseInput(code string) { return } - fmt.Println(value) + self.PrintValue(value) } // The JSEthereum object attempts to wrap the PEthereum object and returns diff --git a/ethereum/js_lib.go b/ethereum/js_lib.go new file mode 100644 index 000000000..8b59d75ca --- /dev/null +++ b/ethereum/js_lib.go @@ -0,0 +1,46 @@ +package main + +const jsLib = ` +function pp(object) { + var str = ""; + + if(object instanceof Array) { + str += "[ "; + for(var i = 0, l = object.length; i < l; i++) { + str += pp(object[i]); + + if(i < l-1) { + str += ", "; + } + } + str += " ]"; + } else if(typeof(object) === "object") { + str += "{ "; + var last = Object.keys(object).sort().pop() + for(var k in object) { + str += k + ": " + pp(object[k]); + + if(k !== last) { + str += ", "; + } + } + str += " }"; + } else if(typeof(object) === "string") { + str += "\033[32m'" + object + "'"; + } else if(typeof(object) === "undefined") { + str += "\033[1m\033[30m" + object; + } else if(typeof(object) === "number") { + str += "\033[31m" + object; + } else { + str += object; + } + + str += "\033[0m"; + + return str; +} + +function prettyPrint(object) { + console.log(pp(object)) +} +` diff --git a/ethereum/repl_darwin.go b/ethereum/repl_darwin.go index 483d4cedf..87da3df1d 100644 --- a/ethereum/repl_darwin.go +++ b/ethereum/repl_darwin.go @@ -8,6 +8,7 @@ package main import "C" import ( + "github.com/robertkrimen/otto" "strings" "unsafe" ) @@ -63,18 +64,30 @@ L: for { switch result := readLine(&self.prompt); true { case result == nil: - break L //exit loop + break L - case *result != "": //ignore blank lines + case *result != "": str += *result + "\n" self.setIndent() if indentCount <= 0 { + if *result == "exit" { + self.Stop() + break L + } + addHistory(str) //allow user to recall this line self.parseInput(str) + + str = "" } } } } + +func (self *JSRepl) PrintValue(value otto.Value) { + method, _ := self.re.vm.Get("prettyPrint") + method.Call(method, value) +} diff --git a/ethereum/repl_windows.go b/ethereum/repl_windows.go index c42fd6e6a..9d4787772 100644 --- a/ethereum/repl_windows.go +++ b/ethereum/repl_windows.go @@ -18,3 +18,7 @@ func (self *JSRepl) read() { } } } + +func (self *JSRepl) PrintValue(value otto.Value) { + fmt.Println(value) +} -- cgit v1.2.3 From 92eaa98e8381bef5224ffe864aa1cd4288af4d12 Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 19 May 2014 17:01:40 +0200 Subject: Added js interpret mode --- ethereum/config.go | 2 ++ ethereum/ethereum.go | 19 ++++++++++++++++++- ethereum/js_lib.go | 11 +++++++++-- 3 files changed, 29 insertions(+), 3 deletions(-) (limited to 'ethereum') diff --git a/ethereum/config.go b/ethereum/config.go index 5ddc8e635..090c022b0 100644 --- a/ethereum/config.go +++ b/ethereum/config.go @@ -21,6 +21,7 @@ var LogFile string var DataDir string var NonInteractive bool var StartJsConsole bool +var InputFile string func Init() { flag.BoolVar(&StartConsole, "c", false, "debug and testing console") @@ -40,6 +41,7 @@ func Init() { flag.StringVar(&ImportKey, "import", "", "imports the given private key (hex)") flag.IntVar(&MaxPeer, "x", 5, "maximum desired peers") flag.BoolVar(&StartJsConsole, "js", false, "exp") + flag.StringVar(&InputFile, "e", "", "Run javascript file") flag.Parse() } diff --git a/ethereum/ethereum.go b/ethereum/ethereum.go index 1cbb61002..f680b5416 100644 --- a/ethereum/ethereum.go +++ b/ethereum/ethereum.go @@ -6,6 +6,7 @@ import ( "github.com/ethereum/eth-go/ethchain" "github.com/ethereum/eth-go/ethutil" "github.com/ethereum/go-ethereum/utils" + "io/ioutil" "log" "os" "os/signal" @@ -51,7 +52,7 @@ func main() { var logSys *log.Logger flags := log.LstdFlags - if StartJsConsole { + if StartJsConsole || len(InputFile) > 0 { ethutil.ReadConfig(DataDir, ethutil.LogFile) } else { ethutil.ReadConfig(DataDir, ethutil.LogFile|ethutil.LogStd) @@ -157,6 +158,22 @@ save these words so you can restore your account later: %s RegisterInterrupt(func(os.Signal) { repl.Stop() }) + } else if len(InputFile) > 0 { + file, err := os.Open(InputFile) + if err != nil { + ethutil.Config.Log.Fatal(err) + } + + content, err := ioutil.ReadAll(file) + if err != nil { + ethutil.Config.Log.Fatal(err) + } + + re := NewJSRE(ethereum) + RegisterInterrupt(func(os.Signal) { + re.Stop() + }) + re.Run(string(content)) } if StartRpc { diff --git a/ethereum/js_lib.go b/ethereum/js_lib.go index 8b59d75ca..189dcc3a0 100644 --- a/ethereum/js_lib.go +++ b/ethereum/js_lib.go @@ -31,6 +31,8 @@ function pp(object) { str += "\033[1m\033[30m" + object; } else if(typeof(object) === "number") { str += "\033[31m" + object; + } else if(typeof(object) === "function") { + str += "\033[35m[Function]"; } else { str += object; } @@ -40,7 +42,12 @@ function pp(object) { return str; } -function prettyPrint(object) { - console.log(pp(object)) +function prettyPrint(/* */) { + var args = arguments; + for(var i = 0, l = args.length; i < l; i++) { + console.log(pp(args[i])) + } } + +var print = prettyPrint; ` -- cgit v1.2.3 From dfc3cb441bed85728914f5575a86c9fcb1f61211 Mon Sep 17 00:00:00 2001 From: Maran Date: Tue, 20 May 2014 11:52:36 +0200 Subject: Increase default peer amount to 10 --- ethereum/config.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ethereum') diff --git a/ethereum/config.go b/ethereum/config.go index 090c022b0..117aa6f2c 100644 --- a/ethereum/config.go +++ b/ethereum/config.go @@ -39,7 +39,7 @@ func Init() { flag.StringVar(&LogFile, "logfile", "", "log file (defaults to standard output)") 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.IntVar(&MaxPeer, "x", 10, "maximum desired peers") flag.BoolVar(&StartJsConsole, "js", false, "exp") flag.StringVar(&InputFile, "e", "", "Run javascript file") -- cgit v1.2.3 From a05adb11288a1ea9dc6e38a952ab89fa5eb7f794 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 20 May 2014 12:48:34 +0200 Subject: Refactored file structure --- ethereum/javascript_console.go | 188 ----------------------------------------- ethereum/javascript_runtime.go | 114 +++++++++++++++++++++++++ ethereum/repl.go | 97 +++++++++++++++++++++ 3 files changed, 211 insertions(+), 188 deletions(-) delete mode 100644 ethereum/javascript_console.go create mode 100644 ethereum/javascript_runtime.go create mode 100644 ethereum/repl.go (limited to 'ethereum') diff --git a/ethereum/javascript_console.go b/ethereum/javascript_console.go deleted file mode 100644 index 07d69dafc..000000000 --- a/ethereum/javascript_console.go +++ /dev/null @@ -1,188 +0,0 @@ -package main - -import ( - "fmt" - "github.com/ethereum/eth-go" - "github.com/ethereum/eth-go/ethchain" - "github.com/ethereum/eth-go/ethpub" - "github.com/ethereum/eth-go/ethutil" - "github.com/robertkrimen/otto" -) - -type Repl interface { - Start() - Stop() -} - -type JSRE struct { - ethereum *eth.Ethereum - vm *otto.Otto - lib *ethpub.PEthereum - - blockChan chan ethutil.React - changeChan chan ethutil.React - quitChan chan bool - - objectCb map[string][]otto.Value -} - -func NewJSRE(ethereum *eth.Ethereum) *JSRE { - re := &JSRE{ - ethereum, - otto.New(), - ethpub.NewPEthereum(ethereum), - make(chan ethutil.React, 1), - make(chan ethutil.React, 1), - make(chan bool), - make(map[string][]otto.Value), - } - - // Init the JS lib - re.vm.Run(jsLib) - - // We have to make sure that, whoever calls this, calls "Stop" - go re.mainLoop() - - re.Bind("eth", &JSEthereum{re.lib, re.vm}) - t, _ := re.vm.Get("eth") - t.Object().Set("watch", func(call otto.FunctionCall) otto.Value { - addr, _ := call.Argument(0).ToString() - cb := call.Argument(1) - - re.objectCb[addr] = append(re.objectCb[addr], cb) - - event := "object:" + string(ethutil.FromHex(addr)) - ethereum.Reactor().Subscribe(event, re.changeChan) - - return otto.UndefinedValue() - }) - - return re -} - -func (self *JSRE) Stop() { - // Kill the main loop - self.quitChan <- true - - close(self.blockChan) - close(self.quitChan) - close(self.changeChan) -} - -func (self *JSRE) mainLoop() { - // Subscribe to events - reactor := self.ethereum.Reactor() - reactor.Subscribe("newBlock", self.blockChan) - -out: - for { - select { - case <-self.quitChan: - break out - case block := <-self.blockChan: - if _, ok := block.Resource.(*ethchain.Block); ok { - } - case object := <-self.changeChan: - if stateObject, ok := object.Resource.(*ethchain.StateObject); ok { - for _, cb := range self.objectCb[ethutil.Hex(stateObject.Address())] { - val, _ := self.vm.ToValue(ethpub.NewPStateObject(stateObject)) - cb.Call(cb, val) - } - } else if storageObject, ok := object.Resource.(*ethchain.StorageState); ok { - fmt.Println(storageObject) - } - } - } -} - -func (self *JSRE) Bind(name string, v interface{}) { - self.vm.Set(name, v) -} - -func (self *JSRE) Run(code string) (otto.Value, error) { - return self.vm.Run(code) -} - -type JSRepl struct { - re *JSRE - - prompt string -} - -func NewJSRepl(ethereum *eth.Ethereum) *JSRepl { - return &JSRepl{re: NewJSRE(ethereum), prompt: "> "} -} - -func (self *JSRepl) Start() { - self.read() -} - -func (self *JSRepl) Stop() { - self.re.Stop() -} - -func (self *JSRepl) parseInput(code string) { - defer func() { - if r := recover(); r != nil { - fmt.Println("[native] error", r) - } - }() - - value, err := self.re.Run(code) - if err != nil { - fmt.Println(err) - return - } - - self.PrintValue(value) -} - -// The JSEthereum object attempts to wrap the PEthereum object and returns -// meaningful javascript objects -type JSEthereum struct { - *ethpub.PEthereum - vm *otto.Otto -} - -func (self *JSEthereum) GetKey() otto.Value { - return self.toVal(self.PEthereum.GetKey()) -} - -func (self *JSEthereum) GetStateObject(addr string) otto.Value { - return self.toVal(self.PEthereum.GetStateObject(addr)) -} - -func (self *JSEthereum) 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 *JSEthereum) 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) -} - -func (self *JSEthereum) toVal(v interface{}) otto.Value { - result, err := self.vm.ToValue(v) - - if err != nil { - fmt.Println(err) - - return otto.UndefinedValue() - } - - return result -} diff --git a/ethereum/javascript_runtime.go b/ethereum/javascript_runtime.go new file mode 100644 index 000000000..b06fb9460 --- /dev/null +++ b/ethereum/javascript_runtime.go @@ -0,0 +1,114 @@ +package main + +import ( + "fmt" + "github.com/ethereum/eth-go" + "github.com/ethereum/eth-go/ethchain" + "github.com/ethereum/eth-go/ethpub" + "github.com/ethereum/eth-go/ethutil" + "github.com/robertkrimen/otto" +) + +type JSRE struct { + ethereum *eth.Ethereum + vm *otto.Otto + lib *ethpub.PEthereum + + blockChan chan ethutil.React + changeChan chan ethutil.React + quitChan chan bool + + objectCb map[string][]otto.Value +} + +func NewJSRE(ethereum *eth.Ethereum) *JSRE { + re := &JSRE{ + ethereum, + otto.New(), + ethpub.NewPEthereum(ethereum), + make(chan ethutil.React, 1), + make(chan ethutil.React, 1), + make(chan bool), + make(map[string][]otto.Value), + } + + // Init the JS lib + re.vm.Run(jsLib) + + // We have to make sure that, whoever calls this, calls "Stop" + go re.mainLoop() + + re.Bind("eth", &JSEthereum{re.lib, re.vm}) + + re.initStdFuncs() + + return re +} + +func (self *JSRE) Bind(name string, v interface{}) { + self.vm.Set(name, v) +} + +func (self *JSRE) Run(code string) (otto.Value, error) { + return self.vm.Run(code) +} + +func (self *JSRE) Stop() { + // Kill the main loop + self.quitChan <- true + + close(self.blockChan) + close(self.quitChan) + close(self.changeChan) +} + +func (self *JSRE) mainLoop() { + // Subscribe to events + reactor := self.ethereum.Reactor() + reactor.Subscribe("newBlock", self.blockChan) + +out: + for { + select { + case <-self.quitChan: + break out + case block := <-self.blockChan: + if _, ok := block.Resource.(*ethchain.Block); ok { + } + case object := <-self.changeChan: + if stateObject, ok := object.Resource.(*ethchain.StateObject); ok { + for _, cb := range self.objectCb[ethutil.Hex(stateObject.Address())] { + val, _ := self.vm.ToValue(ethpub.NewPStateObject(stateObject)) + cb.Call(cb, val) + } + } else if storageObject, ok := object.Resource.(*ethchain.StorageState); ok { + fmt.Println(storageObject) + } + } + } +} + +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) + + 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() + }) +} diff --git a/ethereum/repl.go b/ethereum/repl.go new file mode 100644 index 000000000..c0b63c0a5 --- /dev/null +++ b/ethereum/repl.go @@ -0,0 +1,97 @@ +package main + +import ( + "fmt" + "github.com/ethereum/eth-go" + "github.com/ethereum/eth-go/ethpub" + "github.com/robertkrimen/otto" +) + +type Repl interface { + Start() + Stop() +} + +type JSRepl struct { + re *JSRE + + prompt string +} + +func NewJSRepl(ethereum *eth.Ethereum) *JSRepl { + return &JSRepl{re: NewJSRE(ethereum), prompt: "> "} +} + +func (self *JSRepl) Start() { + self.read() +} + +func (self *JSRepl) Stop() { + self.re.Stop() +} + +func (self *JSRepl) parseInput(code string) { + defer func() { + if r := recover(); r != nil { + fmt.Println("[native] error", r) + } + }() + + value, err := self.re.Run(code) + if err != nil { + fmt.Println(err) + return + } + + self.PrintValue(value) +} + +// The JSEthereum object attempts to wrap the PEthereum object and returns +// meaningful javascript objects +type JSEthereum struct { + *ethpub.PEthereum + vm *otto.Otto +} + +func (self *JSEthereum) GetKey() otto.Value { + return self.toVal(self.PEthereum.GetKey()) +} + +func (self *JSEthereum) GetStateObject(addr string) otto.Value { + return self.toVal(self.PEthereum.GetStateObject(addr)) +} + +func (self *JSEthereum) 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 *JSEthereum) 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) +} + +func (self *JSEthereum) toVal(v interface{}) otto.Value { + result, err := self.vm.ToValue(v) + + if err != nil { + fmt.Println(err) + + return otto.UndefinedValue() + } + + return result +} -- cgit v1.2.3 From 0ef7f6372939189dcfeaea8197798a63a6d6688a Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 20 May 2014 12:57:43 +0200 Subject: Removed old console in favor of the new JS REPL --- ethereum/config.go | 3 - ethereum/dev_console.go | 259 ------------------------------------------------ ethereum/ethereum.go | 11 +- 3 files changed, 1 insertion(+), 272 deletions(-) delete mode 100644 ethereum/dev_console.go (limited to 'ethereum') diff --git a/ethereum/config.go b/ethereum/config.go index 117aa6f2c..97e8687d8 100644 --- a/ethereum/config.go +++ b/ethereum/config.go @@ -4,7 +4,6 @@ import ( "flag" ) -var StartConsole bool var StartMining bool var StartRpc bool var RpcPort int @@ -24,10 +23,8 @@ var StartJsConsole bool var InputFile string func Init() { - flag.BoolVar(&StartConsole, "c", false, "debug and testing console") flag.BoolVar(&StartMining, "m", false, "start dagger mining") flag.BoolVar(&ShowGenesis, "g", false, "prints genesis header and exits") - //flag.BoolVar(&UseGui, "gui", true, "use the gui") flag.BoolVar(&StartRpc, "r", false, "start rpc server") flag.IntVar(&RpcPort, "rpcport", 8080, "port to start json-rpc server on") flag.BoolVar(&NonInteractive, "y", false, "non-interactive mode (say yes to confirmations)") diff --git a/ethereum/dev_console.go b/ethereum/dev_console.go deleted file mode 100644 index 5941c03ab..000000000 --- a/ethereum/dev_console.go +++ /dev/null @@ -1,259 +0,0 @@ -package main - -import ( - "bufio" - "bytes" - "encoding/hex" - "errors" - "fmt" - "github.com/ethereum/eth-go" - "github.com/ethereum/eth-go/ethchain" - "github.com/ethereum/eth-go/ethdb" - "github.com/ethereum/eth-go/ethutil" - "github.com/ethereum/eth-go/ethwire" - "github.com/ethereum/go-ethereum/utils" - "github.com/obscuren/mutan" - "os" - "strings" -) - -type Console struct { - db *ethdb.MemDatabase - trie *ethutil.Trie - ethereum *eth.Ethereum -} - -func NewConsole(s *eth.Ethereum) *Console { - db, _ := ethdb.NewMemDatabase() - trie := ethutil.NewTrie(db, "") - - return &Console{db: db, trie: trie, ethereum: s} -} - -func (i *Console) ValidateInput(action string, argumentLength int) error { - err := false - var expArgCount int - - switch { - case action == "update" && argumentLength != 2: - err = true - expArgCount = 2 - case action == "get" && argumentLength != 1: - err = true - expArgCount = 1 - case action == "dag" && argumentLength != 2: - err = true - expArgCount = 2 - case action == "decode" && argumentLength != 1: - err = true - expArgCount = 1 - case action == "encode" && argumentLength != 1: - err = true - expArgCount = 1 - case action == "gettx" && argumentLength != 1: - err = true - expArgCount = 1 - case action == "tx" && argumentLength != 4: - err = true - expArgCount = 4 - case action == "getaddr" && argumentLength != 1: - err = true - expArgCount = 1 - case action == "contract" && argumentLength != 2: - err = true - expArgCount = 2 - case action == "say" && argumentLength != 1: - err = true - expArgCount = 1 - case action == "addp" && argumentLength != 1: - err = true - expArgCount = 1 - case action == "block" && argumentLength != 1: - err = true - expArgCount = 1 - } - - if err { - return errors.New(fmt.Sprintf("'%s' requires %d args, got %d", action, expArgCount, argumentLength)) - } else { - return nil - } -} - -func (i *Console) Editor() string { - var buff bytes.Buffer - for { - reader := bufio.NewReader(os.Stdin) - str, _, err := reader.ReadLine() - if len(str) > 0 { - buff.Write(str) - buff.WriteString("\n") - } - - if err != nil && err.Error() == "EOF" { - break - } - } - - return buff.String() -} - -func (i *Console) PrintRoot() { - root := ethutil.NewValue(i.trie.Root) - if len(root.Bytes()) != 0 { - fmt.Println(hex.EncodeToString(root.Bytes())) - } else { - fmt.Println(i.trie.Root) - } -} - -func (i *Console) ParseInput(input string) bool { - scanner := bufio.NewScanner(strings.NewReader(input)) - scanner.Split(bufio.ScanWords) - - count := 0 - var tokens []string - for scanner.Scan() { - count++ - tokens = append(tokens, scanner.Text()) - } - if err := scanner.Err(); err != nil { - fmt.Fprintln(os.Stderr, "reading input:", err) - } - - if len(tokens) == 0 { - return true - } - - err := i.ValidateInput(tokens[0], count-1) - if err != nil { - fmt.Println(err) - } else { - switch tokens[0] { - case "update": - i.trie.Update(tokens[1], tokens[2]) - - i.PrintRoot() - case "get": - fmt.Println(i.trie.Get(tokens[1])) - case "root": - i.PrintRoot() - case "rawroot": - fmt.Println(i.trie.Root) - case "print": - i.db.Print() - case "dag": - fmt.Println(ethchain.DaggerVerify(ethutil.Big(tokens[1]), // hash - ethutil.BigPow(2, 36), // diff - ethutil.Big(tokens[2]))) // nonce - case "decode": - value := ethutil.NewValueFromBytes([]byte(tokens[1])) - fmt.Println(value) - case "getaddr": - encoded, _ := hex.DecodeString(tokens[1]) - addr := i.ethereum.BlockChain().CurrentBlock.State().GetAccount(encoded) - fmt.Println("addr:", addr) - case "block": - encoded, _ := hex.DecodeString(tokens[1]) - block := i.ethereum.BlockChain().GetBlock(encoded) - info := block.BlockInfo() - fmt.Printf("++++++++++ #%d ++++++++++\n%v\n", info.Number, block) - case "say": - i.ethereum.Broadcast(ethwire.MsgTalkTy, []interface{}{tokens[1]}) - case "addp": - i.ethereum.ConnectToPeer(tokens[1]) - case "pcount": - fmt.Println("peers:", i.ethereum.Peers().Len()) - case "encode": - fmt.Printf("%q\n", ethutil.Encode(tokens[1])) - case "tx": - recipient, err := hex.DecodeString(tokens[1]) - if err != nil { - fmt.Println("recipient err:", err) - } else { - tx := ethchain.NewTransactionMessage(recipient, ethutil.Big(tokens[2]), ethutil.Big(tokens[3]), ethutil.Big(tokens[4]), nil) - - keyPair := ethutil.GetKeyRing().Get(0) - tx.Sign(keyPair.PrivateKey) - i.ethereum.TxPool().QueueTransaction(tx) - - fmt.Printf("%x\n", tx.Hash()) - } - case "gettx": - addr, _ := hex.DecodeString(tokens[1]) - data, _ := ethutil.Config.Db.Get(addr) - if len(data) != 0 { - decoder := ethutil.NewValueFromBytes(data) - fmt.Println(decoder) - } else { - fmt.Println("gettx: tx not found") - } - case "contract": - fmt.Println("Contract editor (Ctrl-D = done)") - - mainInput, initInput := mutan.PreParse(i.Editor()) - mainScript, err := utils.Compile(mainInput) - if err != nil { - fmt.Println(err) - - break - } - initScript, err := utils.Compile(initInput) - if err != nil { - fmt.Println(err) - - break - } - - contract := ethchain.NewContractCreationTx(ethutil.Big(tokens[0]), ethutil.Big(tokens[1]), ethutil.Big(tokens[1]), mainScript, initScript) - - keyPair := ethutil.GetKeyRing().Get(0) - contract.Sign(keyPair.PrivateKey) - - i.ethereum.TxPool().QueueTransaction(contract) - - fmt.Printf("%x\n", contract.Hash()[12:]) - case "exit", "quit", "q": - return false - case "help": - fmt.Printf("COMMANDS:\n" + - "\033[1m= DB =\033[0m\n" + - "update KEY VALUE - Updates/Creates a new value for the given key\n" + - "get KEY - Retrieves the given key\n" + - "root - Prints the hex encoded merkle root\n" + - "rawroot - Prints the raw merkle root\n" + - "block HASH - Prints the block\n" + - "getaddr ADDR - Prints the account associated with the address\n" + - "\033[1m= Dagger =\033[0m\n" + - "dag HASH NONCE - Verifies a nonce with the given hash with dagger\n" + - "\033[1m= Encoding =\033[0m\n" + - "decode STR\n" + - "encode STR\n" + - "\033[1m= Other =\033[0m\n" + - "addp HOST:PORT\n" + - "tx TO AMOUNT\n" + - "contract AMOUNT\n") - - default: - fmt.Println("Unknown command:", tokens[0]) - } - } - - return true -} - -func (i *Console) Start() { - fmt.Printf("Eth Console. Type (help) for help\n") - reader := bufio.NewReader(os.Stdin) - for { - fmt.Printf("eth >>> ") - str, _, err := reader.ReadLine() - if err != nil { - fmt.Println("Error reading input", err) - } else { - if !i.ParseInput(string(str)) { - return - } - } - } -} diff --git a/ethereum/ethereum.go b/ethereum/ethereum.go index f680b5416..2fdfd5caf 100644 --- a/ethereum/ethereum.go +++ b/ethereum/ethereum.go @@ -141,16 +141,7 @@ save these words so you can restore your account later: %s utils.DoMining(ethereum) } - if StartConsole { - err := os.Mkdir(ethutil.Config.ExecPath, os.ModePerm) - // Error is OK if the error is ErrExist - if err != nil && !os.IsExist(err) { - log.Panic("Unable to create EXECPATH:", err) - } - - console := NewConsole(ethereum) - go console.Start() - } else if StartJsConsole { + if StartJsConsole { repl := NewJSRepl(ethereum) go repl.Start() -- cgit v1.2.3