diff options
Diffstat (limited to 'cmd/ethereum')
-rw-r--r-- | cmd/ethereum/admin.go | 259 | ||||
-rw-r--r-- | cmd/ethereum/js.go | 168 | ||||
-rw-r--r-- | cmd/ethereum/js_test.go | 252 | ||||
-rw-r--r-- | cmd/ethereum/main.go | 56 |
4 files changed, 602 insertions, 133 deletions
diff --git a/cmd/ethereum/admin.go b/cmd/ethereum/admin.go new file mode 100644 index 000000000..967af2553 --- /dev/null +++ b/cmd/ethereum/admin.go @@ -0,0 +1,259 @@ +package main + +import ( + "fmt" + "net" + "net/http" + "os" + "time" + + "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/rlp" + "github.com/ethereum/go-ethereum/rpc" + "github.com/ethereum/go-ethereum/state" + "github.com/ethereum/go-ethereum/xeth" + "github.com/obscuren/otto" +) + +/* +node admin bindings +*/ + +func (js *jsre) adminBindings() { + js.re.Set("admin", struct{}{}) + t, _ := js.re.Get("admin") + admin := t.Object() + admin.Set("suggestPeer", js.suggestPeer) + admin.Set("startRPC", js.startRPC) + admin.Set("startMining", js.startMining) + admin.Set("stopMining", js.stopMining) + admin.Set("nodeInfo", js.nodeInfo) + admin.Set("peers", js.peers) + admin.Set("newAccount", js.newAccount) + admin.Set("unlock", js.unlock) + admin.Set("import", js.importChain) + admin.Set("export", js.exportChain) + admin.Set("dumpBlock", js.dumpBlock) +} + +func (js *jsre) startMining(call otto.FunctionCall) otto.Value { + _, err := call.Argument(0).ToInteger() + if err != nil { + fmt.Println(err) + return otto.FalseValue() + } + // threads now ignored + err = js.ethereum.StartMining() + if err != nil { + fmt.Println(err) + return otto.FalseValue() + } + return otto.TrueValue() +} + +func (js *jsre) stopMining(call otto.FunctionCall) otto.Value { + js.ethereum.StopMining() + return otto.TrueValue() +} + +func (js *jsre) startRPC(call otto.FunctionCall) otto.Value { + addr, err := call.Argument(0).ToString() + if err != nil { + fmt.Println(err) + return otto.FalseValue() + } + port, err := call.Argument(1).ToInteger() + if err != nil { + fmt.Println(err) + return otto.FalseValue() + } + dataDir := js.ethereum.DataDir + + l, err := net.Listen("tcp", fmt.Sprintf("%s:%d", addr, port)) + if err != nil { + fmt.Printf("Can't listen on %s:%d: %v", addr, port, err) + return otto.FalseValue() + } + go http.Serve(l, rpc.JSONRPC(xeth.New(js.ethereum, nil), dataDir)) + return otto.TrueValue() +} + +func (js *jsre) suggestPeer(call otto.FunctionCall) otto.Value { + nodeURL, err := call.Argument(0).ToString() + if err != nil { + fmt.Println(err) + return otto.FalseValue() + } + err = js.ethereum.SuggestPeer(nodeURL) + if err != nil { + fmt.Println(err) + return otto.FalseValue() + } + return otto.TrueValue() +} + +func (js *jsre) unlock(call otto.FunctionCall) otto.Value { + addr, err := call.Argument(0).ToString() + if err != nil { + fmt.Println(err) + return otto.FalseValue() + } + seconds, err := call.Argument(2).ToInteger() + if err != nil { + fmt.Println(err) + return otto.FalseValue() + } + arg := call.Argument(1) + var passphrase string + if arg.IsUndefined() { + fmt.Println("Please enter a passphrase now.") + passphrase, err = readPassword("Passphrase: ", true) + if err != nil { + utils.Fatalf("%v", err) + } + } else { + passphrase, err = arg.ToString() + if err != nil { + fmt.Println(err) + return otto.FalseValue() + } + } + am := js.ethereum.AccountManager() + // err := am.Unlock(common.FromHex(split[0]), split[1]) + // if err != nil { + // utils.Fatalf("Unlock account failed '%v'", err) + // } + err = am.TimedUnlock(common.FromHex(addr), passphrase, time.Duration(seconds)*time.Second) + if err != nil { + fmt.Printf("Unlock account failed '%v'\n", err) + return otto.FalseValue() + } + return otto.TrueValue() +} + +func (js *jsre) newAccount(call otto.FunctionCall) otto.Value { + arg := call.Argument(0) + var passphrase string + if arg.IsUndefined() { + fmt.Println("The new account will be encrypted with a passphrase.") + fmt.Println("Please enter a passphrase now.") + auth, err := readPassword("Passphrase: ", true) + if err != nil { + utils.Fatalf("%v", err) + } + confirm, err := readPassword("Repeat Passphrase: ", false) + if err != nil { + utils.Fatalf("%v", err) + } + if auth != confirm { + utils.Fatalf("Passphrases did not match.") + } + passphrase = auth + } else { + var err error + passphrase, err = arg.ToString() + if err != nil { + fmt.Println(err) + return otto.FalseValue() + } + } + acct, err := js.ethereum.AccountManager().NewAccount(passphrase) + if err != nil { + fmt.Printf("Could not create the account: %v", err) + return otto.UndefinedValue() + } + return js.re.ToVal(common.Bytes2Hex(acct.Address)) +} + +func (js *jsre) nodeInfo(call otto.FunctionCall) otto.Value { + return js.re.ToVal(js.ethereum.NodeInfo()) +} + +func (js *jsre) peers(call otto.FunctionCall) otto.Value { + return js.re.ToVal(js.ethereum.PeersInfo()) +} + +func (js *jsre) importChain(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() + } + + var fh *os.File + fh, err = os.OpenFile(fn, os.O_RDONLY, os.ModePerm) + if err != nil { + fmt.Println(err) + return otto.FalseValue() + } + defer fh.Close() + + var blocks types.Blocks + if err = rlp.Decode(fh, &blocks); err != nil { + fmt.Println(err) + return otto.FalseValue() + } + + js.ethereum.ChainManager().Reset() + if err = js.ethereum.ChainManager().InsertChain(blocks); err != nil { + fmt.Println(err) + return otto.FalseValue() + } + + return otto.TrueValue() +} + +func (js *jsre) exportChain(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 := js.ethereum.ChainManager().Export() + if err := common.WriteFile(fn, data); err != nil { + fmt.Println(err) + return otto.FalseValue() + } + + return otto.TrueValue() +} + +func (js *jsre) dumpBlock(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 = js.ethereum.ChainManager().GetBlockByNumber(uint64(num)) + } else if call.Argument(0).IsString() { + hash, _ := call.Argument(0).ToString() + block = js.ethereum.ChainManager().GetBlock(common.HexToHash(hash)) + } else { + fmt.Println("invalid argument for dump. Either hex string or number") + } + + } else { + block = js.ethereum.ChainManager().CurrentBlock() + } + if block == nil { + fmt.Println("block not found") + return otto.UndefinedValue() + } + + statedb := state.New(block.Root(), js.ethereum.StateDb()) + dump := statedb.RawDump() + return js.re.ToVal(dump) + +} diff --git a/cmd/ethereum/js.go b/cmd/ethereum/js.go index a3c5f5d2d..b4b54b7e6 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/common" - "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,12 @@ 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() + js.adminBindings() if !liner.TerminalSupported() { js.prompter = dumbterm{bufio.NewReader(os.Stdin)} @@ -89,6 +88,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 +153,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 +227,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(common.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 := common.WriteFile(fn, data); err != nil { - fmt.Println(err) - return otto.FalseValue() + fmt.Printf("%v", val) } - - return otto.TrueValue() } diff --git a/cmd/ethereum/js_test.go b/cmd/ethereum/js_test.go new file mode 100644 index 000000000..0d3c22553 --- /dev/null +++ b/cmd/ethereum/js_test.go @@ -0,0 +1,252 @@ +package main + +import ( + "fmt" + "github.com/obscuren/otto" + "os" + "path" + "testing" + + "github.com/ethereum/go-ethereum/accounts" + "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/crypto" + "github.com/ethereum/go-ethereum/eth" +) + +var port = 30300 + +func testJEthRE(t *testing.T) (repl *jsre, ethereum *eth.Ethereum, err error) { + os.RemoveAll("/tmp/eth/") + err = os.MkdirAll("/tmp/eth/keys/e273f01c99144c438695e10f24926dc1f9fbf62d/", os.ModePerm) + if err != nil { + t.Errorf("%v", err) + return + } + err = os.MkdirAll("/tmp/eth/data", os.ModePerm) + if err != nil { + t.Errorf("%v", err) + return + } + // FIXME: this does not work ATM + ks := crypto.NewKeyStorePlain("/tmp/eth/keys") + common.WriteFile("/tmp/eth/keys/e273f01c99144c438695e10f24926dc1f9fbf62d/e273f01c99144c438695e10f24926dc1f9fbf62d", + []byte(`{"Id":"RhRXD+fNRKS4jx+7ZfEsNA==","Address":"4nPwHJkUTEOGleEPJJJtwfn79i0=","PrivateKey":"h4ACVpe74uIvi5Cg/2tX/Yrm2xdr3J7QoMbMtNX2CNc="}`)) + + port++ + ethereum, err = eth.New(ð.Config{ + DataDir: "/tmp/eth", + AccountManager: accounts.NewManager(ks), + Port: fmt.Sprintf("%d", port), + MaxPeers: 10, + Name: "test", + }) + + if err != nil { + t.Errorf("%v", err) + return + } + assetPath := path.Join(os.Getenv("GOPATH"), "src", "github.com", "ethereum", "go-ethereum", "cmd", "mist", "assets", "ext") + repl = newJSRE(ethereum, assetPath) + return +} + +func TestNodeInfo(t *testing.T) { + repl, ethereum, err := testJEthRE(t) + if err != nil { + t.Errorf("error creating jsre, got %v", err) + return + } + err = ethereum.Start() + if err != nil { + t.Errorf("error starting ethereum: %v", err) + return + } + defer ethereum.Stop() + + val, err := repl.re.Run("admin.nodeInfo()") + if err != nil { + t.Errorf("expected no error, got %v", err) + } + exp, err := val.Export() + if err != nil { + t.Errorf("expected no error, got %v", err) + } + nodeInfo, ok := exp.(*eth.NodeInfo) + if !ok { + t.Errorf("expected nodeInfo, got %v", err) + } + exp = "test" + got := nodeInfo.Name + if exp != got { + t.Errorf("expected %v, got %v", exp, got) + } + exp = 30301 + port := nodeInfo.DiscPort + if exp != port { + t.Errorf("expected %v, got %v", exp, port) + } + exp = 30301 + port = nodeInfo.TCPPort + if exp != port { + t.Errorf("expected %v, got %v", exp, port) + } +} + +func TestAccounts(t *testing.T) { + repl, ethereum, err := testJEthRE(t) + if err != nil { + t.Errorf("error creating jsre, got %v", err) + return + } + err = ethereum.Start() + if err != nil { + t.Errorf("error starting ethereum: %v", err) + return + } + defer ethereum.Stop() + + val, err := repl.re.Run("eth.coinbase") + if err != nil { + t.Errorf("expected no error, got %v", err) + } + + pp, err := repl.re.PrettyPrint(val) + if err != nil { + t.Errorf("%v", err) + } + + if !val.IsString() { + t.Errorf("incorrect type, expected string, got %v: %v", val, pp) + } + strVal, _ := val.ToString() + expected := "0xe273f01c99144c438695e10f24926dc1f9fbf62d" + if strVal != expected { + t.Errorf("incorrect result, expected %s, got %v", expected, strVal) + } + + val, err = repl.re.Run(`admin.newAccount("password")`) + if err != nil { + t.Errorf("expected no error, got %v", err) + } + addr, err := val.ToString() + if err != nil { + t.Errorf("expected string, got %v", err) + } + + val, err = repl.re.Run("eth.accounts") + if err != nil { + t.Errorf("expected no error, got %v", err) + } + exp, err := val.Export() + if err != nil { + t.Errorf("expected no error, got %v", err) + } + addrs, ok := exp.([]string) + if !ok { + t.Errorf("expected []string, got %v", err) + } + if len(addrs) != 2 || (addr != addrs[0][2:] && addr != addrs[1][2:]) { + t.Errorf("expected addrs == [<default>, <new>], got %v (%v)", addrs, addr) + } + +} + +func TestBlockChain(t *testing.T) { + repl, ethereum, err := testJEthRE(t) + if err != nil { + t.Errorf("error creating jsre, got %v", err) + return + } + err = ethereum.Start() + if err != nil { + t.Errorf("error starting ethereum: %v", err) + return + } + defer ethereum.Stop() + + // should get current block + val0, err := repl.re.Run("admin.dumpBlock()") + if err != nil { + t.Errorf("expected no error, got %v", err) + } + + fn := "/tmp/eth/data/blockchain.0" + _, err = repl.re.Run("admin.export(\"" + fn + "\")") + if err != nil { + t.Errorf("expected no error, got %v", err) + } + if _, err = os.Stat(fn); err != nil { + t.Errorf("expected no error on file, got %v", err) + } + + _, err = repl.re.Run("admin.import(\"" + fn + "\")") + if err != nil { + t.Errorf("expected no error, got %v", err) + } + + var val1 otto.Value + + // should get current block + val1, err = repl.re.Run("admin.dumpBlock()") + if err != nil { + t.Errorf("expected no error, got %v", err) + } + + // FIXME: neither != , nor reflect.DeepEqual works, doing string comparison + v0 := fmt.Sprintf("%v", val0) + v1 := fmt.Sprintf("%v", val1) + if v0 != v1 { + t.Errorf("expected same head after export-import, got %v (!=%v)", v1, v0) + } +} + +func TestMining(t *testing.T) { + repl, ethereum, err := testJEthRE(t) + if err != nil { + t.Errorf("error creating jsre, got %v", err) + return + } + err = ethereum.Start() + if err != nil { + t.Errorf("error starting ethereum: %v", err) + return + } + defer ethereum.Stop() + + val, err := repl.re.Run("eth.mining") + if err != nil { + t.Errorf("expected no error, got %v", err) + } + var mining bool + mining, err = val.ToBoolean() + if err != nil { + t.Errorf("expected boolean, got %v", err) + } + if mining { + t.Errorf("expected false (not mining), got true") + } + +} + +func TestRPC(t *testing.T) { + repl, ethereum, err := testJEthRE(t) + if err != nil { + t.Errorf("error creating jsre, got %v", err) + return + } + err = ethereum.Start() + if err != nil { + t.Errorf("error starting ethereum: %v", err) + return + } + defer ethereum.Stop() + + val, err := repl.re.Run(`admin.startRPC("127.0.0.1", 5004)`) + if err != nil { + t.Errorf("expected no error, got %v", err) + } + success, _ := val.ToBoolean() + if !success { + t.Errorf("expected true (started), got false") + } +} diff --git a/cmd/ethereum/main.go b/cmd/ethereum/main.go index 1efea927f..459059e6c 100644 --- a/cmd/ethereum/main.go +++ b/cmd/ethereum/main.go @@ -31,9 +31,9 @@ import ( "github.com/codegangsta/cli" "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/eth" - "github.com/ethereum/go-ethereum/common" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/state" "github.com/peterh/liner" @@ -41,7 +41,7 @@ import ( const ( ClientIdentifier = "Ethereum(G)" - Version = "0.9.0" + Version = "0.9.1" ) var ( @@ -89,16 +89,20 @@ Use "ethereum dump 0" to dump the genesis block. `, }, { - Action: runjs, + Action: console, + Name: "console", + Usage: `Ethereum Console: interactive JavaScript environment`, + Description: ` +Console is an interactive shell for the Ethereum 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 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() } @@ -284,7 +302,7 @@ func dump(ctx *cli.Context) { for _, arg := range ctx.Args() { var block *types.Block if hashish(arg) { - block = chainmgr.GetBlock(common.Hex2Bytes(arg)) + block = chainmgr.GetBlock(common.HexToHash(arg)) } else { num, _ := strconv.Atoi(arg) block = chainmgr.GetBlockByNumber(uint64(num)) |