aboutsummaryrefslogtreecommitdiffstats
path: root/cmd
diff options
context:
space:
mode:
authorobscuren <geffobscura@gmail.com>2015-03-10 08:22:38 +0800
committerobscuren <geffobscura@gmail.com>2015-03-10 08:22:38 +0800
commit0db4a0e898d09ffa7b6b1289e9a334edc0001cfa (patch)
treea0b5c8381ab482550ef4800a06d4db086d76a983 /cmd
parent94e543bc398efbb5c712b6e4cb48d8a57eb3400d (diff)
parent0d64163fea3a266ceb71cb4c4ee5682052c9ca6c (diff)
downloadgo-tangerine-0db4a0e898d09ffa7b6b1289e9a334edc0001cfa.tar
go-tangerine-0db4a0e898d09ffa7b6b1289e9a334edc0001cfa.tar.gz
go-tangerine-0db4a0e898d09ffa7b6b1289e9a334edc0001cfa.tar.bz2
go-tangerine-0db4a0e898d09ffa7b6b1289e9a334edc0001cfa.tar.lz
go-tangerine-0db4a0e898d09ffa7b6b1289e9a334edc0001cfa.tar.xz
go-tangerine-0db4a0e898d09ffa7b6b1289e9a334edc0001cfa.tar.zst
go-tangerine-0db4a0e898d09ffa7b6b1289e9a334edc0001cfa.zip
Merge branch 'poc-9' into develop
Diffstat (limited to 'cmd')
-rw-r--r--cmd/blocktest/flags.go41
-rw-r--r--cmd/blocktest/main.go320
-rw-r--r--cmd/ethereum/cmd.go55
-rw-r--r--cmd/ethereum/flags.go168
-rw-r--r--cmd/ethereum/js.go280
-rw-r--r--cmd/ethereum/main.go235
-rw-r--r--cmd/ethereum/repl/console_colors_windows.go97
-rw-r--r--cmd/ethereum/repl/repl.go103
-rw-r--r--cmd/ethereum/repl/repl_darwin.go144
l---------cmd/ethereum/repl/repl_linux.go1
-rw-r--r--cmd/ethereum/repl/repl_windows.go92
-rw-r--r--cmd/evm/main.go1
-rw-r--r--cmd/mist/assets/ext/ethereum.js/dist/ethereum.js843
-rw-r--r--cmd/mist/assets/qml/main.qml2
-rw-r--r--cmd/mist/bindings.go6
-rw-r--r--cmd/mist/ext_app.go117
-rw-r--r--cmd/mist/gui.go6
-rw-r--r--cmd/mist/main.go2
-rw-r--r--cmd/mist/ui_lib.go21
-rw-r--r--cmd/utils/cmd.go68
-rw-r--r--cmd/utils/flags.go190
21 files changed, 1670 insertions, 1122 deletions
diff --git a/cmd/blocktest/flags.go b/cmd/blocktest/flags.go
new file mode 100644
index 000000000..c811e5b85
--- /dev/null
+++ b/cmd/blocktest/flags.go
@@ -0,0 +1,41 @@
+/*
+ This file is part of go-ethereum
+
+ go-ethereum is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ go-ethereum is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * @authors
+ * Gustav Simonsson <gustav.simonsson@gmail.com>
+ */
+package main
+
+import (
+ "flag"
+ "fmt"
+ "os"
+)
+
+var (
+ TestFile string
+)
+
+func Init() {
+ flag.Usage = func() {
+ fmt.Fprintf(os.Stderr, "%s <testfile>\n", os.Args[0])
+ flag.PrintDefaults()
+ }
+ flag.Parse()
+
+ TestFile = flag.Arg(0)
+}
diff --git a/cmd/blocktest/main.go b/cmd/blocktest/main.go
new file mode 100644
index 000000000..4a05b8bee
--- /dev/null
+++ b/cmd/blocktest/main.go
@@ -0,0 +1,320 @@
+/*
+ This file is part of go-ethereum
+
+ go-ethereum is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ go-ethereum is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
+*/
+/**
+ * @authors
+ * Gustav Simonsson <gustav.simonsson@gmail.com>
+ * @date 2015
+ *
+ */
+
+package main
+
+import (
+ "bytes"
+ "crypto/ecdsa"
+ "encoding/hex"
+ "encoding/json"
+ "fmt"
+ "io/ioutil"
+ "log"
+ "math/big"
+ "path"
+ "runtime"
+ "strconv"
+ "strings"
+ "time"
+
+ "github.com/ethereum/go-ethereum/cmd/utils"
+ types "github.com/ethereum/go-ethereum/core/types"
+ "github.com/ethereum/go-ethereum/eth"
+ "github.com/ethereum/go-ethereum/ethutil"
+ "github.com/ethereum/go-ethereum/logger"
+ "github.com/ethereum/go-ethereum/p2p"
+ "github.com/ethereum/go-ethereum/p2p/nat"
+ "github.com/ethereum/go-ethereum/rlp"
+)
+
+const (
+ ClientIdentifier = "Ethereum(G)"
+ Version = "0.8.6"
+)
+
+type Account struct {
+ Balance string
+ Code string
+ Nonce string
+ Storage map[string]string
+}
+
+type BlockHeader struct {
+ Bloom string
+ Coinbase string
+ Difficulty string
+ ExtraData string
+ GasLimit string
+ GasUsed string
+ MixHash string
+ Nonce string
+ Number string
+ ParentHash string
+ ReceiptTrie string
+ SeedHash string
+ StateRoot string
+ Timestamp string
+ TransactionsTrie string
+ UncleHash string
+}
+type Tx struct {
+ Data string
+ GasLimit string
+ GasPrice string
+ Nonce string
+ R string
+ S string
+ To string
+ V string
+ Value string
+}
+
+type Block struct {
+ BlockHeader BlockHeader
+ Rlp string
+ Transactions []Tx
+ UncleHeaders []string
+}
+
+type Test struct {
+ Blocks []Block
+ GenesisBlockHeader BlockHeader
+ Pre map[string]Account
+}
+
+var (
+ Identifier string
+ KeyRing string
+ DiffTool bool
+ DiffType string
+ KeyStore string
+ StartRpc bool
+ StartWebSockets bool
+ RpcListenAddress string
+ RpcPort int
+ WsPort int
+ OutboundPort string
+ ShowGenesis bool
+ AddPeer string
+ MaxPeer int
+ GenAddr bool
+ BootNodes string
+ NodeKey *ecdsa.PrivateKey
+ NAT nat.Interface
+ SecretFile string
+ ExportDir string
+ NonInteractive bool
+ Datadir string
+ LogFile string
+ ConfigFile string
+ DebugFile string
+ LogLevel int
+ LogFormat string
+ Dump bool
+ DumpHash string
+ DumpNumber int
+ VmType int
+ ImportChain string
+ SHH bool
+ Dial bool
+ PrintVersion bool
+ MinerThreads int
+)
+
+// flags specific to cli client
+var (
+ StartMining bool
+ StartJsConsole bool
+ InputFile string
+)
+
+func main() {
+ init_vars()
+
+ Init()
+
+ if len(TestFile) < 1 {
+ log.Fatal("Please specify test file")
+ }
+ blocks, err := loadBlocksFromTestFile(TestFile)
+ if err != nil {
+ panic(err)
+ }
+
+ runtime.GOMAXPROCS(runtime.NumCPU())
+
+ defer func() {
+ logger.Flush()
+ }()
+
+ utils.HandleInterrupt()
+
+ utils.InitConfig(VmType, ConfigFile, Datadir, "ethblocktest")
+
+ ethereum, err := eth.New(&eth.Config{
+ Name: p2p.MakeName(ClientIdentifier, Version),
+ KeyStore: KeyStore,
+ DataDir: Datadir,
+ LogFile: LogFile,
+ LogLevel: LogLevel,
+ LogFormat: LogFormat,
+ MaxPeers: MaxPeer,
+ Port: OutboundPort,
+ NAT: NAT,
+ KeyRing: KeyRing,
+ Shh: true,
+ Dial: Dial,
+ BootNodes: BootNodes,
+ NodeKey: NodeKey,
+ MinerThreads: MinerThreads,
+ })
+
+ utils.StartRpc(ethereum, RpcListenAddress, RpcPort)
+ utils.StartEthereum(ethereum)
+
+ ethereum.ChainManager().ResetWithGenesisBlock(blocks[0])
+
+ // fmt.Println("HURR: ", hex.EncodeToString(ethutil.Encode(blocks[0].RlpData())))
+
+ go ethereum.ChainManager().InsertChain(types.Blocks{blocks[1]})
+ fmt.Println("OK! ")
+ ethereum.WaitForShutdown()
+}
+
+func loadBlocksFromTestFile(filePath string) (blocks types.Blocks, err error) {
+ fileContent, err := ioutil.ReadFile(filePath)
+ if err != nil {
+ return
+ }
+ bt := *new(map[string]Test)
+ err = json.Unmarshal(fileContent, &bt)
+ if err != nil {
+ return
+ }
+
+ // TODO: support multiple blocks; loop over all blocks
+ gbh := new(types.Header)
+
+ // Let's use slighlty different namings for the same things, because that's awesome.
+ gbh.ParentHash, err = hex_decode(bt["SimpleTx"].GenesisBlockHeader.ParentHash)
+ gbh.UncleHash, err = hex_decode(bt["SimpleTx"].GenesisBlockHeader.UncleHash)
+ gbh.Coinbase, err = hex_decode(bt["SimpleTx"].GenesisBlockHeader.Coinbase)
+ gbh.Root, err = hex_decode(bt["SimpleTx"].GenesisBlockHeader.StateRoot)
+ gbh.TxHash, err = hex_decode(bt["SimpleTx"].GenesisBlockHeader.TransactionsTrie)
+ gbh.ReceiptHash, err = hex_decode(bt["SimpleTx"].GenesisBlockHeader.ReceiptTrie)
+ gbh.Bloom, err = hex_decode(bt["SimpleTx"].GenesisBlockHeader.Bloom)
+
+ gbh.MixDigest, err = hex_decode(bt["SimpleTx"].GenesisBlockHeader.MixHash)
+ gbh.SeedHash, err = hex_decode(bt["SimpleTx"].GenesisBlockHeader.SeedHash)
+
+ d, _ := new(big.Int).SetString(bt["SimpleTx"].GenesisBlockHeader.Difficulty, 10)
+ gbh.Difficulty = d
+
+ n, _ := new(big.Int).SetString(bt["SimpleTx"].GenesisBlockHeader.Number, 10)
+ gbh.Number = n
+
+ gl, _ := new(big.Int).SetString(bt["SimpleTx"].GenesisBlockHeader.GasLimit, 10)
+ gbh.GasLimit = gl
+
+ gu, _ := new(big.Int).SetString(bt["SimpleTx"].GenesisBlockHeader.GasUsed, 10)
+ gbh.GasUsed = gu
+
+ ts, _ := new(big.Int).SetString(bt["SimpleTx"].GenesisBlockHeader.Timestamp, 0)
+ gbh.Time = ts.Uint64()
+
+ extra, err := hex_decode(bt["SimpleTx"].GenesisBlockHeader.ExtraData)
+ gbh.Extra = string(extra) // TODO: change ExtraData to byte array
+
+ nonce, _ := hex_decode(bt["SimpleTx"].GenesisBlockHeader.Nonce)
+ gbh.Nonce = nonce
+
+ if err != nil {
+ return
+ }
+
+ gb := types.NewBlockWithHeader(gbh)
+ gb.Reward = new(big.Int)
+
+ testBlock := new(types.Block)
+
+ rlpBytes, err := hex_decode(bt["SimpleTx"].Blocks[0].Rlp)
+ err = rlp.Decode(bytes.NewReader(rlpBytes), &testBlock)
+ if err != nil {
+ return
+ }
+
+ blocks = types.Blocks{
+ gb,
+ testBlock,
+ }
+
+ return
+}
+
+func init_vars() {
+ VmType = 0
+ Identifier = ""
+ KeyRing = ""
+ KeyStore = "db"
+ RpcListenAddress = "127.0.0.1"
+ RpcPort = 8545
+ WsPort = 40404
+ StartRpc = true
+ StartWebSockets = false
+ NonInteractive = false
+ GenAddr = false
+ SecretFile = ""
+ ExportDir = ""
+ LogFile = ""
+
+ timeStr := strconv.FormatInt(time.Now().UnixNano(), 10)
+
+ Datadir = path.Join(ethutil.DefaultDataDir(), timeStr)
+ ConfigFile = path.Join(ethutil.DefaultDataDir(), timeStr, "conf.ini")
+
+ DebugFile = ""
+ LogLevel = 5
+ LogFormat = "std"
+ DiffTool = false
+ DiffType = "all"
+ ShowGenesis = false
+ ImportChain = ""
+ Dump = false
+ DumpHash = ""
+ DumpNumber = -1
+ StartMining = false
+ StartJsConsole = false
+ PrintVersion = false
+ MinerThreads = runtime.NumCPU()
+
+ Dial = false
+ OutboundPort = "30303"
+ BootNodes = ""
+ MaxPeer = 1
+
+}
+
+func hex_decode(s string) (res []byte, err error) {
+ return hex.DecodeString(strings.TrimPrefix(s, "0x"))
+}
diff --git a/cmd/ethereum/cmd.go b/cmd/ethereum/cmd.go
deleted file mode 100644
index 8ffd868ed..000000000
--- a/cmd/ethereum/cmd.go
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- This file is part of go-ethereum
-
- go-ethereum is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- go-ethereum is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * @authors
- * Jeffrey Wilcke <i@jev.io>
- */
-package main
-
-import (
- "io/ioutil"
- "os"
-
- "github.com/ethereum/go-ethereum/cmd/ethereum/repl"
- "github.com/ethereum/go-ethereum/cmd/utils"
- "github.com/ethereum/go-ethereum/eth"
- "github.com/ethereum/go-ethereum/javascript"
-)
-
-func InitJsConsole(ethereum *eth.Ethereum) {
- repl := ethrepl.NewJSRepl(ethereum)
- go repl.Start()
- utils.RegisterInterrupt(func(os.Signal) {
- repl.Stop()
- })
-}
-
-func ExecJsFile(ethereum *eth.Ethereum, InputFile string) {
- file, err := os.Open(InputFile)
- if err != nil {
- clilogger.Fatalln(err)
- }
- content, err := ioutil.ReadAll(file)
- if err != nil {
- clilogger.Fatalln(err)
- }
- re := javascript.NewJSRE(ethereum)
- utils.RegisterInterrupt(func(os.Signal) {
- re.Stop()
- })
- re.Run(string(content))
-}
diff --git a/cmd/ethereum/flags.go b/cmd/ethereum/flags.go
deleted file mode 100644
index a3004f503..000000000
--- a/cmd/ethereum/flags.go
+++ /dev/null
@@ -1,168 +0,0 @@
-/*
- This file is part of go-ethereum
-
- go-ethereum is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- go-ethereum is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * @authors
- * Jeffrey Wilcke <i@jev.io>
- */
-package main
-
-import (
- "crypto/ecdsa"
- "flag"
- "fmt"
- "log"
- "os"
- "path"
- "runtime"
-
- "github.com/ethereum/go-ethereum/crypto"
- "github.com/ethereum/go-ethereum/ethutil"
- "github.com/ethereum/go-ethereum/logger"
- "github.com/ethereum/go-ethereum/p2p/nat"
- "github.com/ethereum/go-ethereum/vm"
-)
-
-var (
- Identifier string
- KeyRing string
- DiffTool bool
- DiffType string
- KeyStore string
- StartRpc bool
- StartWebSockets bool
- RpcListenAddress string
- RpcPort int
- OutboundPort string
- ShowGenesis bool
- AddPeer string
- MaxPeer int
- GenAddr bool
- BootNodes string
- NodeKey *ecdsa.PrivateKey
- NAT nat.Interface
- SecretFile string
- ExportDir string
- NonInteractive bool
- Datadir string
- LogFile string
- ConfigFile string
- DebugFile string
- LogLevel int
- LogFormat string
- Dump bool
- DumpHash string
- DumpNumber int
- VmType int
- ImportChain string
- SHH bool
- Dial bool
- PrintVersion bool
- MinerThreads int
-)
-
-// flags specific to cli client
-var (
- StartMining bool
- StartJsConsole bool
- InputFile string
-)
-
-var defaultConfigFile = path.Join(ethutil.DefaultDataDir(), "conf.ini")
-
-func Init() {
- // TODO: move common flag processing to cmd/util
- flag.Usage = func() {
- fmt.Fprintf(os.Stderr, "%s [options] [filename]:\noptions precedence: default < config file < environment variables < command line\n", os.Args[0])
- flag.PrintDefaults()
- }
-
- flag.IntVar(&VmType, "vm", 0, "Virtual Machine type: 0-1: standard, debug")
- flag.StringVar(&Identifier, "id", "", "Custom client identifier")
- flag.StringVar(&KeyRing, "keyring", "", "identifier for keyring to use")
- flag.StringVar(&KeyStore, "keystore", "db", "system to store keyrings: db|file")
-
- flag.StringVar(&RpcListenAddress, "rpcaddr", "127.0.0.1", "address for json-rpc server to listen on")
- flag.IntVar(&RpcPort, "rpcport", 8545, "port to start json-rpc server on")
- flag.BoolVar(&StartRpc, "rpc", false, "start rpc server")
- flag.BoolVar(&NonInteractive, "y", false, "non-interactive mode (say yes to confirmations)")
- flag.BoolVar(&GenAddr, "genaddr", false, "create a new priv/pub key")
- flag.StringVar(&SecretFile, "import", "", "imports the file given (hex or mnemonic formats)")
- flag.StringVar(&ExportDir, "export", "", "exports the session keyring to files in the directory given")
- flag.StringVar(&LogFile, "logfile", "", "log file (defaults to standard output)")
- flag.StringVar(&Datadir, "datadir", ethutil.DefaultDataDir(), "specifies the datadir to use")
- flag.StringVar(&ConfigFile, "conf", defaultConfigFile, "config file")
- flag.StringVar(&DebugFile, "debug", "", "debug file (no debugging if not set)")
- flag.IntVar(&LogLevel, "loglevel", int(logger.InfoLevel), "loglevel: 0-5 (= silent,error,warn,info,debug,debug detail)")
- flag.StringVar(&LogFormat, "logformat", "std", "logformat: std,raw")
- flag.BoolVar(&DiffTool, "difftool", false, "creates output for diff'ing. Sets LogLevel=0")
- flag.StringVar(&DiffType, "diff", "all", "sets the level of diff output [vm, all]. Has no effect if difftool=false")
- flag.BoolVar(&ShowGenesis, "genesis", false, "Dump the genesis block")
- flag.StringVar(&ImportChain, "chain", "", "Imports given chain")
-
- flag.BoolVar(&Dump, "dump", false, "output the ethereum state in JSON format. Sub args [number, hash]")
- flag.StringVar(&DumpHash, "hash", "", "specify arg in hex")
- flag.IntVar(&DumpNumber, "number", -1, "specify arg in number")
-
- flag.BoolVar(&StartMining, "mine", false, "start mining")
- flag.BoolVar(&StartJsConsole, "js", false, "launches javascript console")
- flag.BoolVar(&PrintVersion, "version", false, "prints version number")
- flag.IntVar(&MinerThreads, "minerthreads", runtime.NumCPU(), "number of miner threads")
-
- // Network stuff
- var (
- nodeKeyFile = flag.String("nodekey", "", "network private key file")
- nodeKeyHex = flag.String("nodekeyhex", "", "network private key (for testing)")
- natstr = flag.String("nat", "any", "port mapping mechanism (any|none|upnp|pmp|extip:<IP>)")
- )
- flag.BoolVar(&Dial, "dial", true, "dial out connections (default on)")
- //flag.BoolVar(&SHH, "shh", true, "run whisper protocol (default on)")
- flag.StringVar(&OutboundPort, "port", "30303", "listening port")
-
- flag.StringVar(&BootNodes, "bootnodes", "", "space-separated node URLs for discovery bootstrap")
- flag.IntVar(&MaxPeer, "maxpeer", 30, "maximum desired peers")
-
- flag.Parse()
-
- // When the javascript console is started log to a file instead
- // of stdout
- if StartJsConsole {
- LogFile = path.Join(Datadir, "ethereum.log")
- }
-
- var err error
- if NAT, err = nat.Parse(*natstr); err != nil {
- log.Fatalf("-nat: %v", err)
- }
- switch {
- case *nodeKeyFile != "" && *nodeKeyHex != "":
- log.Fatal("Options -nodekey and -nodekeyhex are mutually exclusive")
- case *nodeKeyFile != "":
- if NodeKey, err = crypto.LoadECDSA(*nodeKeyFile); err != nil {
- log.Fatalf("-nodekey: %v", err)
- }
- case *nodeKeyHex != "":
- if NodeKey, err = crypto.HexToECDSA(*nodeKeyHex); err != nil {
- log.Fatalf("-nodekeyhex: %v", err)
- }
- }
-
- if VmType >= int(vm.MaxVmTy) {
- log.Fatal("Invalid VM type ", VmType)
- }
-
- InputFile = flag.Arg(0)
-}
diff --git a/cmd/ethereum/js.go b/cmd/ethereum/js.go
new file mode 100644
index 000000000..e3165d3f5
--- /dev/null
+++ b/cmd/ethereum/js.go
@@ -0,0 +1,280 @@
+// Copyright (c) 2013-2014, Jeffrey Wilcke. All rights reserved.
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+// General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this library; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
+// MA 02110-1301 USA
+
+package main
+
+import (
+ "bufio"
+ "fmt"
+ "io/ioutil"
+ "os"
+ "os/signal"
+ "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"
+ "github.com/ethereum/go-ethereum/xeth"
+ "github.com/obscuren/otto"
+ "github.com/peterh/liner"
+)
+
+func execJsFile(ethereum *eth.Ethereum, filename string) {
+ file, err := os.Open(filename)
+ if err != nil {
+ utils.Fatalf("%v", err)
+ }
+ content, err := ioutil.ReadAll(file)
+ if err != nil {
+ utils.Fatalf("%v", err)
+ }
+ re := javascript.NewJSRE(xeth.New(ethereum, nil))
+ if _, err := re.Run(string(content)); err != nil {
+ utils.Fatalf("Javascript Error: %v", err)
+ }
+}
+
+type repl struct {
+ re *javascript.JSRE
+ ethereum *eth.Ethereum
+ xeth *xeth.XEth
+ prompt string
+ lr *liner.State
+}
+
+func runREPL(ethereum *eth.Ethereum) {
+ xeth := xeth.New(ethereum, nil)
+ repl := &repl{
+ re: javascript.NewJSRE(xeth),
+ xeth: xeth,
+ ethereum: ethereum,
+ prompt: "> ",
+ }
+ repl.initStdFuncs()
+ if !liner.TerminalSupported() {
+ repl.dumbRead()
+ } else {
+ lr := liner.NewLiner()
+ defer lr.Close()
+ lr.SetCtrlCAborts(true)
+ repl.withHistory(func(hist *os.File) { lr.ReadHistory(hist) })
+ repl.read(lr)
+ repl.withHistory(func(hist *os.File) { hist.Truncate(0); lr.WriteHistory(hist) })
+ }
+}
+
+func (self *repl) withHistory(op func(*os.File)) {
+ hist, err := os.OpenFile(path.Join(self.ethereum.DataDir, "history"), os.O_RDWR|os.O_CREATE, os.ModePerm)
+ if err != nil {
+ fmt.Printf("unable to open history file: %v\n", err)
+ return
+ }
+ op(hist)
+ hist.Close()
+}
+
+func (self *repl) 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)
+}
+
+var indentCount = 0
+var str = ""
+
+func (self *repl) 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 *repl) read(lr *liner.State) {
+ for {
+ input, err := lr.Prompt(self.prompt)
+ if err != nil {
+ return
+ }
+ if input == "" {
+ continue
+ }
+ str += input + "\n"
+ self.setIndent()
+ if indentCount <= 0 {
+ if input == "exit" {
+ return
+ }
+ hist := str[:len(str)-1]
+ lr.AppendHistory(hist)
+ self.parseInput(str)
+ str = ""
+ }
+ }
+}
+
+func (self *repl) dumbRead() {
+ fmt.Println("Unsupported terminal, line editing will not work.")
+
+ // process lines
+ readDone := make(chan struct{})
+ go func() {
+ r := bufio.NewReader(os.Stdin)
+ loop:
+ for {
+ fmt.Print(self.prompt)
+ line, err := r.ReadString('\n')
+ switch {
+ case err != nil || line == "exit":
+ break loop
+ case line == "":
+ continue
+ default:
+ self.parseInput(line + "\n")
+ }
+ }
+ close(readDone)
+ }()
+
+ // wait for Ctrl-C
+ sigc := make(chan os.Signal, 1)
+ signal.Notify(sigc, os.Interrupt, os.Kill)
+ defer signal.Stop(sigc)
+
+ select {
+ case <-readDone:
+ case <-sigc:
+ os.Stdin.Close() // terminate read
+ }
+}
+
+func (self *repl) printValue(v interface{}) {
+ method, _ := self.re.Vm.Get("prettyPrint")
+ v, err := self.re.Vm.ToValue(v)
+ if err == nil {
+ val, err := method.Call(method, v)
+ if err == nil {
+ fmt.Printf("%v", val)
+ }
+ }
+}
+
+func (self *repl) 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 *repl) 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 *repl) stopMining(call otto.FunctionCall) otto.Value {
+ self.xeth.Miner().Stop()
+ return otto.TrueValue()
+}
+
+func (self *repl) startMining(call otto.FunctionCall) otto.Value {
+ self.xeth.Miner().Start()
+ return otto.TrueValue()
+}
+
+func (self *repl) 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 *repl) 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()
+ }
+
+ return otto.TrueValue()
+}
diff --git a/cmd/ethereum/main.go b/cmd/ethereum/main.go
index ff306b10f..8b361f7ae 100644
--- a/cmd/ethereum/main.go
+++ b/cmd/ethereum/main.go
@@ -24,128 +24,191 @@ import (
"fmt"
"os"
"runtime"
+ "strconv"
"time"
+ "github.com/codegangsta/cli"
"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/logger"
- "github.com/ethereum/go-ethereum/p2p"
"github.com/ethereum/go-ethereum/state"
)
const (
ClientIdentifier = "Ethereum(G)"
- Version = "0.8.6"
+ Version = "0.9.0"
)
-var clilogger = logger.NewLogger("CLI")
+var (
+ clilogger = logger.NewLogger("CLI")
+ app = cli.NewApp()
+)
+
+func init() {
+ app.Version = Version
+ app.Usage = "the go-ethereum command-line client"
+ app.Action = run
+ app.HideVersion = true // we have a command to print the version
+ app.Commands = []cli.Command{
+ {
+ Action: version,
+ Name: "version",
+ Usage: "print ethereum version numbers",
+ Description: `
+The output of this command is supposed to be machine-readable.
+`,
+ },
+ {
+ Action: dump,
+ Name: "dump",
+ Usage: `dump a specific block from storage`,
+ Description: `
+The arguments are interpreted as block numbers or hashes.
+Use "ethereum dump 0" to dump the genesis block.
+`,
+ },
+ {
+ Action: runjs,
+ Name: "js",
+ Usage: `interactive JavaScript console`,
+ 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.
+`,
+ },
+ {
+ Action: importchain,
+ Name: "import",
+ Usage: `import a blockchain file`,
+ },
+ }
+ app.Author = ""
+ app.Email = ""
+ app.Flags = []cli.Flag{
+ utils.BootnodesFlag,
+ utils.DataDirFlag,
+ utils.KeyRingFlag,
+ utils.KeyStoreFlag,
+ utils.ListenPortFlag,
+ utils.LogFileFlag,
+ utils.LogFormatFlag,
+ utils.LogLevelFlag,
+ utils.MaxPeersFlag,
+ utils.MinerThreadsFlag,
+ utils.MiningEnabledFlag,
+ utils.NATFlag,
+ utils.NodeKeyFileFlag,
+ utils.NodeKeyHexFlag,
+ utils.RPCEnabledFlag,
+ utils.RPCListenAddrFlag,
+ utils.RPCPortFlag,
+ utils.VMDebugFlag,
+ //utils.VMTypeFlag,
+ }
+
+ // missing:
+ // flag.StringVar(&ConfigFile, "conf", defaultConfigFile, "config file")
+ // flag.BoolVar(&DiffTool, "difftool", false, "creates output for diff'ing. Sets LogLevel=0")
+ // flag.StringVar(&DiffType, "diff", "all", "sets the level of diff output [vm, all]. Has no effect if difftool=false")
+
+ // potential subcommands:
+ // flag.StringVar(&SecretFile, "import", "", "imports the file given (hex or mnemonic formats)")
+ // flag.StringVar(&ExportDir, "export", "", "exports the session keyring to files in the directory given")
+ // flag.BoolVar(&GenAddr, "genaddr", false, "create a new priv/pub key")
+}
func main() {
runtime.GOMAXPROCS(runtime.NumCPU())
+ defer logger.Flush()
+ if err := app.Run(os.Args); err != nil {
+ fmt.Fprintln(os.Stderr, err)
+ os.Exit(1)
+ }
+}
- defer func() {
- logger.Flush()
- }()
-
+func run(ctx *cli.Context) {
+ fmt.Printf("Welcome to the FRONTIER\n")
utils.HandleInterrupt()
+ eth := utils.GetEthereum(ClientIdentifier, Version, ctx)
+ startEth(ctx, eth)
+ // this blocks the thread
+ eth.WaitForShutdown()
+}
- // precedence: code-internal flag default < config file < environment variables < command line
- Init() // parsing command line
-
- if PrintVersion {
- printVersion()
- return
+func runjs(ctx *cli.Context) {
+ eth := utils.GetEthereum(ClientIdentifier, Version, ctx)
+ startEth(ctx, eth)
+ if len(ctx.Args()) == 0 {
+ runREPL(eth)
+ eth.Stop()
+ eth.WaitForShutdown()
+ } else if len(ctx.Args()) == 1 {
+ execJsFile(eth, ctx.Args()[0])
+ } else {
+ utils.Fatalf("This command can handle at most one argument.")
}
+}
- utils.InitConfig(VmType, ConfigFile, Datadir, "ETH")
-
- ethereum, err := eth.New(&eth.Config{
- Name: p2p.MakeName(ClientIdentifier, Version),
- KeyStore: KeyStore,
- DataDir: Datadir,
- LogFile: LogFile,
- LogLevel: LogLevel,
- LogFormat: LogFormat,
- MaxPeers: MaxPeer,
- Port: OutboundPort,
- NAT: NAT,
- KeyRing: KeyRing,
- Shh: true,
- Dial: Dial,
- BootNodes: BootNodes,
- NodeKey: NodeKey,
- MinerThreads: MinerThreads,
- })
+func startEth(ctx *cli.Context, eth *eth.Ethereum) {
+ utils.StartEthereum(eth)
+ if ctx.GlobalBool(utils.RPCEnabledFlag.Name) {
+ addr := ctx.GlobalString(utils.RPCListenAddrFlag.Name)
+ port := ctx.GlobalInt(utils.RPCPortFlag.Name)
+ utils.StartRpc(eth, addr, port)
+ }
+ if ctx.GlobalBool(utils.MiningEnabledFlag.Name) {
+ eth.Miner().Start()
+ }
+}
+func importchain(ctx *cli.Context) {
+ if len(ctx.Args()) != 1 {
+ utils.Fatalf("This command requires an argument.")
+ }
+ chain, _, _ := utils.GetChain(ctx)
+ start := time.Now()
+ err := utils.ImportChain(chain, ctx.Args().First())
if err != nil {
- clilogger.Fatalln(err)
+ utils.Fatalf("Import error: %v\n", err)
}
+ fmt.Printf("Import done in", time.Since(start))
+ return
+}
- utils.KeyTasks(ethereum.KeyManager(), KeyRing, GenAddr, SecretFile, ExportDir, NonInteractive)
-
- if Dump {
+func dump(ctx *cli.Context) {
+ chain, _, stateDb := utils.GetChain(ctx)
+ for _, arg := range ctx.Args() {
var block *types.Block
-
- if len(DumpHash) == 0 && DumpNumber == -1 {
- block = ethereum.ChainManager().CurrentBlock()
- } else if len(DumpHash) > 0 {
- block = ethereum.ChainManager().GetBlock(ethutil.Hex2Bytes(DumpHash))
+ if hashish(arg) {
+ block = chain.GetBlock(ethutil.Hex2Bytes(arg))
} else {
- block = ethereum.ChainManager().GetBlockByNumber(uint64(DumpNumber))
+ num, _ := strconv.Atoi(arg)
+ block = chain.GetBlockByNumber(uint64(num))
}
-
if block == nil {
- fmt.Fprintln(os.Stderr, "block not found")
-
- // We want to output valid JSON
fmt.Println("{}")
-
- os.Exit(1)
- }
-
- // Leave the Println. This needs clean output for piping
- statedb := state.New(block.Root(), ethereum.Db())
- fmt.Printf("%s\n", statedb.Dump())
-
- fmt.Println(block)
-
- return
- }
-
- if len(ImportChain) > 0 {
- start := time.Now()
- err := utils.ImportChain(ethereum, ImportChain)
- if err != nil {
- clilogger.Infoln(err)
+ utils.Fatalf("block not found")
+ } else {
+ statedb := state.New(block.Root(), stateDb)
+ fmt.Printf("%s\n", statedb.Dump())
+ // fmt.Println(block)
}
- clilogger.Infoln("import done in", time.Since(start))
- return
- }
-
- if StartRpc {
- utils.StartRpc(ethereum, RpcListenAddress, RpcPort)
- }
-
- utils.StartEthereum(ethereum)
-
- fmt.Printf("Welcome to the FRONTIER\n")
-
- if StartMining {
- ethereum.Miner().Start()
}
+}
- if StartJsConsole {
- InitJsConsole(ethereum)
- } else if len(InputFile) > 0 {
- ExecJsFile(ethereum, InputFile)
- }
- // this blocks the thread
- ethereum.WaitForShutdown()
+// hashish returns true for strings that look like hashes.
+func hashish(x string) bool {
+ _, err := strconv.Atoi(x)
+ return err != nil
}
-func printVersion() {
+func version(c *cli.Context) {
fmt.Printf(`%v %v
PV=%d
GOOS=%s
diff --git a/cmd/ethereum/repl/console_colors_windows.go b/cmd/ethereum/repl/console_colors_windows.go
deleted file mode 100644
index 8062746fb..000000000
--- a/cmd/ethereum/repl/console_colors_windows.go
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright (c) 2013-2014, Jeffrey Wilcke. All rights reserved.
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this library; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-// MA 02110-1301 USA
-
-/* Inspired by https://github.com/xuyu/logging/blob/master/colorful_win.go */
-
-package ethrepl
-
-import (
- "syscall"
- "unsafe"
-)
-
-type color uint16
-
-const (
- green = color(0x0002)
- red = color(0x0004)
- yellow = color(0x000E)
-)
-
-const (
- mask = uint16(yellow | green | red)
-)
-
-var (
- kernel32 = syscall.NewLazyDLL("kernel32.dll")
- procGetStdHandle = kernel32.NewProc("GetStdHandle")
- procSetConsoleTextAttribute = kernel32.NewProc("SetConsoleTextAttribute")
- procGetConsoleScreenBufferInfo = kernel32.NewProc("GetConsoleScreenBufferInfo")
- hStdout uintptr
- initScreenInfo *consoleScreenBufferInfo
-)
-
-func setConsoleTextAttribute(hConsoleOutput uintptr, wAttributes uint16) bool {
- ret, _, _ := procSetConsoleTextAttribute.Call(hConsoleOutput, uintptr(wAttributes))
- return ret != 0
-}
-
-type coord struct {
- X, Y int16
-}
-
-type smallRect struct {
- Left, Top, Right, Bottom int16
-}
-
-type consoleScreenBufferInfo struct {
- DwSize coord
- DwCursorPosition coord
- WAttributes uint16
- SrWindow smallRect
- DwMaximumWindowSize coord
-}
-
-func getConsoleScreenBufferInfo(hConsoleOutput uintptr) *consoleScreenBufferInfo {
- var csbi consoleScreenBufferInfo
- ret, _, _ := procGetConsoleScreenBufferInfo.Call(hConsoleOutput, uintptr(unsafe.Pointer(&csbi)))
- if ret == 0 {
- return nil
- }
- return &csbi
-}
-
-const (
- stdOutputHandle = uint32(-11 & 0xFFFFFFFF)
-)
-
-func init() {
- hStdout, _, _ = procGetStdHandle.Call(uintptr(stdOutputHandle))
- initScreenInfo = getConsoleScreenBufferInfo(hStdout)
-}
-
-func resetColorful() {
- if initScreenInfo == nil {
- return
- }
- setConsoleTextAttribute(hStdout, initScreenInfo.WAttributes)
-}
-
-func changeColor(c color) {
- attr := uint16(0) & ^mask | uint16(c)
- setConsoleTextAttribute(hStdout, attr)
-}
diff --git a/cmd/ethereum/repl/repl.go b/cmd/ethereum/repl/repl.go
deleted file mode 100644
index 11b812617..000000000
--- a/cmd/ethereum/repl/repl.go
+++ /dev/null
@@ -1,103 +0,0 @@
-// Copyright (c) 2013-2014, Jeffrey Wilcke. All rights reserved.
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this library; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-// MA 02110-1301 USA
-
-package ethrepl
-
-import (
- "bufio"
- "fmt"
- "io"
- "os"
- "path"
-
- "github.com/ethereum/go-ethereum/eth"
- "github.com/ethereum/go-ethereum/ethutil"
- "github.com/ethereum/go-ethereum/javascript"
- "github.com/ethereum/go-ethereum/logger"
-)
-
-var repllogger = logger.NewLogger("REPL")
-
-type Repl interface {
- Start()
- Stop()
-}
-
-type JSRepl struct {
- re *javascript.JSRE
-
- prompt string
-
- history *os.File
-
- running bool
-}
-
-func NewJSRepl(ethereum *eth.Ethereum) *JSRepl {
- hist, err := os.OpenFile(path.Join(ethutil.Config.ExecPath, "history"), os.O_RDWR|os.O_CREATE, os.ModePerm)
- if err != nil {
- panic(err)
- }
-
- return &JSRepl{re: javascript.NewJSRE(ethereum), prompt: "> ", history: hist}
-}
-
-func (self *JSRepl) Start() {
- if !self.running {
- self.running = true
- repllogger.Infoln("init JS Console")
-
- reader := bufio.NewReader(self.history)
- for {
- line, err := reader.ReadString('\n')
- if err != nil && err == io.EOF {
- break
- } else if err != nil {
- fmt.Println("error reading history", err)
- break
- }
-
- addHistory(line[:len(line)-1])
- }
- self.read()
- }
-}
-
-func (self *JSRepl) Stop() {
- if self.running {
- self.running = false
- self.re.Stop()
- repllogger.Infoln("exit JS Console")
- self.history.Close()
- }
-}
-
-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)
-}
diff --git a/cmd/ethereum/repl/repl_darwin.go b/cmd/ethereum/repl/repl_darwin.go
deleted file mode 100644
index 3710150cc..000000000
--- a/cmd/ethereum/repl/repl_darwin.go
+++ /dev/null
@@ -1,144 +0,0 @@
-// Copyright (c) 2013-2014, Jeffrey Wilcke. All rights reserved.
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this library; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-// MA 02110-1301 USA
-
-package ethrepl
-
-// #cgo darwin CFLAGS: -I/usr/local/opt/readline/include
-// #cgo darwin LDFLAGS: -L/usr/local/opt/readline/lib
-// #cgo LDFLAGS: -lreadline
-// #include <stdio.h>
-// #include <stdlib.h>
-// #include <readline/readline.h>
-// #include <readline/history.h>
-import "C"
-import (
- "fmt"
- "os"
- "os/signal"
- "strings"
- "syscall"
- "unsafe"
-)
-
-func initReadLine() {
- C.rl_catch_sigwinch = 0
- C.rl_catch_signals = 0
- c := make(chan os.Signal, 1)
- signal.Notify(c, syscall.SIGWINCH)
- signal.Notify(c, os.Interrupt)
- go func() {
- for sig := range c {
- switch sig {
- case syscall.SIGWINCH:
- C.rl_resize_terminal()
-
- case os.Interrupt:
- C.rl_cleanup_after_signal()
- default:
-
- }
- }
- }()
-}
-
-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))
-}
-
-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() {
- initReadLine()
-L:
- for {
- switch result := readLine(&self.prompt); true {
- case result == nil:
- break L
-
- case *result != "":
- str += *result + "\n"
-
- self.setIndent()
-
- if indentCount <= 0 {
- if *result == "exit" {
- self.Stop()
- break L
- }
-
- hist := str[:len(str)-1]
- addHistory(hist) //allow user to recall this line
- self.history.WriteString(str)
-
- self.parseInput(str)
-
- str = ""
- }
- }
- }
-}
-
-func (self *JSRepl) PrintValue(v interface{}) {
- method, _ := self.re.Vm.Get("prettyPrint")
- v, err := self.re.Vm.ToValue(v)
- if err == nil {
- val, err := method.Call(method, v)
- if err == nil {
- fmt.Printf("%v", val)
- }
- }
-}
diff --git a/cmd/ethereum/repl/repl_linux.go b/cmd/ethereum/repl/repl_linux.go
deleted file mode 120000
index 276f135d7..000000000
--- a/cmd/ethereum/repl/repl_linux.go
+++ /dev/null
@@ -1 +0,0 @@
-repl_darwin.go \ No newline at end of file
diff --git a/cmd/ethereum/repl/repl_windows.go b/cmd/ethereum/repl/repl_windows.go
deleted file mode 100644
index d2c405ee9..000000000
--- a/cmd/ethereum/repl/repl_windows.go
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright (c) 2013-2014, Jeffrey Wilcke. All rights reserved.
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU General Public
-// License as published by the Free Software Foundation; either
-// version 2.1 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License
-// along with this library; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
-// MA 02110-1301 USA
-
-package ethrepl
-
-import (
- "bufio"
- "fmt"
- "os"
- "strings"
-)
-
-func (self *JSRepl) read() {
- reader := bufio.NewReader(os.Stdin)
- for {
- fmt.Printf(self.prompt)
- str, _, err := reader.ReadLine()
- if err != nil {
- fmt.Println("Error reading input", err)
- } else {
- if string(str) == "exit" {
- self.Stop()
- break
- } else {
- self.parseInput(string(str))
- }
- }
- }
-}
-
-func addHistory(s string) {
-}
-
-func printColored(outputVal string) {
- for outputVal != "" {
- codePart := ""
- if strings.HasPrefix(outputVal, "\033[32m") {
- codePart = "\033[32m"
- changeColor(2)
- }
- if strings.HasPrefix(outputVal, "\033[1m\033[30m") {
- codePart = "\033[1m\033[30m"
- changeColor(8)
- }
- if strings.HasPrefix(outputVal, "\033[31m") {
- codePart = "\033[31m"
- changeColor(red)
- }
- if strings.HasPrefix(outputVal, "\033[35m") {
- codePart = "\033[35m"
- changeColor(5)
- }
- if strings.HasPrefix(outputVal, "\033[0m") {
- codePart = "\033[0m"
- resetColorful()
- }
- textPart := outputVal[len(codePart):len(outputVal)]
- index := strings.Index(textPart, "\033")
- if index == -1 {
- outputVal = ""
- } else {
- outputVal = textPart[index:len(textPart)]
- textPart = textPart[0:index]
- }
- fmt.Printf("%v", textPart)
- }
-}
-
-func (self *JSRepl) PrintValue(v interface{}) {
- method, _ := self.re.Vm.Get("prettyPrint")
- v, err := self.re.Vm.ToValue(v)
- if err == nil {
- val, err := method.Call(method, v)
- if err == nil {
- printColored(fmt.Sprintf("%v", val))
- }
- }
-}
diff --git a/cmd/evm/main.go b/cmd/evm/main.go
index 432cbd001..d6a93460e 100644
--- a/cmd/evm/main.go
+++ b/cmd/evm/main.go
@@ -65,7 +65,6 @@ func main() {
statedb := state.New(nil, db)
sender := statedb.NewStateObject([]byte("sender"))
receiver := statedb.NewStateObject([]byte("receiver"))
- //receiver.SetCode([]byte(*code))
receiver.SetCode(ethutil.Hex2Bytes(*code))
vmenv := NewEnv(statedb, []byte("evmuser"), ethutil.Big(*value))
diff --git a/cmd/mist/assets/ext/ethereum.js/dist/ethereum.js b/cmd/mist/assets/ext/ethereum.js/dist/ethereum.js
index 522b77ebf..5b7d87270 100644
--- a/cmd/mist/assets/ext/ethereum.js/dist/ethereum.js
+++ b/cmd/mist/assets/ext/ethereum.js/dist/ethereum.js
@@ -22,7 +22,6 @@ require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof requ
* @date 2014
*/
-var web3 = require('./web3');
var utils = require('./utils');
var types = require('./types');
var c = require('./const');
@@ -41,11 +40,11 @@ var arrayType = function (type) {
var dynamicTypeBytes = function (type, value) {
// TODO: decide what to do with array of strings
if (arrayType(type) || type === 'string') // only string itself that is dynamic; stringX is static length.
- return f.formatInputInt(value.length);
+ return f.formatInputInt(value.length);
return "";
};
-var inputTypes = types.inputTypes();
+var inputTypes = types.inputTypes();
/// Formats input params to bytes
/// @param abi contract method inputs
@@ -53,13 +52,16 @@ var inputTypes = types.inputTypes();
/// @returns bytes representation of input params
var formatInput = function (inputs, params) {
var bytes = "";
+ var toAppendConstant = "";
+ var toAppendArrayContent = "";
- /// first we iterate in search for dynamic
+ /// first we iterate in search for dynamic
inputs.forEach(function (input, index) {
bytes += dynamicTypeBytes(input.type, params[index]);
});
inputs.forEach(function (input, i) {
+ /*jshint maxcomplexity:5 */
var typeMatch = false;
for (var j = 0; j < inputTypes.length && !typeMatch; j++) {
typeMatch = inputTypes[j].type(inputs[i].type, params[i]);
@@ -69,17 +71,19 @@ var formatInput = function (inputs, params) {
}
var formatter = inputTypes[j - 1].format;
- var toAppend = "";
if (arrayType(inputs[i].type))
- toAppend = params[i].reduce(function (acc, curr) {
+ toAppendArrayContent += params[i].reduce(function (acc, curr) {
return acc + formatter(curr);
}, "");
+ else if (inputs[i].type === 'string')
+ toAppendArrayContent += formatter(params[i]);
else
- toAppend = formatter(params[i]);
-
- bytes += toAppend;
+ toAppendConstant += formatter(params[i]);
});
+
+ bytes += toAppendConstant + toAppendArrayContent;
+
return bytes;
};
@@ -89,14 +93,14 @@ var dynamicBytesLength = function (type) {
return 0;
};
-var outputTypes = types.outputTypes();
+var outputTypes = types.outputTypes();
/// Formats output bytes back to param list
/// @param contract abi method outputs
-/// @param bytes representtion of output
-/// @returns array of output params
+/// @param bytes representtion of output
+/// @returns array of output params
var formatOutput = function (outs, output) {
-
+
output = output.slice(2);
var result = [];
var padding = c.ETH_PADDING * 2;
@@ -104,7 +108,7 @@ var formatOutput = function (outs, output) {
var dynamicPartLength = outs.reduce(function (acc, curr) {
return acc + dynamicBytesLength(curr.type);
}, 0);
-
+
var dynamicPart = output.slice(0, dynamicPartLength);
output = output.slice(dynamicPartLength);
@@ -125,13 +129,13 @@ var formatOutput = function (outs, output) {
dynamicPart = dynamicPart.slice(padding);
var array = [];
for (var k = 0; k < size; k++) {
- array.push(formatter(output.slice(0, padding)));
+ array.push(formatter(output.slice(0, padding)));
output = output.slice(padding);
}
result.push(array);
}
else if (types.prefixedType('string')(outs[i].type)) {
- dynamicPart = dynamicPart.slice(padding);
+ dynamicPart = dynamicPart.slice(padding);
result.push(formatter(output.slice(0, padding)));
output = output.slice(padding);
} else {
@@ -149,14 +153,14 @@ var formatOutput = function (outs, output) {
var inputParser = function (json) {
var parser = {};
json.forEach(function (method) {
- var displayName = utils.extractDisplayName(method.name);
+ var displayName = utils.extractDisplayName(method.name);
var typeName = utils.extractTypeName(method.name);
var impl = function () {
var params = Array.prototype.slice.call(arguments);
return formatInput(method.inputs, params);
};
-
+
if (parser[displayName] === undefined) {
parser[displayName] = impl;
}
@@ -173,7 +177,7 @@ var outputParser = function (json) {
var parser = {};
json.forEach(function (method) {
- var displayName = utils.extractDisplayName(method.name);
+ var displayName = utils.extractDisplayName(method.name);
var typeName = utils.extractTypeName(method.name);
var impl = function (output) {
@@ -190,27 +194,14 @@ var outputParser = function (json) {
return parser;
};
-/// @param function/event name for which we want to get signature
-/// @returns signature of function/event with given name
-var signatureFromAscii = function (name) {
- return web3.sha3(web3.fromAscii(name)).slice(0, 2 + c.ETH_SIGNATURE_LENGTH * 2);
-};
-
-var eventSignatureFromAscii = function (name) {
- return web3.sha3(web3.fromAscii(name));
-};
-
module.exports = {
inputParser: inputParser,
outputParser: outputParser,
formatInput: formatInput,
- formatOutput: formatOutput,
- signatureFromAscii: signatureFromAscii,
- eventSignatureFromAscii: eventSignatureFromAscii
+ formatOutput: formatOutput
};
-
-},{"./const":2,"./formatters":8,"./types":14,"./utils":15,"./web3":17}],2:[function(require,module,exports){
+},{"./const":2,"./formatters":8,"./types":15,"./utils":16}],2:[function(require,module,exports){
/*
This file is part of ethereum.js.
@@ -296,6 +287,7 @@ var web3 = require('./web3');
var abi = require('./abi');
var utils = require('./utils');
var eventImpl = require('./event');
+var signature = require('./signature');
var exportNatspecGlobals = function (vars) {
// it's used byt natspec.js
@@ -309,16 +301,24 @@ var exportNatspecGlobals = function (vars) {
var addFunctionRelatedPropertiesToContract = function (contract) {
contract.call = function (options) {
- contract._isTransact = false;
+ contract._isTransaction = false;
contract._options = options;
return contract;
};
- contract.transact = function (options) {
- contract._isTransact = true;
+
+ contract.sendTransaction = function (options) {
+ contract._isTransaction = true;
contract._options = options;
return contract;
};
+ // DEPRECATED
+ contract.transact = function (options) {
+
+ console.warn('myContract.transact() is deprecated please use myContract.sendTransaction() instead.');
+
+ return contract.sendTransaction(options);
+ };
contract._options = {};
['gas', 'gasPrice', 'value', 'from'].forEach(function(p) {
@@ -343,21 +343,21 @@ var addFunctionsToContract = function (contract, desc, address) {
var impl = function () {
/*jshint maxcomplexity:7 */
var params = Array.prototype.slice.call(arguments);
- var signature = abi.signatureFromAscii(method.name);
+ var sign = signature.functionSignatureFromAscii(method.name);
var parsed = inputParser[displayName][typeName].apply(null, params);
var options = contract._options || {};
options.to = address;
- options.data = signature + parsed;
+ options.data = sign + parsed;
- var isTransact = contract._isTransact === true || (contract._isTransact !== false && !method.constant);
+ var isTransaction = contract._isTransaction === true || (contract._isTransaction !== false && !method.constant);
var collapse = options.collapse !== false;
// reset
contract._options = {};
- contract._isTransact = null;
+ contract._isTransaction = null;
- if (isTransact) {
+ if (isTransaction) {
exportNatspecGlobals({
abi: desc,
@@ -367,7 +367,7 @@ var addFunctionsToContract = function (contract, desc, address) {
});
// transactions do not have any output, cause we do not know, when they will be processed
- web3.eth.transact(options);
+ web3.eth.sendTransaction(options);
return;
}
@@ -402,7 +402,7 @@ var addEventRelatedPropertiesToContract = function (contract, desc, address) {
Object.defineProperty(contract, 'topic', {
get: function() {
return utils.filterEvents(desc).map(function (e) {
- return abi.eventSignatureFromAscii(e.name);
+ return signature.eventSignatureFromAscii(e.name);
});
}
});
@@ -415,14 +415,14 @@ var addEventsToContract = function (contract, desc, address) {
var impl = function () {
var params = Array.prototype.slice.call(arguments);
- var signature = abi.eventSignatureFromAscii(e.name);
- var event = eventImpl.inputParser(address, signature, e);
+ var sign = signature.eventSignatureFromAscii(e.name);
+ var event = eventImpl.inputParser(address, sign, e);
var o = event.apply(null, params);
var outputFormatter = function (data) {
var parser = eventImpl.outputParser(e);
return parser(data);
};
- return web3.eth.watch(o, undefined, undefined, outputFormatter);
+ return web3.eth.filter(o, undefined, undefined, outputFormatter);
};
// this property should be used by eth.filter to check if object is an event
@@ -452,24 +452,40 @@ var addEventsToContract = function (contract, desc, address) {
* outputs: [{name: 'd', type: 'string' }]
* }]; // contract abi
*
- * var myContract = web3.eth.contract('0x0123123121', abi); // creation of contract object
+ * var MyContract = web3.eth.contract(abi); // creation of contract prototype
+ *
+ * var contractInstance = new MyContract('0x0123123121');
*
- * myContract.myMethod('this is test string param for call'); // myMethod call (implicit, default)
- * myContract.call().myMethod('this is test string param for call'); // myMethod call (explicit)
- * myContract.transact().myMethod('this is test string param for transact'); // myMethod transact
+ * contractInstance.myMethod('this is test string param for call'); // myMethod call (implicit, default)
+ * contractInstance.call().myMethod('this is test string param for call'); // myMethod call (explicit)
+ * contractInstance.sendTransaction().myMethod('this is test string param for transact'); // myMethod sendTransaction
*
- * @param address - address of the contract, which should be called
- * @param desc - abi json description of the contract, which is being created
+ * @param abi - abi json description of the contract, which is being created
* @returns contract object
*/
+var contract = function (abi) {
+
+ // return prototype
+ if(abi instanceof Array && arguments.length === 1) {
+ return Contract.bind(null, abi);
+
+ // deprecated: auto initiate contract
+ } else {
+
+ console.warn('Initiating a contract like this is deprecated please use var MyContract = eth.contract(abi); new MyContract(address); instead.');
+
+ return new Contract(arguments[1], arguments[0]);
+ }
+
+};
-var contract = function (address, desc) {
+function Contract(abi, address) {
// workaround for invalid assumption that method.name is the full anonymous prototype of the method.
// it's not. it's just the name. the rest of the code assumes it's actually the anonymous
// prototype, so we make it so as a workaround.
// TODO: we may not want to modify input params, maybe use copy instead?
- desc.forEach(function (method) {
+ abi.forEach(function (method) {
if (method.name.indexOf('(') === -1) {
var displayName = method.name;
var typeName = method.inputs.map(function(i){return i.type; }).join();
@@ -479,17 +495,17 @@ var contract = function (address, desc) {
var result = {};
addFunctionRelatedPropertiesToContract(result);
- addFunctionsToContract(result, desc, address);
- addEventRelatedPropertiesToContract(result, desc, address);
- addEventsToContract(result, desc, address);
+ addFunctionsToContract(result, abi, address);
+ addEventRelatedPropertiesToContract(result, abi, address);
+ addEventsToContract(result, abi, address);
return result;
-};
+}
module.exports = contract;
-},{"./abi":1,"./event":6,"./utils":15,"./web3":17}],4:[function(require,module,exports){
+},{"./abi":1,"./event":6,"./signature":14,"./utils":16,"./web3":18}],4:[function(require,module,exports){
/*
This file is part of ethereum.js.
@@ -549,63 +565,83 @@ module.exports = {
* @date 2015
*/
-/// @returns an array of objects describing web3.eth api methods
-var methods = function () {
- var blockCall = function (args) {
- return typeof args[0] === "string" ? "eth_blockByHash" : "eth_blockByNumber";
- };
+var formatters = require('./formatters');
- var transactionCall = function (args) {
- return typeof args[0] === "string" ? 'eth_transactionByHash' : 'eth_transactionByNumber';
- };
- var uncleCall = function (args) {
- return typeof args[0] === "string" ? 'eth_uncleByHash' : 'eth_uncleByNumber';
- };
+var blockCall = function (args) {
+ return typeof args[0] === "string" ? "eth_blockByHash" : "eth_blockByNumber";
+};
- var transactionCountCall = function (args) {
- return typeof args[0] === "string" ? 'eth_transactionCountByHash' : 'eth_transactionCountByNumber';
- };
+var transactionCall = function (args) {
+ return typeof args[0] === "string" ? 'eth_transactionByHash' : 'eth_transactionByNumber';
+};
- var uncleCountCall = function (args) {
- return typeof args[0] === "string" ? 'eth_uncleCountByHash' : 'eth_uncleCountByNumber';
- };
+var uncleCall = function (args) {
+ return typeof args[0] === "string" ? 'eth_uncleByHash' : 'eth_uncleByNumber';
+};
- return [
- { name: 'balanceAt', call: 'eth_balanceAt' },
- { name: 'stateAt', call: 'eth_stateAt' },
- { name: 'storageAt', call: 'eth_storageAt' },
- { name: 'countAt', call: 'eth_countAt'},
- { name: 'codeAt', call: 'eth_codeAt' },
- { name: 'transact', call: 'eth_transact' },
+var transactionCountCall = function (args) {
+ return typeof args[0] === "string" ? 'eth_transactionCountByHash' : 'eth_transactionCountByNumber';
+};
+
+var uncleCountCall = function (args) {
+ return typeof args[0] === "string" ? 'eth_uncleCountByHash' : 'eth_uncleCountByNumber';
+};
+
+/// @returns an array of objects describing web3.eth api methods
+var methods = [
+ { name: 'getBalance', call: 'eth_balanceAt', outputFormatter: formatters.convertToBigNumber},
+ { name: 'getState', call: 'eth_stateAt' },
+ { name: 'getStorage', call: 'eth_storageAt' },
+ { name: 'getData', call: 'eth_codeAt' },
+ { name: 'getBlock', call: blockCall, outputFormatter: formatters.outputBlockFormatter},
+ { name: 'getUncle', call: uncleCall, outputFormatter: formatters.outputBlockFormatter},
+ { name: 'getCompilers', call: 'eth_compilers' },
+ { name: 'getBlockTransactionCount', call: transactionCountCall },
+ { name: 'getBlockUncleCount', call: uncleCountCall },
+ { name: 'getTransaction', call: transactionCall, outputFormatter: formatters.outputTransactionFormatter },
+ { name: 'getTransactionCount', call: 'eth_countAt'},
+ { name: 'sendTransaction', call: 'eth_transact', inputFormatter: formatters.inputTransactionFormatter },
{ name: 'call', call: 'eth_call' },
- { name: 'block', call: blockCall },
- { name: 'transaction', call: transactionCall },
- { name: 'uncle', call: uncleCall },
- { name: 'compilers', call: 'eth_compilers' },
+ { name: 'compile.solidity', call: 'eth_solidity' },
+ { name: 'compile.lll', call: 'eth_lll' },
+ { name: 'compile.serpent', call: 'eth_serpent' },
{ name: 'flush', call: 'eth_flush' },
- { name: 'lll', call: 'eth_lll' },
- { name: 'solidity', call: 'eth_solidity' },
- { name: 'serpent', call: 'eth_serpent' },
- { name: 'logs', call: 'eth_logs' },
- { name: 'transactionCount', call: transactionCountCall },
- { name: 'uncleCount', call: uncleCountCall }
- ];
-};
+
+ // deprecated methods
+ { name: 'balanceAt', call: 'eth_balanceAt', newMethod: 'getBalance' },
+ { name: 'stateAt', call: 'eth_stateAt', newMethod: 'getState' },
+ { name: 'storageAt', call: 'eth_storageAt', newMethod: 'getStorage' },
+ { name: 'countAt', call: 'eth_countAt', newMethod: 'getTransactionCount' },
+ { name: 'codeAt', call: 'eth_codeAt', newMethod: 'getData' },
+ { name: 'transact', call: 'eth_transact', newMethod: 'sendTransaction' },
+ { name: 'block', call: blockCall, newMethod: 'getBlock' },
+ { name: 'transaction', call: transactionCall, newMethod: 'getTransaction' },
+ { name: 'uncle', call: uncleCall, newMethod: 'getUncle' },
+ { name: 'compilers', call: 'eth_compilers', newMethod: 'getCompilers' },
+ { name: 'solidity', call: 'eth_solidity', newMethod: 'compile.solidity' },
+ { name: 'lll', call: 'eth_lll', newMethod: 'compile.lll' },
+ { name: 'serpent', call: 'eth_serpent', newMethod: 'compile.serpent' },
+ { name: 'transactionCount', call: transactionCountCall, newMethod: 'getBlockTransactionCount' },
+ { name: 'uncleCount', call: uncleCountCall, newMethod: 'getBlockUncleCount' },
+ { name: 'logs', call: 'eth_logs' }
+];
/// @returns an array of objects describing web3.eth api properties
-var properties = function () {
- return [
+var properties = [
{ name: 'coinbase', getter: 'eth_coinbase', setter: 'eth_setCoinbase' },
{ name: 'listening', getter: 'eth_listening', setter: 'eth_setListening' },
{ name: 'mining', getter: 'eth_mining', setter: 'eth_setMining' },
- { name: 'gasPrice', getter: 'eth_gasPrice' },
+ { name: 'gasPrice', getter: 'eth_gasPrice', outputFormatter: formatters.convertToBigNumber},
{ name: 'accounts', getter: 'eth_accounts' },
{ name: 'peerCount', getter: 'eth_peerCount' },
{ name: 'defaultBlock', getter: 'eth_defaultBlock', setter: 'eth_setDefaultBlock' },
- { name: 'number', getter: 'eth_number'}
- ];
-};
+ { name: 'blockNumber', getter: 'eth_number'},
+
+ // deprecated properties
+ { name: 'number', getter: 'eth_number', newProperty: 'blockNumber'}
+];
+
module.exports = {
methods: methods,
@@ -613,7 +649,7 @@ module.exports = {
};
-},{}],6:[function(require,module,exports){
+},{"./formatters":8}],6:[function(require,module,exports){
/*
This file is part of ethereum.js.
@@ -638,6 +674,7 @@ module.exports = {
var abi = require('./abi');
var utils = require('./utils');
+var signature = require('./signature');
/// filter inputs array && returns only indexed (or not) inputs
/// @param inputs array
@@ -676,14 +713,14 @@ var indexedParamsToTopics = function (event, indexed) {
});
};
-var inputParser = function (address, signature, event) {
+var inputParser = function (address, sign, event) {
- // valid options are 'earliest', 'latest', 'offset' and 'max', as defined for 'eth.watch'
+ // valid options are 'earliest', 'latest', 'offset' and 'max', as defined for 'eth.filter'
return function (indexed, options) {
var o = options || {};
o.address = address;
o.topic = [];
- o.topic.push(signature);
+ o.topic.push(sign);
if (indexed) {
o.topic = o.topic.concat(indexedParamsToTopics(event, indexed));
}
@@ -712,6 +749,7 @@ var outputParser = function (event) {
var result = {
event: utils.extractDisplayName(event.name),
number: output.number,
+ hash: output.hash,
args: {}
};
@@ -735,8 +773,8 @@ var outputParser = function (event) {
var getMatchingEvent = function (events, payload) {
for (var i = 0; i < events.length; i++) {
- var signature = abi.eventSignatureFromAscii(events[i].name);
- if (signature === payload.topic[0]) {
+ var sign = signature.eventSignatureFromAscii(events[i].name);
+ if (sign === payload.topic[0]) {
return events[i];
}
}
@@ -751,7 +789,7 @@ module.exports = {
};
-},{"./abi":1,"./utils":15}],7:[function(require,module,exports){
+},{"./abi":1,"./signature":14,"./utils":16}],7:[function(require,module,exports){
/*
This file is part of ethereum.js.
@@ -782,7 +820,7 @@ module.exports = {
var implementationIsValid = function (i) {
return !!i &&
typeof i.newFilter === 'function' &&
- typeof i.getMessages === 'function' &&
+ typeof i.getLogs === 'function' &&
typeof i.uninstallFilter === 'function' &&
typeof i.startPolling === 'function' &&
typeof i.stopPolling === 'function';
@@ -839,27 +877,50 @@ var filter = function(options, implementation, formatter) {
implementation.startPolling(filterId, onMessages, implementation.uninstallFilter);
- var changed = function (callback) {
+ var watch = function(callback) {
callbacks.push(callback);
};
- var messages = function () {
- return implementation.getMessages(filterId);
- };
-
- var uninstall = function () {
+ var stopWatching = function() {
implementation.stopPolling(filterId);
implementation.uninstallFilter(filterId);
callbacks = [];
};
+ var get = function () {
+ return implementation.getLogs(filterId);
+ };
+
return {
- changed: changed,
- arrived: changed,
- happened: changed,
- messages: messages,
- logs: messages,
- uninstall: uninstall
+ watch: watch,
+ stopWatching: stopWatching,
+ get: get,
+
+ // DEPRECATED methods
+ changed: function(){
+ console.warn('watch().changed() is deprecated please use filter().watch() instead.');
+ return watch.apply(this, arguments);
+ },
+ arrived: function(){
+ console.warn('watch().arrived() is deprecated please use filter().watch() instead.');
+ return watch.apply(this, arguments);
+ },
+ happened: function(){
+ console.warn('watch().happened() is deprecated please use filter().watch() instead.');
+ return watch.apply(this, arguments);
+ },
+ uninstall: function(){
+ console.warn('watch().uninstall() is deprecated please use filter().stopWatching() instead.');
+ return stopWatching.apply(this, arguments);
+ },
+ messages: function(){
+ console.warn('watch().messages() is deprecated please use filter().get() instead.');
+ return get.apply(this, arguments);
+ },
+ logs: function(){
+ console.warn('watch().logs() is deprecated please use filter().get() instead.');
+ return get.apply(this, arguments);
+ }
};
};
@@ -911,7 +972,7 @@ var padLeft = function (string, chars, sign) {
var formatInputInt = function (value) {
/*jshint maxcomplexity:7 */
var padding = c.ETH_PADDING * 2;
- if (value instanceof BigNumber || typeof value === 'number') {
+ if (utils.isBigNumber(value) || typeof value === 'number') {
if (typeof value === 'number')
value = new BigNumber(value);
BigNumber.config(c.ETH_BIGNUMBER_ROUNDING_MODE);
@@ -921,10 +982,13 @@ var formatInputInt = function (value) {
value = new BigNumber("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", 16).plus(value).plus(1);
value = value.toString(16);
}
- else if (value.indexOf('0x') === 0)
- value = value.substr(2);
- else if (typeof value === 'string')
- value = formatInputInt(new BigNumber(value));
+ else if (typeof value === 'string') {
+ if (value.indexOf('0x') === 0) {
+ value = value.substr(2);
+ } else {
+ value = formatInputInt(new BigNumber(value));
+ }
+ }
else
value = (+value).toString(16);
return padLeft(value, padding);
@@ -960,7 +1024,9 @@ var signedIsNegative = function (value) {
/// Formats input right-aligned input bytes to int
/// @returns right-aligned input bytes formatted to int
var formatOutputInt = function (value) {
+
value = value || "0";
+
// check if it's negative number
// it it is, return two's complement
if (signedIsNegative(value)) {
@@ -969,6 +1035,7 @@ var formatOutputInt = function (value) {
return new BigNumber(value, 16);
};
+
/// Formats big right-aligned input bytes to uint
/// @returns right-aligned input bytes formatted to uint
var formatOutputUInt = function (value) {
@@ -1007,6 +1074,138 @@ var formatOutputAddress = function (value) {
};
+/// Formats the input to a big number
+/// @returns a BigNumber object
+var convertToBigNumber = function (value) {
+
+ // remove the leading 0x
+ if(typeof value === 'string')
+ value = value.replace('0x', '');
+
+ value = value || "0";
+
+ return new BigNumber(value, 16);
+};
+
+
+/**
+Formats the input of a transaction and converts all values to HEX
+
+@returns object
+*/
+var inputTransactionFormatter = function(options){
+
+ // make code -> data
+ if(options.code) {
+ options.data = options.code;
+ delete options.code;
+ }
+
+ // make endowment -> value
+ if(options.endowment) {
+ options.value = options.endowment;
+ delete options.endowment;
+ }
+
+
+ // format the following options
+ /*jshint maxcomplexity:5 */
+ ['gasPrice', 'value'].forEach(function(key){
+
+ // if hex or string integer
+ if(typeof options[key] === 'string') {
+
+ // if not hex assume its a number string
+ if(options[key].indexOf('0x') === -1)
+ options[key] = utils.fromDecimal(options[key]);
+
+ // if number
+ } else if(typeof options[key] === 'number') {
+ options[key] = utils.fromDecimal(options[key]);
+
+ // if bignumber
+ } else if(options[key] instanceof BigNumber) {
+ options[key] = '0x'+ options[key].toString(16);
+ }
+ });
+
+ // format gas to number
+ options.gas = Number(options.gas);
+
+
+ return options;
+};
+
+/**
+Formats the output of a transaction to its proper values
+
+@returns object
+*/
+var outputTransactionFormatter = function(tx){
+ // transform to number
+ tx.gas = Number(tx.gas);
+
+ // gasPrice to bignumber
+ if(typeof tx.gasPrice === 'string' && tx.gasPrice.indexOf('0x') === 0)
+ tx.gasPrice = new BigNumber(tx.gasPrice, 16);
+ else
+ tx.gasPrice = new BigNumber(tx.gasPrice.toString(10), 10);
+
+ // value to bignumber
+ if(typeof tx.value === 'string' && tx.value.indexOf('0x') === 0)
+ tx.value = new BigNumber(tx.value, 16);
+ else
+ tx.value = new BigNumber(tx.value.toString(10), 10);
+
+ return tx;
+};
+
+
+/**
+Formats the output of a block to its proper values
+
+@returns object
+*/
+var outputBlockFormatter = function(block){
+ /*jshint maxcomplexity:7 */
+
+ // transform to number
+ block.gasLimit = Number(block.gasLimit);
+ block.gasUsed = Number(block.gasUsed);
+ block.size = Number(block.size);
+ block.timestamp = Number(block.timestamp);
+ block.number = Number(block.number);
+
+ // minGasPrice to bignumber
+ if(block.minGasPrice) {
+ if(typeof block.minGasPrice === 'string' && block.minGasPrice.indexOf('0x') === 0)
+ block.minGasPrice = new BigNumber(block.minGasPrice, 16);
+ else
+ block.minGasPrice = new BigNumber(block.minGasPrice.toString(10), 10);
+ }
+
+
+ // difficulty to bignumber
+ if(block.difficulty) {
+ if(typeof block.difficulty === 'string' && block.difficulty.indexOf('0x') === 0)
+ block.difficulty = new BigNumber(block.difficulty, 16);
+ else
+ block.difficulty = new BigNumber(block.difficulty.toString(10), 10);
+ }
+
+
+ // difficulty to bignumber
+ if(block.totalDifficulty) {
+ if(typeof block.totalDifficulty === 'string' && block.totalDifficulty.indexOf('0x') === 0)
+ block.totalDifficulty = new BigNumber(block.totalDifficulty, 16);
+ else
+ block.totalDifficulty = new BigNumber(block.totalDifficulty.toString(10), 10);
+ }
+
+ return block;
+};
+
+
module.exports = {
formatInputInt: formatInputInt,
formatInputString: formatInputString,
@@ -1019,11 +1218,15 @@ module.exports = {
formatOutputHash: formatOutputHash,
formatOutputBool: formatOutputBool,
formatOutputString: formatOutputString,
- formatOutputAddress: formatOutputAddress
+ formatOutputAddress: formatOutputAddress,
+ convertToBigNumber: convertToBigNumber,
+ inputTransactionFormatter: inputTransactionFormatter,
+ outputTransactionFormatter: outputTransactionFormatter,
+ outputBlockFormatter: outputBlockFormatter
};
-},{"./const":2,"./utils":15}],9:[function(require,module,exports){
+},{"./const":2,"./utils":16}],9:[function(require,module,exports){
/*
This file is part of ethereum.js.
@@ -1215,6 +1418,15 @@ var requestManager = function() {
var provider;
var send = function (data) {
+ /*jshint maxcomplexity: 6 */
+
+ // format the input before sending
+ if(typeof data.inputFormatter === 'function') {
+ data.params = Array.prototype.map.call(data.params, function(item){
+ return data.inputFormatter(item);
+ });
+ }
+
var payload = jsonrpc.toPayload(data.method, data.params);
if (!provider) {
@@ -1226,10 +1438,13 @@ var requestManager = function() {
if (!jsonrpc.isValidResponse(result)) {
console.log(result);
+ if(typeof result === 'object' && result.error && result.error.message)
+ console.error(result.error.message);
return null;
}
- return result.result;
+ // format the output
+ return (typeof data.outputFormatter === 'function') ? data.outputFormatter(result.result) : result.result;
};
var setProvider = function (p) {
@@ -1317,9 +1532,12 @@ var methods = function () {
return [
{ name: 'post', call: 'shh_post' },
{ name: 'newIdentity', call: 'shh_newIdentity' },
- { name: 'haveIdentity', call: 'shh_haveIdentity' },
+ { name: 'hasIdentity', call: 'shh_haveIdentity' },
{ name: 'newGroup', call: 'shh_newGroup' },
- { name: 'addToGroup', call: 'shh_addToGroup' }
+ { name: 'addToGroup', call: 'shh_addToGroup' },
+
+ // deprecated
+ { name: 'haveIdentity', call: 'shh_haveIdentity', newMethod: 'hasIdentity' },
];
};
@@ -1345,6 +1563,50 @@ module.exports = {
You should have received a copy of the GNU Lesser General Public License
along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
*/
+/** @file signature.js
+ * @authors:
+ * Marek Kotewicz <marek@ethdev.com>
+ * @date 2015
+ */
+
+var web3 = require('./web3');
+var c = require('./const');
+
+/// @param function name for which we want to get signature
+/// @returns signature of function with given name
+var functionSignatureFromAscii = function (name) {
+ return web3.sha3(web3.fromAscii(name)).slice(0, 2 + c.ETH_SIGNATURE_LENGTH * 2);
+};
+
+/// @param event name for which we want to get signature
+/// @returns signature of event with given name
+var eventSignatureFromAscii = function (name) {
+ return web3.sha3(web3.fromAscii(name));
+};
+
+module.exports = {
+ functionSignatureFromAscii: functionSignatureFromAscii,
+ eventSignatureFromAscii: eventSignatureFromAscii
+};
+
+
+},{"./const":2,"./web3":18}],15:[function(require,module,exports){
+/*
+ This file is part of ethereum.js.
+
+ ethereum.js is free software: you can redistribute it and/or modify
+ it under the terms of the GNU Lesser General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ ethereum.js is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public License
+ along with ethereum.js. If not, see <http://www.gnu.org/licenses/>.
+*/
/** @file types.js
* @authors:
* Marek Kotewicz <marek@ethdev.com>
@@ -1409,7 +1671,7 @@ module.exports = {
};
-},{"./formatters":8}],15:[function(require,module,exports){
+},{"./formatters":8}],16:[function(require,module,exports){
/*
This file is part of ethereum.js.
@@ -1434,6 +1696,30 @@ module.exports = {
var c = require('./const');
+if ("build" !== 'build') {/*
+ var BigNumber = require('bignumber.js'); // jshint ignore:line
+*/}
+
+var unitMap = {
+ 'wei': '1',
+ 'kwei': '1000',
+ 'ada': '1000',
+ 'mwei': '1000000',
+ 'babbage': '1000000',
+ 'gwei': '1000000000',
+ 'shannon': '1000000000',
+ 'szabo': '1000000000000',
+ 'finney': '1000000000000000',
+ 'ether': '1000000000000000000',
+ 'kether': '1000000000000000000000',
+ 'grand': '1000000000000000000000',
+ 'einstein': '1000000000000000000000',
+ 'mether': '1000000000000000000000000',
+ 'gether': '1000000000000000000000000000',
+ 'tether': '1000000000000000000000000000000'
+};
+
+
/// Finds first index of array element matching pattern
/// @param array
/// @param callback pattern
@@ -1519,8 +1805,11 @@ var filterEvents = function (json) {
/// TODO: use BigNumber.js to parse int
/// TODO: add tests for it!
var toEth = function (str) {
+
+ console.warn('This method is deprecated please use eth.fromWei(BigNumberOrNumber, unit) instead.');
+
/*jshint maxcomplexity:7 */
- var val = typeof str === "string" ? str.indexOf('0x') === 0 ? parseInt(str.substr(2), 16) : parseInt(str) : str;
+ var val = typeof str === "string" ? str.indexOf('0x') === 0 ? parseInt(str.substr(2), 16) : parseInt(str.replace(/,/g,'').replace(/ /g,'')) : str;
var unit = 0;
var units = c.ETH_UNITS;
while (val > 3000 && unit < units.length - 1)
@@ -1542,19 +1831,161 @@ var toEth = function (str) {
return s + ' ' + units[unit];
};
+
+var toDecimal = function (val) {
+ // remove 0x and place 0, if it's required
+ val = val.length > 2 ? val.substring(2) : "0";
+ return (new BigNumber(val, 16).toString(10));
+};
+
+var fromDecimal = function (val) {
+ return "0x" + (new BigNumber(val).toString(16));
+};
+
+
+/**
+Takes a number of wei and converts it to any other ether unit.
+
+Possible units are:
+
+ - kwei/ada
+ - mwei/babbage
+ - gwei/shannon
+ - szabo
+ - finney
+ - ether
+ - kether/grand/einstein
+ - mether
+ - gether
+ - tether
+
+@method fromWei
+@param {Number|String} number can be a number, number string or a HEX of a decimal
+@param {String} unit the unit to convert to
+@return {String|Object} When given a BigNumber object it returns one as well, otherwise a number
+*/
+var fromWei = function(number, unit) {
+ /*jshint maxcomplexity: 6 */
+ unit = unit.toLowerCase();
+
+ var isBigNumber = true;
+
+ if(!unitMap[unit]) {
+ console.warn('This unit doesn\'t exists, please use the one of the following units' , unitMap);
+ return number;
+ }
+
+ if(!number)
+ return number;
+
+ if(typeof number === 'string' && number.indexOf('0x') === 0) {
+ isBigNumber = false;
+ number = new BigNumber(number, 16);
+ }
+
+ if(!(number instanceof BigNumber)) {
+ isBigNumber = false;
+ number = new BigNumber(number.toString(10), 10); // toString to prevent errors, the user have to handle giving correct bignums themselves
+ }
+
+ number = number.dividedBy(new BigNumber(unitMap[unit], 10));
+
+ return (isBigNumber) ? number : number.toString(10);
+};
+
+/**
+Takes a number of a unit and converts it to wei.
+
+Possible units are:
+
+ - kwei/ada
+ - mwei/babbage
+ - gwei/shannon
+ - szabo
+ - finney
+ - ether
+ - kether/grand/einstein
+ - mether
+ - gether
+ - tether
+
+@method toWei
+@param {Number|String|BigNumber} number can be a number, number string or a HEX of a decimal
+@param {String} unit the unit to convert to
+@return {String|Object} When given a BigNumber object it returns one as well, otherwise a number
+*/
+var toWei = function(number, unit) {
+ /*jshint maxcomplexity: 6 */
+ unit = unit.toLowerCase();
+
+ var isBigNumber = true;
+
+ if(!unitMap[unit]) {
+ console.warn('This unit doesn\'t exists, please use the one of the following units' , unitMap);
+ return number;
+ }
+
+ if(!number)
+ return number;
+
+ if(typeof number === 'string' && number.indexOf('0x') === 0) {
+ isBigNumber = false;
+ number = new BigNumber(number, 16);
+ }
+
+ if(!(number instanceof BigNumber)) {
+ isBigNumber = false;
+ number = new BigNumber(number.toString(10), 10);// toString to prevent errors, the user have to handle giving correct bignums themselves
+ }
+
+
+ number = number.times(new BigNumber(unitMap[unit], 10));
+
+ return (isBigNumber) ? number : number.toString(10);
+};
+
+
+/**
+Checks if the given string is a valid ethereum HEX address.
+
+@method isAddress
+@param {String} address the given HEX adress
+@return {Boolean}
+*/
+var isAddress = function(address) {
+ if(address.indexOf('0x') === 0 && address.length !== 42)
+ return false;
+ if(address.indexOf('0x') === -1 && address.length !== 40)
+ return false;
+
+ return /^\w+$/.test(address);
+};
+
+var isBigNumber = function (value) {
+ return value instanceof BigNumber ||
+ (value && value.constructor && value.constructor.name === 'BigNumber');
+};
+
+
module.exports = {
findIndex: findIndex,
+ toDecimal: toDecimal,
+ fromDecimal: fromDecimal,
toAscii: toAscii,
fromAscii: fromAscii,
extractDisplayName: extractDisplayName,
extractTypeName: extractTypeName,
filterFunctions: filterFunctions,
filterEvents: filterEvents,
- toEth: toEth
+ toEth: toEth,
+ toWei: toWei,
+ fromWei: fromWei,
+ isAddress: isAddress,
+ isBigNumber: isBigNumber
};
-},{"./const":2}],16:[function(require,module,exports){
+},{"./const":2}],17:[function(require,module,exports){
/*
This file is part of ethereum.js.
@@ -1577,7 +2008,7 @@ module.exports = {
* @date 2015
*/
-/// @returns an array of objects describing web3.eth.watch api methods
+/// @returns an array of objects describing web3.eth.filter api methods
var eth = function () {
var newFilter = function (args) {
return typeof args[0] === 'string' ? 'eth_newFilterString' : 'eth_newFilter';
@@ -1586,7 +2017,7 @@ var eth = function () {
return [
{ name: 'newFilter', call: newFilter },
{ name: 'uninstallFilter', call: 'eth_uninstallFilter' },
- { name: 'getMessages', call: 'eth_filterLogs' }
+ { name: 'getLogs', call: 'eth_filterLogs' }
];
};
@@ -1595,7 +2026,7 @@ var shh = function () {
return [
{ name: 'newFilter', call: 'shh_newFilter' },
{ name: 'uninstallFilter', call: 'shh_uninstallFilter' },
- { name: 'getMessages', call: 'shh_getMessages' }
+ { name: 'getLogs', call: 'shh_getMessages' }
];
};
@@ -1605,7 +2036,7 @@ module.exports = {
};
-},{}],17:[function(require,module,exports){
+},{}],18:[function(require,module,exports){
/*
This file is part of ethereum.js.
@@ -1631,9 +2062,9 @@ module.exports = {
* @date 2014
*/
-if ("build" !== 'build') {/*
- var BigNumber = require('bignumber.js');
-*/}
+// if (process.env.NODE_ENV !== 'build') {
+// var BigNumber = require('bignumber.js');
+// }
var eth = require('./eth');
var db = require('./db');
@@ -1654,14 +2085,35 @@ var web3Methods = function () {
/// setups api calls for these methods
var setupMethods = function (obj, methods) {
methods.forEach(function (method) {
- obj[method.name] = function () {
- var args = Array.prototype.slice.call(arguments);
- var call = typeof method.call === 'function' ? method.call(args) : method.call;
- return web3.manager.send({
- method: call,
- params: args
- });
- };
+ // allow for object methods 'myObject.method'
+ var objectMethods = method.name.split('.'),
+ callFunction = function () {
+ var args = Array.prototype.slice.call(arguments);
+ var call = typeof method.call === 'function' ? method.call(args) : method.call;
+
+ // show deprecated warning
+ if(method.newMethod)
+ console.warn('This method is deprecated please use eth.'+ method.newMethod +'() instead.');
+
+ return web3.manager.send({
+ method: call,
+ params: args,
+ outputFormatter: method.outputFormatter,
+ inputFormatter: method.inputFormatter
+ });
+ };
+
+ if(objectMethods.length > 1) {
+ if(!obj[objectMethods[0]])
+ obj[objectMethods[0]] = {};
+
+ obj[objectMethods[0]][objectMethods[1]] = callFunction;
+
+ } else {
+
+ obj[objectMethods[0]] = callFunction;
+ }
+
});
};
@@ -1671,20 +2123,36 @@ var setupProperties = function (obj, properties) {
properties.forEach(function (property) {
var proto = {};
proto.get = function () {
+
+ // show deprecated warning
+ if(property.newProperty)
+ console.warn('This property is deprecated please use eth.'+ property.newProperty +' instead.');
+
+
return web3.manager.send({
- method: property.getter
+ method: property.getter,
+ outputFormatter: property.outputFormatter
});
};
if (property.setter) {
proto.set = function (val) {
+
+ // show deprecated warning
+ if(property.newProperty)
+ console.warn('This property is deprecated please use eth.'+ property.newProperty +' instead.');
+
return web3.manager.send({
method: property.setter,
- params: [val]
+ params: [val],
+ inputFormatter: property.inputFormatter
});
};
}
+
+ proto.enumerable = !property.newProperty;
Object.defineProperty(obj, property.name, proto);
+
});
};
@@ -1716,6 +2184,16 @@ var web3 = {
manager: requestManager(),
providers: {},
+ setProvider: function (provider) {
+ web3.manager.setProvider(provider);
+ },
+
+ /// Should be called to reset state of web3 object
+ /// Resets everything except manager
+ reset: function () {
+ web3.manager.reset();
+ },
+
/// @returns ascii string representation of hex value prefixed with 0x
toAscii: utils.toAscii,
@@ -1723,23 +2201,25 @@ var web3 = {
fromAscii: utils.fromAscii,
/// @returns decimal representaton of hex value prefixed by 0x
- toDecimal: function (val) {
- // remove 0x and place 0, if it's required
- val = val.length > 2 ? val.substring(2) : "0";
- return (new BigNumber(val, 16).toString(10));
- },
+ toDecimal: utils.toDecimal,
/// @returns hex representation (prefixed by 0x) of decimal value
- fromDecimal: function (val) {
- return "0x" + (new BigNumber(val).toString(16));
- },
+ fromDecimal: utils.fromDecimal,
/// used to transform value/string to eth string
toEth: utils.toEth,
+ toWei: utils.toWei,
+ fromWei: utils.fromWei,
+ isAddress: utils.isAddress,
+
+
/// eth object prototype
eth: {
+ // DEPRECATED
contractFromAbi: function (abi) {
+ console.warn('Initiating a contract like this is deprecated please use var MyContract = eth.contract(abi); new MyContract(address); instead.');
+
return function(addr) {
// Default to address of Config. TODO: rremove prior to genesis.
addr = addr || '0xc6d9d2cd449a754c494264e1809c50e34d64562b';
@@ -1750,15 +2230,22 @@ var web3 = {
},
/// @param filter may be a string, object or event
- /// @param indexed is optional, this is an object with optional event indexed params
+ /// @param eventParams is optional, this is an object with optional event eventParams params
/// @param options is optional, this is an object with optional event options ('max'...)
/// TODO: fix it, 4 params? no way
/*jshint maxparams:4 */
- watch: function (fil, indexed, options, formatter) {
- if (fil._isEvent) {
- return fil(indexed, options);
- }
+ filter: function (fil, eventParams, options, formatter) {
+
+ // if its event, treat it differently
+ if (fil._isEvent)
+ return fil(eventParams, options);
+
return filter(fil, ethWatch, formatter);
+ },
+ // DEPRECATED
+ watch: function (fil, eventParams, options, formatter) {
+ console.warn('eth.watch() is deprecated please use eth.filter() instead.');
+ return this.filter(fil, eventParams, options, formatter);
}
/*jshint maxparams:3 */
},
@@ -1769,25 +2256,21 @@ var web3 = {
/// shh object prototype
shh: {
/// @param filter may be a string, object or event
- watch: function (fil) {
+ filter: function (fil) {
return filter(fil, shhWatch);
+ },
+ // DEPRECATED
+ watch: function (fil) {
+ console.warn('shh.watch() is deprecated please use shh.filter() instead.');
+ return this.filter(fil);
}
- },
- setProvider: function (provider) {
- web3.manager.setProvider(provider);
- },
-
- /// Should be called to reset state of web3 object
- /// Resets everything except manager
- reset: function () {
- web3.manager.reset();
}
};
/// setups all api methods
setupMethods(web3, web3Methods());
-setupMethods(web3.eth, eth.methods());
-setupProperties(web3.eth, eth.properties());
+setupMethods(web3.eth, eth.methods);
+setupProperties(web3.eth, eth.properties);
setupMethods(web3.db, db.methods());
setupMethods(web3.shh, shh.methods());
setupMethods(ethWatch, watches.eth());
@@ -1796,7 +2279,7 @@ setupMethods(shhWatch, watches.shh());
module.exports = web3;
-},{"./db":4,"./eth":5,"./filter":7,"./requestmanager":12,"./shh":13,"./utils":15,"./watches":16}],"web3":[function(require,module,exports){
+},{"./db":4,"./eth":5,"./filter":7,"./requestmanager":12,"./shh":13,"./utils":16,"./watches":17}],"web3":[function(require,module,exports){
var web3 = require('./lib/web3');
web3.providers.HttpSyncProvider = require('./lib/httpsync');
web3.providers.QtSyncProvider = require('./lib/qtsync');
@@ -1805,7 +2288,7 @@ web3.abi = require('./lib/abi');
module.exports = web3;
-},{"./lib/abi":1,"./lib/contract":3,"./lib/httpsync":9,"./lib/qtsync":11,"./lib/web3":17}]},{},["web3"])
+},{"./lib/abi":1,"./lib/contract":3,"./lib/httpsync":9,"./lib/qtsync":11,"./lib/web3":18}]},{},["web3"])
//# sourceMappingURL=ethereum.js.map
diff --git a/cmd/mist/assets/qml/main.qml b/cmd/mist/assets/qml/main.qml
index f9ee6939d..6824d2ba9 100644
--- a/cmd/mist/assets/qml/main.qml
+++ b/cmd/mist/assets/qml/main.qml
@@ -981,7 +981,7 @@ ApplicationWindow {
anchors.top: parent.top
anchors.topMargin: 30
font.pointSize: 12
- text: "<h2>Mist (0.8.6)</h2><br><h3>Development</h3>Jeffrey Wilcke<br>Viktor Trón<br>Felix Lange<br>Taylor Gerring<br>Daniel Nagy<br>Gustav Simonsson<br><h3>UX/UI</h3>Alex van de Sande<br>Fabian Vogelsteller"
+ text: "<h2>Mist (0.9.0)</h2><br><h3>Development</h3>Jeffrey Wilcke<br>Viktor Trón<br>Felix Lange<br>Taylor Gerring<br>Daniel Nagy<br>Gustav Simonsson<br><h3>UX/UI</h3>Alex van de Sande<br>Fabian Vogelsteller"
}
}
diff --git a/cmd/mist/bindings.go b/cmd/mist/bindings.go
index 9623538a3..c63f11591 100644
--- a/cmd/mist/bindings.go
+++ b/cmd/mist/bindings.go
@@ -79,14 +79,14 @@ func (self *Gui) AddPlugin(pluginPath string) {
self.plugins[pluginPath] = plugin{Name: pluginPath, Path: pluginPath}
json, _ := json.MarshalIndent(self.plugins, "", " ")
- ethutil.WriteFile(ethutil.Config.ExecPath+"/plugins.json", json)
+ ethutil.WriteFile(self.eth.DataDir+"/plugins.json", json)
}
func (self *Gui) RemovePlugin(pluginPath string) {
delete(self.plugins, pluginPath)
json, _ := json.MarshalIndent(self.plugins, "", " ")
- ethutil.WriteFile(ethutil.Config.ExecPath+"/plugins.json", json)
+ ethutil.WriteFile(self.eth.DataDir+"/plugins.json", json)
}
// this extra function needed to give int typecast value to gui widget
@@ -113,7 +113,7 @@ func (self *Gui) DumpState(hash, path string) {
return
}
- stateDump = state.New(block.Root(), self.eth.Db()).Dump()
+ stateDump = state.New(block.Root(), self.eth.StateDb()).Dump()
}
file, err := os.OpenFile(path[7:], os.O_CREATE|os.O_RDWR, os.ModePerm)
diff --git a/cmd/mist/ext_app.go b/cmd/mist/ext_app.go
deleted file mode 100644
index 84041a553..000000000
--- a/cmd/mist/ext_app.go
+++ /dev/null
@@ -1,117 +0,0 @@
-/*
- This file is part of go-ethereum
-
- go-ethereum is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- go-ethereum is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with go-ethereum. If not, see <http://www.gnu.org/licenses/>.
-*/
-/**
- * @authors
- * Jeffrey Wilcke <i@jev.io>
- */
-package main
-
-import (
- "github.com/ethereum/go-ethereum/core"
- "github.com/ethereum/go-ethereum/core/types"
- "github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/xeth"
- "github.com/obscuren/qml"
-)
-
-type AppContainer interface {
- Create() error
- Destroy()
-
- Window() *qml.Window
- Engine() *qml.Engine
-
- NewBlock(*types.Block)
- NewWatcher(chan bool)
- Post(string, int)
-}
-
-type ExtApplication struct {
- *xeth.XEth
- eth core.Backend
-
- events event.Subscription
- watcherQuitChan chan bool
-
- filters map[string]*core.Filter
-
- container AppContainer
- lib *UiLib
-}
-
-func NewExtApplication(container AppContainer, lib *UiLib) *ExtApplication {
- return &ExtApplication{
- XEth: xeth.New(lib.eth),
- eth: lib.eth,
- watcherQuitChan: make(chan bool),
- filters: make(map[string]*core.Filter),
- container: container,
- lib: lib,
- }
-}
-
-func (app *ExtApplication) run() {
- // Set the "eth" api on to the containers context
- context := app.container.Engine().Context()
- context.SetVar("eth", app)
- context.SetVar("ui", app.lib)
-
- err := app.container.Create()
- if err != nil {
- guilogger.Errorln(err)
- return
- }
-
- // Call the main loop
- go app.mainLoop()
-
- app.container.NewWatcher(app.watcherQuitChan)
-
- win := app.container.Window()
- win.Show()
- win.Wait()
-
- app.stop()
-}
-
-func (app *ExtApplication) stop() {
- app.events.Unsubscribe()
-
- // Kill the main loop
- app.watcherQuitChan <- true
-
- app.container.Destroy()
-}
-
-func (app *ExtApplication) mainLoop() {
- for ev := range app.events.Chan() {
- switch ev := ev.(type) {
- case core.NewBlockEvent:
- app.container.NewBlock(ev.Block)
-
- /* TODO remove
- case state.Messages:
- for id, filter := range app.filters {
- msgs := filter.FilterMessages(ev)
- if len(msgs) > 0 {
- app.container.Messages(msgs, id)
- }
- }
- */
- }
- }
-}
diff --git a/cmd/mist/gui.go b/cmd/mist/gui.go
index 35bfdf9a3..53ca35574 100644
--- a/cmd/mist/gui.go
+++ b/cmd/mist/gui.go
@@ -88,7 +88,7 @@ func NewWindow(ethereum *eth.Ethereum, config *ethutil.ConfigManager, session st
panic(err)
}
- xeth := xeth.New(ethereum)
+ xeth := xeth.New(ethereum, nil)
gui := &Gui{eth: ethereum,
txDb: db,
xeth: xeth,
@@ -99,7 +99,7 @@ func NewWindow(ethereum *eth.Ethereum, config *ethutil.ConfigManager, session st
plugins: make(map[string]plugin),
serviceEvents: make(chan ServEv, 1),
}
- data, _ := ethutil.ReadAllFile(path.Join(ethutil.Config.ExecPath, "plugins.json"))
+ data, _ := ethutil.ReadAllFile(path.Join(ethereum.DataDir, "plugins.json"))
json.Unmarshal([]byte(data), &gui.plugins)
return gui
@@ -158,8 +158,6 @@ func (gui *Gui) Stop() {
gui.win.Hide()
}
- gui.uiLib.jsEngine.Stop()
-
guilogger.Infoln("Stopped")
}
diff --git a/cmd/mist/main.go b/cmd/mist/main.go
index 1d4403848..7d78c9c02 100644
--- a/cmd/mist/main.go
+++ b/cmd/mist/main.go
@@ -36,7 +36,7 @@ import (
const (
ClientIdentifier = "Mist"
- Version = "0.8.6"
+ Version = "0.9.0"
)
var ethereum *eth.Ethereum
diff --git a/cmd/mist/ui_lib.go b/cmd/mist/ui_lib.go
index 4fa6e8e55..187d5b2d6 100644
--- a/cmd/mist/ui_lib.go
+++ b/cmd/mist/ui_lib.go
@@ -58,7 +58,8 @@ type UiLib struct {
}
func NewUiLib(engine *qml.Engine, eth *eth.Ethereum, assetPath string) *UiLib {
- lib := &UiLib{XEth: xeth.New(eth), engine: engine, eth: eth, assetPath: assetPath, jsEngine: javascript.NewJSRE(eth), filterCallbacks: make(map[int][]int)} //, filters: make(map[int]*xeth.JSFilter)}
+ x := xeth.New(eth, nil)
+ lib := &UiLib{XEth: x, engine: engine, eth: eth, assetPath: assetPath, jsEngine: javascript.NewJSRE(x), filterCallbacks: make(map[int][]int)} //, filters: make(map[int]*xeth.JSFilter)}
lib.filterManager = filter.NewFilterManager(eth.EventMux())
go lib.filterManager.Start()
@@ -90,24 +91,6 @@ func (self *UiLib) EvalJavascriptString(str string) string {
return fmt.Sprintf("%v", value)
}
-func (ui *UiLib) OpenQml(path string) {
- container := NewQmlApplication(path[7:], ui)
- app := NewExtApplication(container, ui)
-
- go app.run()
-}
-
-func (ui *UiLib) OpenHtml(path string) {
- container := NewHtmlApplication(path, ui)
- app := NewExtApplication(container, ui)
-
- go app.run()
-}
-
-func (ui *UiLib) OpenBrowser() {
- ui.OpenHtml("file://" + ui.AssetPath("ext/home.html"))
-}
-
func (ui *UiLib) Muted(content string) {
component, err := ui.engine.LoadFile(ui.AssetPath("qml/muted.qml"))
if err != nil {
diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go
index 723cfa887..a77c6ad4d 100644
--- a/cmd/utils/cmd.go
+++ b/cmd/utils/cmd.go
@@ -27,12 +27,12 @@ import (
"os/signal"
"regexp"
+ "github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/eth"
"github.com/ethereum/go-ethereum/ethutil"
"github.com/ethereum/go-ethereum/logger"
- "github.com/ethereum/go-ethereum/miner"
"github.com/ethereum/go-ethereum/rlp"
rpchttp "github.com/ethereum/go-ethereum/rpc/http"
"github.com/ethereum/go-ethereum/state"
@@ -109,13 +109,20 @@ func InitConfig(vmType int, ConfigFile string, Datadir string, EnvPrefix string)
func exit(err error) {
status := 0
if err != nil {
- clilogger.Errorln("Fatal: ", err)
+ fmt.Fprintln(os.Stderr, "Fatal: ", err)
status = 1
}
logger.Flush()
os.Exit(status)
}
+// Fatalf formats a message to standard output and exits the program.
+func Fatalf(format string, args ...interface{}) {
+ fmt.Fprintf(os.Stderr, "Fatal: "+format+"\n", args...)
+ logger.Flush()
+ os.Exit(1)
+}
+
func StartEthereum(ethereum *eth.Ethereum) {
clilogger.Infoln("Starting ", ethereum.Name())
if err := ethereum.Start(); err != nil {
@@ -128,7 +135,6 @@ func StartEthereum(ethereum *eth.Ethereum) {
}
func KeyTasks(keyManager *crypto.KeyManager, KeyRing string, GenAddr bool, SecretFile string, ExportDir string, NonInteractive bool) {
-
var err error
switch {
case GenAddr:
@@ -161,7 +167,7 @@ func KeyTasks(keyManager *crypto.KeyManager, KeyRing string, GenAddr bool, Secre
func StartRpc(ethereum *eth.Ethereum, RpcListenAddress string, RpcPort int) {
var err error
- ethereum.RpcServer, err = rpchttp.NewRpcHttpServer(xeth.New(ethereum), RpcListenAddress, RpcPort)
+ ethereum.RpcServer, err = rpchttp.NewRpcHttpServer(xeth.New(ethereum, nil), RpcListenAddress, RpcPort)
if err != nil {
clilogger.Errorf("Could not start RPC interface (port %v): %v", RpcPort, err)
} else {
@@ -169,32 +175,6 @@ func StartRpc(ethereum *eth.Ethereum, RpcListenAddress string, RpcPort int) {
}
}
-var gminer *miner.Miner
-
-func GetMiner() *miner.Miner {
- return gminer
-}
-
-func StartMining(ethereum *eth.Ethereum) bool {
- if !ethereum.Mining {
- ethereum.Mining = true
- addr := ethereum.KeyManager().Address()
-
- go func() {
- clilogger.Infoln("Start mining")
- if gminer == nil {
- gminer = miner.New(addr, ethereum, 4)
- }
- gminer.Start()
- }()
- RegisterInterrupt(func(os.Signal) {
- StopMining(ethereum)
- })
- return true
- }
- return false
-}
-
func FormatTransactionData(data string) []byte {
d := ethutil.StringToByteFunc(data, func(s string) (ret []byte) {
slice := regexp.MustCompile("\\n|\\s").Split(s, 1000000000)
@@ -208,18 +188,6 @@ func FormatTransactionData(data string) []byte {
return d
}
-func StopMining(ethereum *eth.Ethereum) bool {
- if ethereum.Mining && gminer != nil {
- gminer.Stop()
- clilogger.Infoln("Stopped mining")
- ethereum.Mining = false
-
- return true
- }
-
- return false
-}
-
// Replay block
func BlockDo(ethereum *eth.Ethereum, hash []byte) error {
block := ethereum.ChainManager().GetBlock(hash)
@@ -229,7 +197,7 @@ func BlockDo(ethereum *eth.Ethereum, hash []byte) error {
parent := ethereum.ChainManager().GetBlock(block.ParentHash())
- statedb := state.New(parent.Root(), ethereum.Db())
+ statedb := state.New(parent.Root(), ethereum.StateDb())
_, err := ethereum.BlockProcessor().TransitionState(statedb, parent, block, true)
if err != nil {
return err
@@ -239,24 +207,24 @@ func BlockDo(ethereum *eth.Ethereum, hash []byte) error {
}
-func ImportChain(ethereum *eth.Ethereum, fn string) error {
- clilogger.Infof("importing chain '%s'\n", fn)
+func ImportChain(chain *core.ChainManager, fn string) error {
+ fmt.Printf("importing chain '%s'\n", fn)
fh, err := os.OpenFile(fn, os.O_RDONLY, os.ModePerm)
if err != nil {
return err
}
defer fh.Close()
- var chain types.Blocks
- if err := rlp.Decode(fh, &chain); err != nil {
+ var blocks types.Blocks
+ if err := rlp.Decode(fh, &blocks); err != nil {
return err
}
- ethereum.ChainManager().Reset()
- if err := ethereum.ChainManager().InsertChain(chain); err != nil {
+ chain.Reset()
+ if err := chain.InsertChain(blocks); err != nil {
return err
}
- clilogger.Infof("imported %d blocks\n", len(chain))
+ fmt.Printf("imported %d blocks\n", len(blocks))
return nil
}
diff --git a/cmd/utils/flags.go b/cmd/utils/flags.go
new file mode 100644
index 000000000..88ff3558d
--- /dev/null
+++ b/cmd/utils/flags.go
@@ -0,0 +1,190 @@
+package utils
+
+import (
+ "crypto/ecdsa"
+ "path"
+ "runtime"
+
+ "github.com/codegangsta/cli"
+ "github.com/ethereum/go-ethereum/core"
+ "github.com/ethereum/go-ethereum/crypto"
+ "github.com/ethereum/go-ethereum/eth"
+ "github.com/ethereum/go-ethereum/ethdb"
+ "github.com/ethereum/go-ethereum/ethutil"
+ "github.com/ethereum/go-ethereum/event"
+ "github.com/ethereum/go-ethereum/logger"
+ "github.com/ethereum/go-ethereum/p2p"
+ "github.com/ethereum/go-ethereum/p2p/nat"
+)
+
+// These are all the command line flags we support.
+// If you add to this list, please remember to include the
+// flag in the appropriate command definition.
+//
+// The flags are defined here so their names and help texts
+// are the same for all commands.
+
+var (
+ // General settings
+ /*
+ VMTypeFlag = cli.IntFlag{
+ Name: "vm",
+ Usage: "Virtual Machine type: 0 is standard VM, 1 is debug VM",
+ }
+ */
+ VMDebugFlag = cli.BoolFlag{
+ Name: "vmdebug",
+ Usage: "Virtual Machine debug output",
+ }
+ KeyRingFlag = cli.StringFlag{
+ Name: "keyring",
+ Usage: "Name of keyring to be used",
+ Value: "",
+ }
+ KeyStoreFlag = cli.StringFlag{
+ Name: "keystore",
+ Usage: `Where to store keyrings: "db" or "file"`,
+ Value: "db",
+ }
+ DataDirFlag = cli.StringFlag{
+ Name: "datadir",
+ Usage: "Data directory to be used",
+ Value: ethutil.DefaultDataDir(),
+ }
+ MinerThreadsFlag = cli.IntFlag{
+ Name: "minerthreads",
+ Usage: "Number of miner threads",
+ Value: runtime.NumCPU(),
+ }
+ MiningEnabledFlag = cli.BoolFlag{
+ Name: "mine",
+ Usage: "Enable mining",
+ }
+
+ LogFileFlag = cli.StringFlag{
+ Name: "logfile",
+ Usage: "Send log output to a file",
+ }
+ LogLevelFlag = cli.IntFlag{
+ Name: "loglevel",
+ Usage: "0-5 (silent, error, warn, info, debug, debug detail)",
+ Value: int(logger.InfoLevel),
+ }
+ LogFormatFlag = cli.StringFlag{
+ Name: "logformat",
+ Usage: `"std" or "raw"`,
+ Value: "std",
+ }
+
+ // RPC settings
+ RPCEnabledFlag = cli.BoolFlag{
+ Name: "rpc",
+ Usage: "Whether RPC server is enabled",
+ }
+ RPCListenAddrFlag = cli.StringFlag{
+ Name: "rpcaddr",
+ Usage: "Listening address for the JSON-RPC server",
+ Value: "127.0.0.1",
+ }
+ RPCPortFlag = cli.IntFlag{
+ Name: "rpcport",
+ Usage: "Port on which the JSON-RPC server should listen",
+ Value: 8545,
+ }
+
+ // Network Settings
+ MaxPeersFlag = cli.IntFlag{
+ Name: "maxpeers",
+ Usage: "Maximum number of network peers",
+ Value: 16,
+ }
+ ListenPortFlag = cli.IntFlag{
+ Name: "port",
+ Usage: "Network listening port",
+ Value: 30303,
+ }
+ BootnodesFlag = cli.StringFlag{
+ Name: "bootnodes",
+ Usage: "Space-separated enode URLs for discovery bootstrap",
+ Value: "",
+ }
+ NodeKeyFileFlag = cli.StringFlag{
+ Name: "nodekey",
+ Usage: "P2P node key file",
+ }
+ NodeKeyHexFlag = cli.StringFlag{
+ Name: "nodekeyhex",
+ Usage: "P2P node key as hex (for testing)",
+ }
+ NATFlag = cli.StringFlag{
+ Name: "nat",
+ Usage: "Port mapping mechanism (any|none|upnp|pmp|extip:<IP>)",
+ Value: "any",
+ }
+)
+
+func GetNAT(ctx *cli.Context) nat.Interface {
+ natif, err := nat.Parse(ctx.GlobalString(NATFlag.Name))
+ if err != nil {
+ Fatalf("Option %s: %v", NATFlag.Name, err)
+ }
+ return natif
+}
+
+func GetNodeKey(ctx *cli.Context) (key *ecdsa.PrivateKey) {
+ hex, file := ctx.GlobalString(NodeKeyHexFlag.Name), ctx.GlobalString(NodeKeyFileFlag.Name)
+ var err error
+ switch {
+ case file != "" && hex != "":
+ Fatalf("Options %q and %q are mutually exclusive", NodeKeyFileFlag.Name, NodeKeyHexFlag.Name)
+ case file != "":
+ if key, err = crypto.LoadECDSA(file); err != nil {
+ Fatalf("Option %q: %v", NodeKeyFileFlag.Name, err)
+ }
+ case hex != "":
+ if key, err = crypto.HexToECDSA(hex); err != nil {
+ Fatalf("Option %q: %v", NodeKeyHexFlag.Name, err)
+ }
+ }
+ return key
+}
+
+func GetEthereum(clientID, version string, ctx *cli.Context) *eth.Ethereum {
+ ethereum, err := eth.New(&eth.Config{
+ Name: p2p.MakeName(clientID, version),
+ KeyStore: ctx.GlobalString(KeyStoreFlag.Name),
+ DataDir: ctx.GlobalString(DataDirFlag.Name),
+ LogFile: ctx.GlobalString(LogFileFlag.Name),
+ LogLevel: ctx.GlobalInt(LogLevelFlag.Name),
+ LogFormat: ctx.GlobalString(LogFormatFlag.Name),
+ MinerThreads: ctx.GlobalInt(MinerThreadsFlag.Name),
+ VmDebug: ctx.GlobalBool(VMDebugFlag.Name),
+
+ MaxPeers: ctx.GlobalInt(MaxPeersFlag.Name),
+ Port: ctx.GlobalString(ListenPortFlag.Name),
+ NAT: GetNAT(ctx),
+ NodeKey: GetNodeKey(ctx),
+ KeyRing: ctx.GlobalString(KeyRingFlag.Name),
+ Shh: true,
+ Dial: true,
+ BootNodes: ctx.GlobalString(BootnodesFlag.Name),
+ })
+ if err != nil {
+ exit(err)
+ }
+ return ethereum
+}
+
+func GetChain(ctx *cli.Context) (*core.ChainManager, ethutil.Database, ethutil.Database) {
+ dataDir := ctx.GlobalString(DataDirFlag.Name)
+ blockDb, err := ethdb.NewLDBDatabase(path.Join(dataDir, "blockchain"))
+ if err != nil {
+ Fatalf("Could not open database: %v", err)
+ }
+
+ stateDb, err := ethdb.NewLDBDatabase(path.Join(dataDir, "state"))
+ if err != nil {
+ Fatalf("Could not open database: %v", err)
+ }
+ return core.NewChainManager(blockDb, stateDb, new(event.TypeMux)), blockDb, stateDb
+}