From 50e1dcc43a3eb4d32147d10c29c0edeadeca6f78 Mon Sep 17 00:00:00 2001 From: zelig Date: Sun, 14 Dec 2014 18:23:48 +0000 Subject: import eth pkg --- cmd/ethereum/cmd.go | 2 +- cmd/ethereum/repl/repl.go | 2 +- cmd/utils/websockets.go | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'cmd') diff --git a/cmd/ethereum/cmd.go b/cmd/ethereum/cmd.go index 8710d6136..d8b9ea487 100644 --- a/cmd/ethereum/cmd.go +++ b/cmd/ethereum/cmd.go @@ -21,9 +21,9 @@ import ( "io/ioutil" "os" - "github.com/ethereum/go-ethereum" "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" ) diff --git a/cmd/ethereum/repl/repl.go b/cmd/ethereum/repl/repl.go index a5146fecd..4a7880ff4 100644 --- a/cmd/ethereum/repl/repl.go +++ b/cmd/ethereum/repl/repl.go @@ -24,7 +24,7 @@ import ( "os" "path" - "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/javascript" "github.com/ethereum/go-ethereum/logger" diff --git a/cmd/utils/websockets.go b/cmd/utils/websockets.go index d3ba50e78..29f9b8aeb 100644 --- a/cmd/utils/websockets.go +++ b/cmd/utils/websockets.go @@ -1,7 +1,7 @@ package utils import ( - "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/websocket" "github.com/ethereum/go-ethereum/xeth" -- cgit v1.2.3 From ae7c1e3e55610cc28bb4f79ede5660dd89c019c5 Mon Sep 17 00:00:00 2001 From: zelig Date: Sun, 14 Dec 2014 18:26:13 +0000 Subject: adapt to new backend - eth p2p pkgs - new Ethereum initialiser - no caps param - use nat type - add NatType func to map nat type string to p2p.NAT - add pubkey to client identity --- cmd/utils/cmd.go | 38 ++++++++++++++++++++++++-------------- 1 file changed, 24 insertions(+), 14 deletions(-) (limited to 'cmd') diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go index db7bcd35e..24d5970bd 100644 --- a/cmd/utils/cmd.go +++ b/cmd/utils/cmd.go @@ -4,23 +4,23 @@ import ( "fmt" "io" "log" + "net" "os" "os/signal" "path" "path/filepath" "regexp" "runtime" - "time" "bitbucket.org/kardianos/osext" - "github.com/ethereum/go-ethereum" "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/logger" "github.com/ethereum/go-ethereum/miner" + "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/rpc" - "github.com/ethereum/go-ethereum/wire" "github.com/ethereum/go-ethereum/xeth" ) @@ -144,17 +144,32 @@ func NewDatabase() ethutil.Database { return db } -func NewClientIdentity(clientIdentifier, version, customIdentifier string) *wire.SimpleClientIdentity { - return wire.NewSimpleClientIdentity(clientIdentifier, version, customIdentifier) +func NewClientIdentity(clientIdentifier, version, customIdentifier string, pubkey string) *p2p.SimpleClientIdentity { + return p2p.NewSimpleClientIdentity(clientIdentifier, version, customIdentifier, pubkey) } -func NewEthereum(db ethutil.Database, clientIdentity wire.ClientIdentity, keyManager *crypto.KeyManager, usePnp bool, OutboundPort string, MaxPeer int) *eth.Ethereum { - ethereum, err := eth.New(db, clientIdentity, keyManager, eth.CapDefault, usePnp) +func NatType(natType string, gateway string) (nat p2p.NAT) { + switch natType { + case "UPNP": + nat = p2p.UPNP() + case "PMP": + ip := net.ParseIP(gateway) + if ip != nil { + clilogger.Fatalf("bad PMP gateway '%s'", gateway) + } + nat = p2p.PMP(ip) + case "": + default: + clilogger.Fatalf("unrecognised NAT type '%s'", natType) + } + return +} + +func NewEthereum(db ethutil.Database, clientIdentity p2p.ClientIdentity, keyManager *crypto.KeyManager, nat p2p.NAT, OutboundPort string, MaxPeer int) *eth.Ethereum { + ethereum, err := eth.New(db, clientIdentity, keyManager, nat, OutboundPort, MaxPeer) if err != nil { clilogger.Fatalln("eth start err:", err) } - ethereum.Port = OutboundPort - ethereum.MaxPeers = MaxPeer return ethereum } @@ -268,11 +283,6 @@ func StartMining(ethereum *eth.Ethereum) bool { if gminer == nil { gminer = miner.New(addr, ethereum) } - // Give it some time to connect with peers - time.Sleep(3 * time.Second) - for !ethereum.IsUpToDate() { - time.Sleep(5 * time.Second) - } gminer.Start() }() RegisterInterrupt(func(os.Signal) { -- cgit v1.2.3 From d9b16c1197f607a52ad62c71425b690bee973c3f Mon Sep 17 00:00:00 2001 From: zelig Date: Sun, 14 Dec 2014 18:29:05 +0000 Subject: new cli options - nat UPNP|PMP - gateway for PMP NAT - obsolete usepnp - add pubkey to client identity --- cmd/ethereum/flags.go | 6 ++++-- cmd/ethereum/main.go | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) (limited to 'cmd') diff --git a/cmd/ethereum/flags.go b/cmd/ethereum/flags.go index 783944cf2..0bea73794 100644 --- a/cmd/ethereum/flags.go +++ b/cmd/ethereum/flags.go @@ -38,7 +38,8 @@ var ( StartRpc bool StartWebSockets bool RpcPort int - UseUPnP bool + NatType string + PMPGateway string OutboundPort string ShowGenesis bool AddPeer string @@ -84,7 +85,8 @@ func Init() { flag.StringVar(&KeyRing, "keyring", "", "identifier for keyring to use") flag.StringVar(&KeyStore, "keystore", "db", "system to store keyrings: db|file (db)") flag.StringVar(&OutboundPort, "port", "30303", "listening port") - flag.BoolVar(&UseUPnP, "upnp", false, "enable UPnP support") + flag.StringVar(&NatType, "nat", "", "nat support (UPNP|PMP)") + flag.StringVar(&PMPGateway, "gateway", "", "PMP gateway IP") flag.IntVar(&MaxPeer, "maxpeer", 10, "maximum desired peers") flag.IntVar(&RpcPort, "rpcport", 8080, "port to start json-rpc server on") flag.BoolVar(&StartRpc, "rpc", false, "start rpc server") diff --git a/cmd/ethereum/main.go b/cmd/ethereum/main.go index 43551fb3a..4f87ef17b 100644 --- a/cmd/ethereum/main.go +++ b/cmd/ethereum/main.go @@ -69,9 +69,9 @@ func main() { // create, import, export keys utils.KeyTasks(keyManager, KeyRing, GenAddr, SecretFile, ExportDir, NonInteractive) - clientIdentity := utils.NewClientIdentity(ClientIdentifier, Version, Identifier) + clientIdentity := utils.NewClientIdentity(ClientIdentifier, Version, Identifier, string(keyManager.PublicKey())) - ethereum := utils.NewEthereum(db, clientIdentity, keyManager, UseUPnP, OutboundPort, MaxPeer) + ethereum := utils.NewEthereum(db, clientIdentity, keyManager, utils.NatType(NatType, PMPGateway), OutboundPort, MaxPeer) if Dump { var block *types.Block -- cgit v1.2.3 From 61940b2275a8f3c77d906947b2d1126bb6c3b21d Mon Sep 17 00:00:00 2001 From: zelig Date: Sun, 14 Dec 2014 19:55:52 +0000 Subject: adapt cmd/cli to new backend - new flag nat for nat support UPNP|PMP - new flag pmp for PMP gateway IP - add NatType to utils/cmd to get p2p.NAT from nat type string - obsolete usepnp flag - get rid of IsUpToDate and sleep in miner start - ethereum constructor takes nat type, port, maxpeer - add pubkey arg to client identity --- cmd/ethereum/flags.go | 5 +++++ cmd/utils/cmd.go | 9 +++++++++ 2 files changed, 14 insertions(+) (limited to 'cmd') diff --git a/cmd/ethereum/flags.go b/cmd/ethereum/flags.go index 0bea73794..e709ecf50 100644 --- a/cmd/ethereum/flags.go +++ b/cmd/ethereum/flags.go @@ -85,8 +85,13 @@ func Init() { flag.StringVar(&KeyRing, "keyring", "", "identifier for keyring to use") flag.StringVar(&KeyStore, "keystore", "db", "system to store keyrings: db|file (db)") flag.StringVar(&OutboundPort, "port", "30303", "listening port") +<<<<<<< HEAD flag.StringVar(&NatType, "nat", "", "nat support (UPNP|PMP)") flag.StringVar(&PMPGateway, "gateway", "", "PMP gateway IP") +======= + flag.StringVar(&NatType, "nat", "", "NAT support (UPNP|PMP) (none)") + flag.StringVar(&PMPGateway, "pmp", "", "Gateway IP for PMP") +>>>>>>> adapt cmd/cli to new backend flag.IntVar(&MaxPeer, "maxpeer", 10, "maximum desired peers") flag.IntVar(&RpcPort, "rpcport", 8080, "port to start json-rpc server on") flag.BoolVar(&StartRpc, "rpc", false, "start rpc server") diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go index 24d5970bd..867ef5e37 100644 --- a/cmd/utils/cmd.go +++ b/cmd/utils/cmd.go @@ -154,13 +154,22 @@ func NatType(natType string, gateway string) (nat p2p.NAT) { nat = p2p.UPNP() case "PMP": ip := net.ParseIP(gateway) +<<<<<<< HEAD if ip != nil { clilogger.Fatalf("bad PMP gateway '%s'", gateway) +======= + if ip == nil { + clilogger.Fatalln("cannot resolve PMP gateway IP %s", gateway) +>>>>>>> adapt cmd/cli to new backend } nat = p2p.PMP(ip) case "": default: +<<<<<<< HEAD clilogger.Fatalf("unrecognised NAT type '%s'", natType) +======= + clilogger.Fatalln("unrecognised NAT type %s", natType) +>>>>>>> adapt cmd/cli to new backend } return } -- cgit v1.2.3 From 72290f67fee2be183981c9672d830040466187bd Mon Sep 17 00:00:00 2001 From: zelig Date: Sun, 14 Dec 2014 20:57:29 +0000 Subject: resolve merge conflict hell --- cmd/ethereum/flags.go | 5 ----- cmd/utils/cmd.go | 11 +---------- 2 files changed, 1 insertion(+), 15 deletions(-) (limited to 'cmd') diff --git a/cmd/ethereum/flags.go b/cmd/ethereum/flags.go index e709ecf50..556735491 100644 --- a/cmd/ethereum/flags.go +++ b/cmd/ethereum/flags.go @@ -85,13 +85,8 @@ func Init() { flag.StringVar(&KeyRing, "keyring", "", "identifier for keyring to use") flag.StringVar(&KeyStore, "keystore", "db", "system to store keyrings: db|file (db)") flag.StringVar(&OutboundPort, "port", "30303", "listening port") -<<<<<<< HEAD - flag.StringVar(&NatType, "nat", "", "nat support (UPNP|PMP)") - flag.StringVar(&PMPGateway, "gateway", "", "PMP gateway IP") -======= flag.StringVar(&NatType, "nat", "", "NAT support (UPNP|PMP) (none)") flag.StringVar(&PMPGateway, "pmp", "", "Gateway IP for PMP") ->>>>>>> adapt cmd/cli to new backend flag.IntVar(&MaxPeer, "maxpeer", 10, "maximum desired peers") flag.IntVar(&RpcPort, "rpcport", 8080, "port to start json-rpc server on") flag.BoolVar(&StartRpc, "rpc", false, "start rpc server") diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go index 867ef5e37..3e3ac617a 100644 --- a/cmd/utils/cmd.go +++ b/cmd/utils/cmd.go @@ -154,22 +154,13 @@ func NatType(natType string, gateway string) (nat p2p.NAT) { nat = p2p.UPNP() case "PMP": ip := net.ParseIP(gateway) -<<<<<<< HEAD - if ip != nil { - clilogger.Fatalf("bad PMP gateway '%s'", gateway) -======= if ip == nil { - clilogger.Fatalln("cannot resolve PMP gateway IP %s", gateway) ->>>>>>> adapt cmd/cli to new backend + clilogger.Fatalf("cannot resolve PMP gateway IP %s", gateway) } nat = p2p.PMP(ip) case "": default: -<<<<<<< HEAD clilogger.Fatalf("unrecognised NAT type '%s'", natType) -======= - clilogger.Fatalln("unrecognised NAT type %s", natType) ->>>>>>> adapt cmd/cli to new backend } return } -- cgit v1.2.3 From 96272e19a6b7a3163ec53f45e04407e9d2ff8414 Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 15 Dec 2014 12:34:06 +0100 Subject: removed filter manager from base --- cmd/mist/ui_lib.go | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'cmd') diff --git a/cmd/mist/ui_lib.go b/cmd/mist/ui_lib.go index fdbde50fd..d5578645f 100644 --- a/cmd/mist/ui_lib.go +++ b/cmd/mist/ui_lib.go @@ -24,7 +24,6 @@ import ( "strconv" "strings" - "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" @@ -64,6 +63,7 @@ type UiLib struct { func NewUiLib(engine *qml.Engine, eth *eth.Ethereum, assetPath string) *UiLib { lib := &UiLib{JSXEth: xeth.NewJSXEth(eth), engine: engine, eth: eth, assetPath: assetPath, jsEngine: javascript.NewJSRE(eth), filterCallbacks: make(map[int][]int)} //, filters: make(map[int]*xeth.JSFilter)} lib.miner = miner.New(eth.KeyManager().Address(), eth) + //eth.filterManager = filter.NewFilterManager(eth.EventMux()) return lib } @@ -372,3 +372,12 @@ func (self *UiLib) ToggleMining() bool { return false } } + +/* +// XXX Refactor me & MOVE +func (self *Ethereum) InstallFilter(filter *core.Filter) (id int) { + return self.filterManager.InstallFilter(filter) +} +func (self *Ethereum) UninstallFilter(id int) { self.filterManager.UninstallFilter(id) } +func (self *Ethereum) GetFilter(id int) *core.Filter { return self.filterManager.GetFilter(id) } +*/ -- cgit v1.2.3 From 56dac74f71d4d1fffa3e240c7d3cee803dec788d Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 15 Dec 2014 13:00:09 +0100 Subject: made mist in a compilable, workable state using the new refactored packages --- cmd/mist/flags.go | 4 ++++ cmd/mist/gui.go | 36 +++++++++++++++++------------------- cmd/mist/main.go | 6 +++--- cmd/mist/ui_lib.go | 18 +++++++++++------- 4 files changed, 35 insertions(+), 29 deletions(-) (limited to 'cmd') diff --git a/cmd/mist/flags.go b/cmd/mist/flags.go index 2ae0a0487..1d77532d9 100644 --- a/cmd/mist/flags.go +++ b/cmd/mist/flags.go @@ -36,10 +36,12 @@ var ( Identifier string KeyRing string KeyStore string + PMPGateway string StartRpc bool StartWebSockets bool RpcPort int UseUPnP bool + NatType string OutboundPort string ShowGenesis bool AddPeer string @@ -111,10 +113,12 @@ func Init() { flag.BoolVar(&NonInteractive, "y", false, "non-interactive mode (say yes to confirmations)") flag.BoolVar(&UseSeed, "seed", true, "seed peers") flag.BoolVar(&GenAddr, "genaddr", false, "create a new priv/pub key") + flag.StringVar(&NatType, "nat", "", "NAT support (UPNP|PMP) (none)") 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", defaultDataDir(), "specifies the datadir to use") + flag.StringVar(&PMPGateway, "pmp", "", "Gateway IP for PMP") 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)") diff --git a/cmd/mist/gui.go b/cmd/mist/gui.go index fe066e994..40499ad7f 100644 --- a/cmd/mist/gui.go +++ b/cmd/mist/gui.go @@ -30,14 +30,14 @@ import ( "strings" "time" - "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/core" "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/miner" - "github.com/ethereum/go-ethereum/wire" + "github.com/ethereum/go-ethereum/p2p" "github.com/ethereum/go-ethereum/xeth" "gopkg.in/qml.v1" ) @@ -97,7 +97,7 @@ type Gui struct { pipe *xeth.JSXEth Session string - clientIdentity *wire.SimpleClientIdentity + clientIdentity *p2p.SimpleClientIdentity config *ethutil.ConfigManager plugins map[string]plugin @@ -107,7 +107,7 @@ type Gui struct { } // Create GUI, but doesn't start it -func NewWindow(ethereum *eth.Ethereum, config *ethutil.ConfigManager, clientIdentity *wire.SimpleClientIdentity, session string, logLevel int) *Gui { +func NewWindow(ethereum *eth.Ethereum, config *ethutil.ConfigManager, clientIdentity *p2p.SimpleClientIdentity, session string, logLevel int) *Gui { db, err := ethdb.NewLDBDatabase("tx_database") if err != nil { panic(err) @@ -409,8 +409,7 @@ func (gui *Gui) update() { miningLabel := gui.getObjectByName("miningLabel") events := gui.eth.EventMux().Subscribe( - eth.ChainSyncEvent{}, - eth.PeerListEvent{}, + //eth.PeerListEvent{}, core.NewBlockEvent{}, core.TxPreEvent{}, core.TxPostEvent{}, @@ -460,9 +459,6 @@ func (gui *Gui) update() { gui.setWalletValue(object.Balance(), nil) state.UpdateStateObject(object) - - case eth.PeerListEvent: - gui.setPeerInfo() } case <-peerUpdateTicker.C: @@ -472,16 +468,18 @@ func (gui *Gui) update() { lastBlockLabel.Set("text", statusText) miningLabel.Set("text", "Mining @ "+strconv.FormatInt(gui.uiLib.miner.GetPow().GetHashrate(), 10)+"Khash") - blockLength := gui.eth.BlockPool().BlocksProcessed - chainLength := gui.eth.BlockPool().ChainLength + /* + blockLength := gui.eth.BlockPool().BlocksProcessed + chainLength := gui.eth.BlockPool().ChainLength - var ( - pct float64 = 1.0 / float64(chainLength) * float64(blockLength) - dlWidget = gui.win.Root().ObjectByName("downloadIndicator") - dlLabel = gui.win.Root().ObjectByName("downloadLabel") - ) - dlWidget.Set("value", pct) - dlLabel.Set("text", fmt.Sprintf("%d / %d", blockLength, chainLength)) + var ( + pct float64 = 1.0 / float64(chainLength) * float64(blockLength) + dlWidget = gui.win.Root().ObjectByName("downloadIndicator") + dlLabel = gui.win.Root().ObjectByName("downloadLabel") + ) + dlWidget.Set("value", pct) + dlLabel.Set("text", fmt.Sprintf("%d / %d", blockLength, chainLength)) + */ case <-statsUpdateTicker.C: gui.setStatsPane() @@ -509,7 +507,7 @@ Heap Alloc: %d CGNext: %x NumGC: %d `, Version, runtime.Version(), - eth.ProtocolVersion, eth.P2PVersion, + eth.ProtocolVersion, 2, runtime.NumCPU, runtime.NumGoroutine(), runtime.NumCgoCall(), memStats.Alloc, memStats.HeapAlloc, memStats.NextGC, memStats.NumGC, diff --git a/cmd/mist/main.go b/cmd/mist/main.go index 14336b4e8..1c0af5d8c 100644 --- a/cmd/mist/main.go +++ b/cmd/mist/main.go @@ -23,8 +23,8 @@ import ( "runtime" "time" - "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/cmd/utils" + "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/logger" "gopkg.in/qml.v1" ) @@ -58,8 +58,8 @@ func run() error { // create, import, export keys utils.KeyTasks(keyManager, KeyRing, GenAddr, SecretFile, ExportDir, NonInteractive) - clientIdentity := utils.NewClientIdentity(ClientIdentifier, Version, Identifier) - ethereum = utils.NewEthereum(db, clientIdentity, keyManager, UseUPnP, OutboundPort, MaxPeer) + clientIdentity := utils.NewClientIdentity(ClientIdentifier, Version, Identifier, string(keyManager.PublicKey())) + ethereum := utils.NewEthereum(db, clientIdentity, keyManager, utils.NatType(NatType, PMPGateway), OutboundPort, MaxPeer) if ShowGenesis { utils.ShowGenesis(ethereum) diff --git a/cmd/mist/ui_lib.go b/cmd/mist/ui_lib.go index d5578645f..d34b527ce 100644 --- a/cmd/mist/ui_lib.go +++ b/cmd/mist/ui_lib.go @@ -27,7 +27,9 @@ import ( "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/event/filter" "github.com/ethereum/go-ethereum/javascript" "github.com/ethereum/go-ethereum/miner" "github.com/ethereum/go-ethereum/state" @@ -56,6 +58,7 @@ type UiLib struct { jsEngine *javascript.JSRE filterCallbacks map[int][]int + filterManager *filter.FilterManager miner *miner.Miner } @@ -63,7 +66,7 @@ type UiLib struct { func NewUiLib(engine *qml.Engine, eth *eth.Ethereum, assetPath string) *UiLib { lib := &UiLib{JSXEth: xeth.NewJSXEth(eth), engine: engine, eth: eth, assetPath: assetPath, jsEngine: javascript.NewJSRE(eth), filterCallbacks: make(map[int][]int)} //, filters: make(map[int]*xeth.JSFilter)} lib.miner = miner.New(eth.KeyManager().Address(), eth) - //eth.filterManager = filter.NewFilterManager(eth.EventMux()) + lib.filterManager = filter.NewFilterManager(eth.EventMux()) return lib } @@ -123,7 +126,8 @@ func (self *UiLib) LookupAddress(name string) string { } func (self *UiLib) PastPeers() *ethutil.List { - return ethutil.NewList(eth.PastPeers()) + return ethutil.NewList([]string{}) + //return ethutil.NewList(eth.PastPeers()) } func (self *UiLib) ImportTx(rlpTx string) { @@ -191,7 +195,7 @@ func (ui *UiLib) Connect(button qml.Object) { } func (ui *UiLib) ConnectToPeer(addr string) { - ui.eth.ConnectToPeer(addr) + ui.eth.SuggestPeer(addr) } func (ui *UiLib) AssetPath(p string) string { @@ -226,7 +230,7 @@ func (self *UiLib) NewFilter(object map[string]interface{}) (id int) { filter.MessageCallback = func(messages state.Messages) { self.win.Root().Call("invokeFilterCallback", xeth.ToJSMessages(messages), id) } - id = self.eth.InstallFilter(filter) + id = self.filterManager.InstallFilter(filter) return id } @@ -239,12 +243,12 @@ func (self *UiLib) NewFilterString(typ string) (id int) { fmt.Println("QML is lagging") } } - id = self.eth.InstallFilter(filter) + id = self.filterManager.InstallFilter(filter) return id } func (self *UiLib) Messages(id int) *ethutil.List { - filter := self.eth.GetFilter(id) + filter := self.filterManager.GetFilter(id) if filter != nil { messages := xeth.ToJSMessages(filter.Find()) @@ -255,7 +259,7 @@ func (self *UiLib) Messages(id int) *ethutil.List { } func (self *UiLib) UninstallFilter(id int) { - self.eth.UninstallFilter(id) + self.filterManager.UninstallFilter(id) } func mapToTxParams(object map[string]interface{}) map[string]string { -- cgit v1.2.3 From 993280ec03a8bd8e108da7e222c98efa8482084b Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 15 Dec 2014 17:09:27 +0100 Subject: Added whisper test --- cmd/mist/assets/qml/views/whisper.qml | 46 +++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 cmd/mist/assets/qml/views/whisper.qml (limited to 'cmd') diff --git a/cmd/mist/assets/qml/views/whisper.qml b/cmd/mist/assets/qml/views/whisper.qml new file mode 100644 index 000000000..631f1981e --- /dev/null +++ b/cmd/mist/assets/qml/views/whisper.qml @@ -0,0 +1,46 @@ + +import QtQuick 2.0 +import QtQuick.Controls 1.0; +import QtQuick.Layouts 1.0; +import QtQuick.Dialogs 1.0; +import QtQuick.Window 2.1; +import QtQuick.Controls.Styles 1.1 +import Ethereum 1.0 + +Rectangle { + id: root + property var title: "Whisper" + property var iconSource: "../facet.png" + property var menuItem + + objectName: "whisperView" + anchors.fill: parent + + property var identity: "" + Component.onCompleted: { + identity = shh.newIdentity() + console.log("New identity:", identity) + } + + RowLayout { + TextField { + id: to + placeholderText: "To" + } + TextField { + id: data + placeholderText: "Data" + } + TextField { + id: topics + placeholderText: "topic1, topic2, topic3, ..." + } + + Button { + text: "Send" + onClicked: { + shh.post(eth.toHex(data.text), "", identity, topics.text.split(","), 500, 50) + } + } + } +} -- cgit v1.2.3 From 01a6db93241a01e98a0467b628423c9b5b1361cb Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 15 Dec 2014 17:14:02 +0100 Subject: Added whisper debug interface + whisper fixes --- cmd/mist/assets/qml/main.qml | 1 + cmd/mist/gui.go | 8 +++++++- cmd/mist/ui_lib.go | 4 ++++ 3 files changed, 12 insertions(+), 1 deletion(-) (limited to 'cmd') diff --git a/cmd/mist/assets/qml/main.qml b/cmd/mist/assets/qml/main.qml index 9f1f214a6..285757080 100644 --- a/cmd/mist/assets/qml/main.qml +++ b/cmd/mist/assets/qml/main.qml @@ -50,6 +50,7 @@ ApplicationWindow { addPlugin("./views/miner.qml", {noAdd: true, close: false, section: "ethereum", active: true}); addPlugin("./views/transaction.qml", {noAdd: true, close: false, section: "legacy"}); + addPlugin("./views/whisper.qml", {noAdd: true, close: false, section: "legacy"}); addPlugin("./views/chain.qml", {noAdd: true, close: false, section: "legacy"}); addPlugin("./views/pending_tx.qml", {noAdd: true, close: false, section: "legacy"}); addPlugin("./views/info.qml", {noAdd: true, close: false, section: "legacy"}); diff --git a/cmd/mist/gui.go b/cmd/mist/gui.go index 40499ad7f..ba031e6c3 100644 --- a/cmd/mist/gui.go +++ b/cmd/mist/gui.go @@ -38,6 +38,7 @@ import ( "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/miner" "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/ui/qt/qwhisper" "github.com/ethereum/go-ethereum/xeth" "gopkg.in/qml.v1" ) @@ -87,7 +88,8 @@ type Gui struct { eth *eth.Ethereum // The public Ethereum library - uiLib *UiLib + uiLib *UiLib + whisper *qwhisper.Whisper txDb *ethdb.LDBDatabase @@ -138,10 +140,12 @@ func (gui *Gui) Start(assetPath string) { gui.engine = qml.NewEngine() context := gui.engine.Context() gui.uiLib = NewUiLib(gui.engine, gui.eth, assetPath) + gui.whisper = qwhisper.New(gui.eth.Whisper()) // Expose the eth library and the ui library to QML context.SetVar("gui", gui) context.SetVar("eth", gui.uiLib) + context.SetVar("shh", gui.whisper) // Load the main QML interface data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) @@ -391,6 +395,8 @@ func (gui *Gui) update() { gui.setPeerInfo() }() + gui.whisper.SetView(gui.win.Root().ObjectByName("whisperView")) + for _, plugin := range gui.plugins { guilogger.Infoln("Loading plugin ", plugin.Name) diff --git a/cmd/mist/ui_lib.go b/cmd/mist/ui_lib.go index d34b527ce..68f333563 100644 --- a/cmd/mist/ui_lib.go +++ b/cmd/mist/ui_lib.go @@ -377,6 +377,10 @@ func (self *UiLib) ToggleMining() bool { } } +func (self *UiLib) ToHex(data string) string { + return "0x" + ethutil.Bytes2Hex([]byte(data)) +} + /* // XXX Refactor me & MOVE func (self *Ethereum) InstallFilter(filter *core.Filter) (id int) { -- cgit v1.2.3 From 52ca80bdd22004525dd1decbf7f9698380bff2be Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 15 Dec 2014 21:53:50 +0100 Subject: Fixed deref ptr The gui already waits and shuts down ethereum. There was no need to wait for an additional shutdown. --- cmd/mist/main.go | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'cmd') diff --git a/cmd/mist/main.go b/cmd/mist/main.go index 1c0af5d8c..3ea6e8e91 100644 --- a/cmd/mist/main.go +++ b/cmd/mist/main.go @@ -69,6 +69,10 @@ func run() error { utils.StartRpc(ethereum, RpcPort) } + if StartWebSockets { + utils.StartWebSockets(ethereum) + } + gui := NewWindow(ethereum, config, clientIdentity, KeyRing, LogLevel) gui.stdLog = stdLog @@ -100,16 +104,10 @@ func main() { utils.HandleInterrupt() - if StartWebSockets { - utils.StartWebSockets(ethereum) - } - // we need to run the interrupt callbacks in case gui is closed // this skips if we got here by actual interrupt stopping the GUI if !interrupted { utils.RunInterruptCallbacks(os.Interrupt) } - // this blocks the thread - ethereum.WaitForShutdown() logger.Flush() } -- cgit v1.2.3 From 52b54631a47dfa46742635be178f2f8d33dd9f41 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 16 Dec 2014 19:55:57 +0100 Subject: Whisper watches fixes --- cmd/mist/assets/qml/views/whisper.qml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'cmd') diff --git a/cmd/mist/assets/qml/views/whisper.qml b/cmd/mist/assets/qml/views/whisper.qml index 631f1981e..b50841ba5 100644 --- a/cmd/mist/assets/qml/views/whisper.qml +++ b/cmd/mist/assets/qml/views/whisper.qml @@ -20,6 +20,8 @@ Rectangle { Component.onCompleted: { identity = shh.newIdentity() console.log("New identity:", identity) + + var t = shh.watch({topics: ["chat"]}) } RowLayout { @@ -35,7 +37,6 @@ Rectangle { id: topics placeholderText: "topic1, topic2, topic3, ..." } - Button { text: "Send" onClicked: { -- cgit v1.2.3 From 2d09e67713757e2a80eb614562c97f962af36cf7 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 18 Dec 2014 13:17:24 +0100 Subject: Updated to new methods --- cmd/ethereum/main.go | 2 +- cmd/mist/debugger.go | 2 +- cmd/mist/gui.go | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) (limited to 'cmd') diff --git a/cmd/ethereum/main.go b/cmd/ethereum/main.go index 43551fb3a..9efc8e9dc 100644 --- a/cmd/ethereum/main.go +++ b/cmd/ethereum/main.go @@ -77,7 +77,7 @@ func main() { var block *types.Block if len(DumpHash) == 0 && DumpNumber == -1 { - block = ethereum.ChainManager().CurrentBlock + block = ethereum.ChainManager().CurrentBlock() } else if len(DumpHash) > 0 { block = ethereum.ChainManager().GetBlock(ethutil.Hex2Bytes(DumpHash)) } else { diff --git a/cmd/mist/debugger.go b/cmd/mist/debugger.go index d7c584eab..a7a286e23 100644 --- a/cmd/mist/debugger.go +++ b/cmd/mist/debugger.go @@ -149,7 +149,7 @@ func (self *DebuggerWindow) Debug(valueStr, gasStr, gasPriceStr, scriptStr, data self.SetAsm(script) - block := self.lib.eth.ChainManager().CurrentBlock + block := self.lib.eth.ChainManager().CurrentBlock() env := utils.NewEnv(statedb, block, account.Address(), value) diff --git a/cmd/mist/gui.go b/cmd/mist/gui.go index fe066e994..773688ffc 100644 --- a/cmd/mist/gui.go +++ b/cmd/mist/gui.go @@ -246,7 +246,7 @@ func (gui *Gui) CreateAndSetPrivKey() (string, string, string, string) { } func (gui *Gui) setInitialChain(ancientBlocks bool) { - sBlk := gui.eth.ChainManager().LastBlockHash + sBlk := gui.eth.ChainManager().LastBlockHash() blk := gui.eth.ChainManager().GetBlock(sBlk) for ; blk != nil; blk = gui.eth.ChainManager().GetBlock(sBlk) { sBlk = blk.PrevHash @@ -468,7 +468,7 @@ func (gui *Gui) update() { case <-peerUpdateTicker.C: gui.setPeerInfo() case <-generalUpdateTicker.C: - statusText := "#" + gui.eth.ChainManager().CurrentBlock.Number.String() + statusText := "#" + gui.eth.ChainManager().CurrentBlock().Number.String() lastBlockLabel.Set("text", statusText) miningLabel.Set("text", "Mining @ "+strconv.FormatInt(gui.uiLib.miner.GetPow().GetHashrate(), 10)+"Khash") -- cgit v1.2.3 From db494170dc819b1eb0d267b6e1ab36c6cfb63569 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 18 Dec 2014 15:18:13 +0100 Subject: Created generic message (easy for testing) --- cmd/mist/gui.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'cmd') diff --git a/cmd/mist/gui.go b/cmd/mist/gui.go index 773688ffc..46f264f35 100644 --- a/cmd/mist/gui.go +++ b/cmd/mist/gui.go @@ -305,13 +305,13 @@ func (gui *Gui) insertTransaction(window string, tx *types.Transaction) { var ( ptx = xeth.NewJSTx(tx, pipe.World().State()) - send = nameReg.Storage(tx.Sender()) - rec = nameReg.Storage(tx.Recipient) + send = nameReg.Storage(tx.From()) + rec = nameReg.Storage(tx.To()) s, r string ) if tx.CreatesContract() { - rec = nameReg.Storage(tx.CreationAddress(pipe.World().State())) + rec = nameReg.Storage(core.AddressFromMessage(tx)) } if send.Len() != 0 { @@ -323,9 +323,9 @@ func (gui *Gui) insertTransaction(window string, tx *types.Transaction) { r = strings.Trim(rec.Str(), "\x00") } else { if tx.CreatesContract() { - r = ethutil.Bytes2Hex(tx.CreationAddress(pipe.World().State())) + r = ethutil.Bytes2Hex(core.AddressFromMessage(tx)) } else { - r = ethutil.Bytes2Hex(tx.Recipient) + r = ethutil.Bytes2Hex(tx.To()) } } ptx.Sender = s @@ -449,11 +449,11 @@ func (gui *Gui) update() { object := state.GetAccount(gui.address()) if bytes.Compare(tx.Sender(), gui.address()) == 0 { - object.SubAmount(tx.Value) + object.SubAmount(tx.Value()) gui.txDb.Put(tx.Hash(), tx.RlpEncode()) - } else if bytes.Compare(tx.Recipient, gui.address()) == 0 { - object.AddAmount(tx.Value) + } else if bytes.Compare(tx.To(), gui.address()) == 0 { + object.AddAmount(tx.Value()) gui.txDb.Put(tx.Hash(), tx.RlpEncode()) } -- cgit v1.2.3 From 5ad473d7581b92811c3a3e035274a82fc5568f57 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 18 Dec 2014 15:33:22 +0100 Subject: Moved methods to messages --- cmd/mist/gui.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'cmd') diff --git a/cmd/mist/gui.go b/cmd/mist/gui.go index 46f264f35..7775889cc 100644 --- a/cmd/mist/gui.go +++ b/cmd/mist/gui.go @@ -310,7 +310,7 @@ func (gui *Gui) insertTransaction(window string, tx *types.Transaction) { s, r string ) - if tx.CreatesContract() { + if core.MessageCreatesContract(tx) { rec = nameReg.Storage(core.AddressFromMessage(tx)) } @@ -322,7 +322,7 @@ func (gui *Gui) insertTransaction(window string, tx *types.Transaction) { if rec.Len() != 0 { r = strings.Trim(rec.Str(), "\x00") } else { - if tx.CreatesContract() { + if core.MessageCreatesContract(tx) { r = ethutil.Bytes2Hex(core.AddressFromMessage(tx)) } else { r = ethutil.Bytes2Hex(tx.To()) -- cgit v1.2.3 From 59ef6e36931c980ba15babfb3680514635faebf6 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 19 Dec 2014 00:18:52 +0100 Subject: Cleaned up objects --- cmd/utils/vm_env.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'cmd') diff --git a/cmd/utils/vm_env.go b/cmd/utils/vm_env.go index eb52602c4..461a797c2 100644 --- a/cmd/utils/vm_env.go +++ b/cmd/utils/vm_env.go @@ -49,9 +49,7 @@ func (self *VMEnv) Transfer(from, to vm.Account, amount *big.Int) error { } func (self *VMEnv) vm(addr, data []byte, gas, price, value *big.Int) *core.Execution { - evm := vm.New(self, vm.DebugVmTy) - - return core.NewExecution(evm, addr, data, gas, price, value) + return core.NewExecution(self, addr, data, gas, price, value) } func (self *VMEnv) Call(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) { -- cgit v1.2.3 From 88af879f7ae55249ff7a9669184b52a611e4fb20 Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 19 Dec 2014 01:18:22 +0100 Subject: version bump --- cmd/ethereum/main.go | 2 +- cmd/mist/main.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'cmd') diff --git a/cmd/ethereum/main.go b/cmd/ethereum/main.go index 9efc8e9dc..2a3c46054 100644 --- a/cmd/ethereum/main.go +++ b/cmd/ethereum/main.go @@ -30,7 +30,7 @@ import ( const ( ClientIdentifier = "Ethereum(G)" - Version = "0.7.9" + Version = "0.7.10" ) var clilogger = logger.NewLogger("CLI") diff --git a/cmd/mist/main.go b/cmd/mist/main.go index 14336b4e8..eaf0af0c7 100644 --- a/cmd/mist/main.go +++ b/cmd/mist/main.go @@ -31,7 +31,7 @@ import ( const ( ClientIdentifier = "Mist" - Version = "0.7.9" + Version = "0.7.10" ) var ethereum *eth.Ethereum -- cgit v1.2.3 From 5da5db5a0a149235c742748aa4b3b94d13d6910f Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 19 Dec 2014 13:34:21 +0100 Subject: Added authors --- cmd/mist/assets/qml/main.qml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'cmd') diff --git a/cmd/mist/assets/qml/main.qml b/cmd/mist/assets/qml/main.qml index 9f1f214a6..a08a8b4ef 100644 --- a/cmd/mist/assets/qml/main.qml +++ b/cmd/mist/assets/qml/main.qml @@ -786,8 +786,8 @@ ApplicationWindow { title: "About" minimumWidth: 350 maximumWidth: 350 - maximumHeight: 200 - minimumHeight: 200 + maximumHeight: 280 + minimumHeight: 280 Image { id: aboutIcon @@ -797,7 +797,7 @@ ApplicationWindow { smooth: true source: "../facet.png" x: 10 - y: 10 + y: 30 } Text { @@ -806,7 +806,7 @@ ApplicationWindow { anchors.top: parent.top anchors.topMargin: 30 font.pointSize: 12 - text: "

Mist (0.6.5)

Amalthea


Development

Jeffrey Wilcke
Viktor Trón

Building

Maran Hidskes" + text: "

Mist (0.7.10)


Development

Jeffrey Wilcke
Viktor Trón
Felix Lange
Taylor Gerring
Daniel Nagy

UX

Alex van de Sande
" } } -- cgit v1.2.3 From 0a9dc1536c5d776844d6947a0090ff7e1a7c6ab4 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sat, 20 Dec 2014 02:33:45 +0100 Subject: Increased peer from 10 to 30 --- cmd/ethereum/flags.go | 2 +- cmd/mist/flags.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'cmd') diff --git a/cmd/ethereum/flags.go b/cmd/ethereum/flags.go index 783944cf2..85aca47c3 100644 --- a/cmd/ethereum/flags.go +++ b/cmd/ethereum/flags.go @@ -85,7 +85,7 @@ func Init() { flag.StringVar(&KeyStore, "keystore", "db", "system to store keyrings: db|file (db)") flag.StringVar(&OutboundPort, "port", "30303", "listening port") flag.BoolVar(&UseUPnP, "upnp", false, "enable UPnP support") - flag.IntVar(&MaxPeer, "maxpeer", 10, "maximum desired peers") + flag.IntVar(&MaxPeer, "maxpeer", 30, "maximum desired peers") flag.IntVar(&RpcPort, "rpcport", 8080, "port to start json-rpc server on") flag.BoolVar(&StartRpc, "rpc", false, "start rpc server") flag.BoolVar(&StartWebSockets, "ws", false, "start websocket server") diff --git a/cmd/mist/flags.go b/cmd/mist/flags.go index 2ae0a0487..e49408181 100644 --- a/cmd/mist/flags.go +++ b/cmd/mist/flags.go @@ -104,7 +104,7 @@ func Init() { flag.StringVar(&KeyStore, "keystore", "db", "system to store keyrings: db|file (db)") flag.StringVar(&OutboundPort, "port", "30303", "listening port") flag.BoolVar(&UseUPnP, "upnp", true, "enable UPnP support") - flag.IntVar(&MaxPeer, "maxpeer", 10, "maximum desired peers") + flag.IntVar(&MaxPeer, "maxpeer", 30, "maximum desired peers") flag.IntVar(&RpcPort, "rpcport", 8080, "port to start json-rpc server on") flag.BoolVar(&StartRpc, "rpc", false, "start rpc server") flag.BoolVar(&StartWebSockets, "ws", false, "start websocket server") -- cgit v1.2.3 From 0e5aed63ddbda716ba7373bed7cfc083ec35ced1 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 21 Dec 2014 15:06:35 +0100 Subject: Updated QWhisper * changed api * general whisper debug interface --- cmd/mist/assets/qml/views/whisper.qml | 32 ++++++++++++++++++++++++++++++-- cmd/mist/ui_lib.go | 8 ++++++++ 2 files changed, 38 insertions(+), 2 deletions(-) (limited to 'cmd') diff --git a/cmd/mist/assets/qml/views/whisper.qml b/cmd/mist/assets/qml/views/whisper.qml index b50841ba5..b43ea4f8b 100644 --- a/cmd/mist/assets/qml/views/whisper.qml +++ b/cmd/mist/assets/qml/views/whisper.qml @@ -9,7 +9,7 @@ import Ethereum 1.0 Rectangle { id: root - property var title: "Whisper" + property var title: "Whisper Traffic" property var iconSource: "../facet.png" property var menuItem @@ -21,10 +21,22 @@ Rectangle { identity = shh.newIdentity() console.log("New identity:", identity) - var t = shh.watch({topics: ["chat"]}) + var t = shh.watch({}, root) + } + + function onMessage(message) { + whisperModel.insert(0, {data: JSON.stringify({from: message.from, payload: eth.toAscii(message.payload)})}) } RowLayout { + id: input + anchors { + left: parent.left + leftMargin: 20 + top: parent.top + topMargin: 20 + } + TextField { id: to placeholderText: "To" @@ -44,4 +56,20 @@ Rectangle { } } } + + TableView { + id: txTableView + anchors { + top: input.bottom + topMargin: 10 + bottom: parent.bottom + left: parent.left + right: parent.right + } + TableViewColumn{ role: "data" ; title: "Data" ; width: parent.width - 2 } + + model: ListModel { + id: whisperModel + } + } } diff --git a/cmd/mist/ui_lib.go b/cmd/mist/ui_lib.go index 68f333563..fd4ffcb84 100644 --- a/cmd/mist/ui_lib.go +++ b/cmd/mist/ui_lib.go @@ -381,6 +381,14 @@ func (self *UiLib) ToHex(data string) string { return "0x" + ethutil.Bytes2Hex([]byte(data)) } +func (self *UiLib) ToAscii(data string) string { + start := 0 + if len(data) > 1 && data[0:2] == "0x" { + start = 2 + } + return string(ethutil.Hex2Bytes(data[start:])) +} + /* // XXX Refactor me & MOVE func (self *Ethereum) InstallFilter(filter *core.Filter) (id int) { -- cgit v1.2.3 From 795b14330ad4399ef292835eac452d258dcd7464 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 21 Dec 2014 15:13:06 +0100 Subject: Fixed EVM environment. Closes #215 --- cmd/evm/main.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'cmd') diff --git a/cmd/evm/main.go b/cmd/evm/main.go index c6c986a04..2bdfdfa9f 100644 --- a/cmd/evm/main.go +++ b/cmd/evm/main.go @@ -141,9 +141,7 @@ func (self *VMEnv) Transfer(from, to vm.Account, amount *big.Int) error { } func (self *VMEnv) vm(addr, data []byte, gas, price, value *big.Int) *core.Execution { - evm := vm.New(self, vm.DebugVmTy) - - return core.NewExecution(evm, addr, data, gas, price, value) + return core.NewExecution(self, addr, data, gas, price, value) } func (self *VMEnv) Call(caller vm.ClosureRef, addr, data []byte, gas, price, value *big.Int) ([]byte, error) { -- cgit v1.2.3 From 8130df63caa719831aeb05f56683ea7439f4af0e Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 22 Dec 2014 10:58:28 +0100 Subject: updated whisper ui --- cmd/mist/assets/qml/views/whisper.qml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'cmd') diff --git a/cmd/mist/assets/qml/views/whisper.qml b/cmd/mist/assets/qml/views/whisper.qml index b43ea4f8b..80d401301 100644 --- a/cmd/mist/assets/qml/views/whisper.qml +++ b/cmd/mist/assets/qml/views/whisper.qml @@ -25,7 +25,7 @@ Rectangle { } function onMessage(message) { - whisperModel.insert(0, {data: JSON.stringify({from: message.from, payload: eth.toAscii(message.payload)})}) + whisperModel.insert(0, {from: message.from, payload: eth.toAscii(message.payload)}) } RowLayout { @@ -66,7 +66,8 @@ Rectangle { left: parent.left right: parent.right } - TableViewColumn{ role: "data" ; title: "Data" ; width: parent.width - 2 } + TableViewColumn{ id: fromRole; role: "from" ; title: "From"; width: 300 } + TableViewColumn{ role: "payload" ; title: "Payload" ; width: parent.width - fromRole.width - 2 } model: ListModel { id: whisperModel -- cgit v1.2.3 From a153b47c2be80bbfb38954c5eae310305d54120b Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 22 Dec 2014 11:56:34 +0100 Subject: moved --- cmd/mist/assets/qml/browser.qml | 414 ++++++++++++++++++++++++++++++++++++++++ cmd/mist/assets/qml/main.qml | 2 +- cmd/mist/assets/qml/webapp.qml | 413 --------------------------------------- 3 files changed, 415 insertions(+), 414 deletions(-) create mode 100644 cmd/mist/assets/qml/browser.qml delete mode 100644 cmd/mist/assets/qml/webapp.qml (limited to 'cmd') diff --git a/cmd/mist/assets/qml/browser.qml b/cmd/mist/assets/qml/browser.qml new file mode 100644 index 000000000..26fef0377 --- /dev/null +++ b/cmd/mist/assets/qml/browser.qml @@ -0,0 +1,414 @@ +import QtQuick 2.0 +import QtWebKit 3.0 +import QtWebKit.experimental 1.0 +import QtQuick.Controls 1.0; +import QtQuick.Controls.Styles 1.0 +import QtQuick.Layouts 1.0; +import QtQuick.Window 2.1; +import Ethereum 1.0 + +Rectangle { + id: window + property var title: "Browser" + property var iconSource: "../browser.png" + property var menuItem + + property alias url: webview.url + property alias webView: webview + + property var cleanPath: false + property var open: function(url) { + if(!window.cleanPath) { + var uri = url; + if(!/.*\:\/\/.*/.test(uri)) { + uri = "http://" + uri; + } + + var reg = /(^https?\:\/\/(?:www\.)?)([a-zA-Z0-9_\-]*\.eth)(.*)/ + + if(reg.test(uri)) { + uri.replace(reg, function(match, pre, domain, path) { + uri = pre; + + var lookup = eth.lookupDomain(domain.substring(0, domain.length - 4)); + var ip = []; + for(var i = 0, l = lookup.length; i < l; i++) { + ip.push(lookup.charCodeAt(i)) + } + + if(ip.length != 0) { + uri += lookup; + } else { + uri += domain; + } + + uri += path; + }); + } + + window.cleanPath = true; + + webview.url = uri; + + //uriNav.text = uri.text.replace(/(^https?\:\/\/(?:www\.)?)([a-zA-Z0-9_\-]*\.\w{2,3})(.*)/, "$1$2$3"); + uriNav.text = uri; + } else { + // Prevent inf loop. + window.cleanPath = false; + } + } + + Component.onCompleted: { + //webview.url = "http://etherian.io" + webview.url = "file:///Users/jeffrey/test.html" + } + + signal messages(var messages, int id); + onMessages: { + // Bit of a cheat to get proper JSON + var m = JSON.parse(JSON.parse(JSON.stringify(messages))) + webview.postEvent("messages", [m, id]); + } + + Item { + objectName: "root" + id: root + anchors.fill: parent + state: "inspectorShown" + + RowLayout { + id: navBar + height: 40 + anchors { + left: parent.left + right: parent.right + leftMargin: 7 + } + + Button { + id: back + onClicked: { + webview.goBack() + } + style: ButtonStyle { + background: Image { + source: "../back.png" + width: 30 + height: 30 + } + } + } + + TextField { + anchors { + left: back.right + right: toggleInspector.left + leftMargin: 5 + rightMargin: 5 + } + text: "http://etherian.io" + id: uriNav + y: parent.height / 2 - this.height / 2 + + Keys.onReturnPressed: { + webview.url = this.text; + } + } + + Button { + id: toggleInspector + anchors { + right: parent.right + } + iconSource: "../bug.png" + onClicked: { + if(inspector.visible == true){ + inspector.visible = false + }else{ + inspector.visible = true + inspector.url = webview.experimental.remoteInspectorUrl + } + } + } + } + + + WebView { + objectName: "webView" + id: webview + anchors { + left: parent.left + right: parent.right + bottom: parent.bottom + top: navBar.bottom + } + + //property var cleanPath: false + onNavigationRequested: { + window.open(request.url.toString()); + } + + function sendMessage(data) { + webview.experimental.postMessage(JSON.stringify(data)) + } + + + experimental.preferences.javascriptEnabled: true + experimental.preferences.navigatorQtObjectEnabled: true + experimental.preferences.developerExtrasEnabled: true + //experimental.userScripts: ["../ext/qt_messaging_adapter.js", "../ext/q.js", "../ext/big.js", "../ext/string.js", "../ext/html_messaging.js"] + experimental.userScripts: ["../ext/q.js", "../ext/eth.js/main.js", "../ext/eth.js/qt.js", "../ext/setup.js"] + experimental.onMessageReceived: { + console.log("[onMessageReceived]: ", message.data) + // TODO move to messaging.js + var data = JSON.parse(message.data) + + try { + switch(data.call) { + case "compile": + postData(data._id, eth.compile(data.args[0])) + break + + case "coinbase": + postData(data._id, eth.coinBase()) + + case "account": + postData(data._id, eth.key().address); + + case "isListening": + postData(data._id, eth.isListening()) + + break + + case "isMining": + postData(data._id, eth.isMining()) + + break + + case "peerCount": + postData(data._id, eth.peerCount()) + + break + + case "countAt": + require(1) + postData(data._id, eth.txCountAt(data.args[0])) + + break + + case "codeAt": + require(1) + var code = eth.codeAt(data.args[0]) + postData(data._id, code); + + break + + case "blockByNumber": + require(1) + var block = eth.blockByNumber(data.args[0]) + postData(data._id, block) + break + + case "blockByHash": + require(1) + var block = eth.blockByHash(data.args[0]) + postData(data._id, block) + break + + require(2) + var block = eth.blockByHash(data.args[0]) + postData(data._id, block.transactions[data.args[1]]) + break + + case "transactionByHash": + case "transactionByNumber": + require(2) + + var block; + if (data.call === "transactionByHash") + block = eth.blockByHash(data.args[0]) + else + block = eth.blockByNumber(data.args[0]) + + var tx = block.transactions.get(data.args[1]) + + postData(data._id, tx) + break + + case "uncleByHash": + case "uncleByNumber": + require(2) + + var block; + if (data.call === "uncleByHash") + block = eth.blockByHash(data.args[0]) + else + block = eth.blockByNumber(data.args[0]) + + var uncle = block.uncles.get(data.args[1]) + + postData(data._id, uncle) + + break + + case "transact": + require(5) + + var tx = eth.transact(data.args) + postData(data._id, tx) + + break + + case "stateAt": + require(2); + + var storage = eth.storageAt(data.args[0], data.args[1]); + postData(data._id, storage) + + break + + case "call": + require(1); + var ret = eth.call(data.args) + postData(data._id, ret) + break + + case "balanceAt": + require(1); + + postData(data._id, eth.balanceAt(data.args[0])); + break + + case "watch": + require(2) + eth.watch(data.args[0], data.args[1]) + + case "disconnect": + require(1) + postData(data._id, null) + break; + + case "messages": + require(1); + + var messages = JSON.parse(eth.getMessages(data.args[0])) + postData(data._id, messages) + break + + case "mutan": + require(1) + + var code = eth.compileMutan(data.args[0]) + postData(data._id, "0x"+code) + break; + + case "newFilterString": + require(1) + var id = eth.newFilterString(data.args[0]) + postData(data._id, id); + break; + + case "newFilter": + require(1) + var id = eth.newFilter(data.args[0]) + + postData(data._id, id); + break; + + case "getMessages": + require(1); + + var messages = eth.messages(data.args[0]); + var m = JSON.parse(JSON.parse(JSON.stringify(messages))) + postData(data._id, m); + + break; + + case "deleteFilter": + require(1); + eth.uninstallFilter(data.args[0]) + break; + } + } catch(e) { + console.log(data.call + ": " + e) + + postData(data._id, null); + } + } + + + function post(seed, data) { + postData(data._id, data) + } + + function require(args, num) { + if(args.length < num) { + throw("required argument count of "+num+" got "+args.length); + } + } + function postData(seed, data) { + webview.experimental.postMessage(JSON.stringify({data: data, _id: seed})) + } + function postEvent(event, data) { + webview.experimental.postMessage(JSON.stringify({data: data, _event: event})) + } + + function onWatchedCb(data, id) { + var messages = JSON.parse(data) + postEvent("watched:"+id, messages) + } + + function onNewBlockCb(block) { + postEvent("block:new", block) + } + function onObjectChangeCb(stateObject) { + postEvent("object:"+stateObject.address(), stateObject) + } + function onStorageChangeCb(storageObject) { + var ev = ["storage", storageObject.stateAddress, storageObject.address].join(":"); + postEvent(ev, [storageObject.address, storageObject.value]) + } + } + + + Rectangle { + id: sizeGrip + color: "gray" + visible: false + height: 10 + anchors { + left: root.left + right: root.right + } + y: Math.round(root.height * 2 / 3) + + MouseArea { + anchors.fill: parent + drag.target: sizeGrip + drag.minimumY: 0 + drag.maximumY: root.height + drag.axis: Drag.YAxis + } + } + + WebView { + id: inspector + visible: false + anchors { + left: root.left + right: root.right + top: sizeGrip.bottom + bottom: root.bottom + } + } + + states: [ + State { + name: "inspectorShown" + PropertyChanges { + target: inspector + } + } + ] + } +} diff --git a/cmd/mist/assets/qml/main.qml b/cmd/mist/assets/qml/main.qml index 65cea439a..06a7bc2a8 100644 --- a/cmd/mist/assets/qml/main.qml +++ b/cmd/mist/assets/qml/main.qml @@ -45,7 +45,7 @@ ApplicationWindow { // Takes care of loading all default plugins Component.onCompleted: { var wallet = addPlugin("./views/wallet.qml", {noAdd: true, close: false, section: "ethereum", active: true}); - var browser = addPlugin("./webapp.qml", {noAdd: true, close: false, section: "ethereum", active: true}); + var browser = addPlugin("./browser.qml", {noAdd: true, close: false, section: "ethereum", active: true}); root.browser = browser; addPlugin("./views/miner.qml", {noAdd: true, close: false, section: "ethereum", active: true}); diff --git a/cmd/mist/assets/qml/webapp.qml b/cmd/mist/assets/qml/webapp.qml deleted file mode 100644 index bd7399dc9..000000000 --- a/cmd/mist/assets/qml/webapp.qml +++ /dev/null @@ -1,413 +0,0 @@ -import QtQuick 2.0 -import QtWebKit 3.0 -import QtWebKit.experimental 1.0 -import QtQuick.Controls 1.0; -import QtQuick.Controls.Styles 1.0 -import QtQuick.Layouts 1.0; -import QtQuick.Window 2.1; -import Ethereum 1.0 - -Rectangle { - id: window - property var title: "Browser" - property var iconSource: "../browser.png" - property var menuItem - - property alias url: webview.url - property alias webView: webview - - property var cleanPath: false - property var open: function(url) { - if(!window.cleanPath) { - var uri = url; - if(!/.*\:\/\/.*/.test(uri)) { - uri = "http://" + uri; - } - - var reg = /(^https?\:\/\/(?:www\.)?)([a-zA-Z0-9_\-]*\.eth)(.*)/ - - if(reg.test(uri)) { - uri.replace(reg, function(match, pre, domain, path) { - uri = pre; - - var lookup = eth.lookupDomain(domain.substring(0, domain.length - 4)); - var ip = []; - for(var i = 0, l = lookup.length; i < l; i++) { - ip.push(lookup.charCodeAt(i)) - } - - if(ip.length != 0) { - uri += lookup; - } else { - uri += domain; - } - - uri += path; - }); - } - - window.cleanPath = true; - - webview.url = uri; - - //uriNav.text = uri.text.replace(/(^https?\:\/\/(?:www\.)?)([a-zA-Z0-9_\-]*\.\w{2,3})(.*)/, "$1$2$3"); - uriNav.text = uri; - } else { - // Prevent inf loop. - window.cleanPath = false; - } - } - - Component.onCompleted: { - webview.url = "http://etherian.io" - } - - signal messages(var messages, int id); - onMessages: { - // Bit of a cheat to get proper JSON - var m = JSON.parse(JSON.parse(JSON.stringify(messages))) - webview.postEvent("messages", [m, id]); - } - - Item { - objectName: "root" - id: root - anchors.fill: parent - state: "inspectorShown" - - RowLayout { - id: navBar - height: 40 - anchors { - left: parent.left - right: parent.right - leftMargin: 7 - } - - Button { - id: back - onClicked: { - webview.goBack() - } - style: ButtonStyle { - background: Image { - source: "../back.png" - width: 30 - height: 30 - } - } - } - - TextField { - anchors { - left: back.right - right: toggleInspector.left - leftMargin: 5 - rightMargin: 5 - } - text: "http://etherian.io" - id: uriNav - y: parent.height / 2 - this.height / 2 - - Keys.onReturnPressed: { - webview.url = this.text; - } - } - - Button { - id: toggleInspector - anchors { - right: parent.right - } - iconSource: "../bug.png" - onClicked: { - if(inspector.visible == true){ - inspector.visible = false - }else{ - inspector.visible = true - inspector.url = webview.experimental.remoteInspectorUrl - } - } - } - } - - - WebView { - objectName: "webView" - id: webview - anchors { - left: parent.left - right: parent.right - bottom: parent.bottom - top: navBar.bottom - } - - //property var cleanPath: false - onNavigationRequested: { - window.open(request.url.toString()); - } - - function sendMessage(data) { - webview.experimental.postMessage(JSON.stringify(data)) - } - - - experimental.preferences.javascriptEnabled: true - experimental.preferences.navigatorQtObjectEnabled: true - experimental.preferences.developerExtrasEnabled: true - //experimental.userScripts: ["../ext/qt_messaging_adapter.js", "../ext/q.js", "../ext/big.js", "../ext/string.js", "../ext/html_messaging.js"] - experimental.userScripts: ["../ext/q.js", "../ext/eth.js/main.js", "../ext/eth.js/qt.js", "../ext/setup.js"] - experimental.onMessageReceived: { - console.log("[onMessageReceived]: ", message.data) - // TODO move to messaging.js - var data = JSON.parse(message.data) - - try { - switch(data.call) { - case "compile": - postData(data._id, eth.compile(data.args[0])) - break - - case "coinbase": - postData(data._id, eth.coinBase()) - - case "account": - postData(data._id, eth.key().address); - - case "isListening": - postData(data._id, eth.isListening()) - - break - - case "isMining": - postData(data._id, eth.isMining()) - - break - - case "peerCount": - postData(data._id, eth.peerCount()) - - break - - case "countAt": - require(1) - postData(data._id, eth.txCountAt(data.args[0])) - - break - - case "codeAt": - require(1) - var code = eth.codeAt(data.args[0]) - postData(data._id, code); - - break - - case "blockByNumber": - require(1) - var block = eth.blockByNumber(data.args[0]) - postData(data._id, block) - break - - case "blockByHash": - require(1) - var block = eth.blockByHash(data.args[0]) - postData(data._id, block) - break - - require(2) - var block = eth.blockByHash(data.args[0]) - postData(data._id, block.transactions[data.args[1]]) - break - - case "transactionByHash": - case "transactionByNumber": - require(2) - - var block; - if (data.call === "transactionByHash") - block = eth.blockByHash(data.args[0]) - else - block = eth.blockByNumber(data.args[0]) - - var tx = block.transactions.get(data.args[1]) - - postData(data._id, tx) - break - - case "uncleByHash": - case "uncleByNumber": - require(2) - - var block; - if (data.call === "uncleByHash") - block = eth.blockByHash(data.args[0]) - else - block = eth.blockByNumber(data.args[0]) - - var uncle = block.uncles.get(data.args[1]) - - postData(data._id, uncle) - - break - - case "transact": - require(5) - - var tx = eth.transact(data.args) - postData(data._id, tx) - - break - - case "stateAt": - require(2); - - var storage = eth.storageAt(data.args[0], data.args[1]); - postData(data._id, storage) - - break - - case "call": - require(1); - var ret = eth.call(data.args) - postData(data._id, ret) - break - - case "balanceAt": - require(1); - - postData(data._id, eth.balanceAt(data.args[0])); - break - - case "watch": - require(2) - eth.watch(data.args[0], data.args[1]) - - case "disconnect": - require(1) - postData(data._id, null) - break; - - case "messages": - require(1); - - var messages = JSON.parse(eth.getMessages(data.args[0])) - postData(data._id, messages) - break - - case "mutan": - require(1) - - var code = eth.compileMutan(data.args[0]) - postData(data._id, "0x"+code) - break; - - case "newFilterString": - require(1) - var id = eth.newFilterString(data.args[0]) - postData(data._id, id); - break; - - case "newFilter": - require(1) - var id = eth.newFilter(data.args[0]) - - postData(data._id, id); - break; - - case "getMessages": - require(1); - - var messages = eth.messages(data.args[0]); - var m = JSON.parse(JSON.parse(JSON.stringify(messages))) - postData(data._id, m); - - break; - - case "deleteFilter": - require(1); - eth.uninstallFilter(data.args[0]) - break; - } - } catch(e) { - console.log(data.call + ": " + e) - - postData(data._id, null); - } - } - - - function post(seed, data) { - postData(data._id, data) - } - - function require(args, num) { - if(args.length < num) { - throw("required argument count of "+num+" got "+args.length); - } - } - function postData(seed, data) { - webview.experimental.postMessage(JSON.stringify({data: data, _id: seed})) - } - function postEvent(event, data) { - webview.experimental.postMessage(JSON.stringify({data: data, _event: event})) - } - - function onWatchedCb(data, id) { - var messages = JSON.parse(data) - postEvent("watched:"+id, messages) - } - - function onNewBlockCb(block) { - postEvent("block:new", block) - } - function onObjectChangeCb(stateObject) { - postEvent("object:"+stateObject.address(), stateObject) - } - function onStorageChangeCb(storageObject) { - var ev = ["storage", storageObject.stateAddress, storageObject.address].join(":"); - postEvent(ev, [storageObject.address, storageObject.value]) - } - } - - - Rectangle { - id: sizeGrip - color: "gray" - visible: false - height: 10 - anchors { - left: root.left - right: root.right - } - y: Math.round(root.height * 2 / 3) - - MouseArea { - anchors.fill: parent - drag.target: sizeGrip - drag.minimumY: 0 - drag.maximumY: root.height - drag.axis: Drag.YAxis - } - } - - WebView { - id: inspector - visible: false - anchors { - left: root.left - right: root.right - top: sizeGrip.bottom - bottom: root.bottom - } - } - - states: [ - State { - name: "inspectorShown" - PropertyChanges { - target: inspector - } - } - ] - } -} -- cgit v1.2.3 From e42517754ac2912b6d3ca78a34b8aeadf8805906 Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 22 Dec 2014 11:57:13 +0100 Subject: updated ethereum.js --- cmd/ethtest/.bowerrc | 5 + cmd/ethtest/.editorconfig | 12 + cmd/ethtest/.gitignore | 18 ++ cmd/ethtest/.jshintrc | 50 ++++ cmd/ethtest/.npmignore | 9 + cmd/ethtest/.travis.yml | 11 + cmd/ethtest/LICENSE | 14 ++ cmd/ethtest/README.md | 79 ++++++ cmd/ethtest/bower.json | 51 ++++ cmd/ethtest/dist/ethereum.js | 20 ++ cmd/ethtest/dist/ethereum.js.map | 29 +++ cmd/ethtest/dist/ethereum.min.js | 1 + cmd/ethtest/example/contract.html | 75 ++++++ cmd/ethtest/example/index.html | 41 ++++ cmd/ethtest/example/node-app.js | 16 ++ cmd/ethtest/gulpfile.js | 123 ++++++++++ cmd/ethtest/index.js | 8 + cmd/ethtest/index_qt.js | 5 + cmd/ethtest/lib/abi.js | 218 +++++++++++++++++ cmd/ethtest/lib/autoprovider.js | 103 ++++++++ cmd/ethtest/lib/contract.js | 65 +++++ cmd/ethtest/lib/httprpc.js | 95 ++++++++ cmd/ethtest/lib/main.js | 494 ++++++++++++++++++++++++++++++++++++++ cmd/ethtest/lib/qt.js | 45 ++++ cmd/ethtest/lib/websocket.js | 78 ++++++ cmd/ethtest/package.json | 67 ++++++ 26 files changed, 1732 insertions(+) create mode 100644 cmd/ethtest/.bowerrc create mode 100644 cmd/ethtest/.editorconfig create mode 100644 cmd/ethtest/.gitignore create mode 100644 cmd/ethtest/.jshintrc create mode 100644 cmd/ethtest/.npmignore create mode 100644 cmd/ethtest/.travis.yml create mode 100644 cmd/ethtest/LICENSE create mode 100644 cmd/ethtest/README.md create mode 100644 cmd/ethtest/bower.json create mode 100644 cmd/ethtest/dist/ethereum.js create mode 100644 cmd/ethtest/dist/ethereum.js.map create mode 100644 cmd/ethtest/dist/ethereum.min.js create mode 100644 cmd/ethtest/example/contract.html create mode 100644 cmd/ethtest/example/index.html create mode 100644 cmd/ethtest/example/node-app.js create mode 100644 cmd/ethtest/gulpfile.js create mode 100644 cmd/ethtest/index.js create mode 100644 cmd/ethtest/index_qt.js create mode 100644 cmd/ethtest/lib/abi.js create mode 100644 cmd/ethtest/lib/autoprovider.js create mode 100644 cmd/ethtest/lib/contract.js create mode 100644 cmd/ethtest/lib/httprpc.js create mode 100644 cmd/ethtest/lib/main.js create mode 100644 cmd/ethtest/lib/qt.js create mode 100644 cmd/ethtest/lib/websocket.js create mode 100644 cmd/ethtest/package.json (limited to 'cmd') diff --git a/cmd/ethtest/.bowerrc b/cmd/ethtest/.bowerrc new file mode 100644 index 000000000..c3a8813e8 --- /dev/null +++ b/cmd/ethtest/.bowerrc @@ -0,0 +1,5 @@ +{ + "directory": "example/js/", + "cwd": "./", + "analytics": false +} \ No newline at end of file diff --git a/cmd/ethtest/.editorconfig b/cmd/ethtest/.editorconfig new file mode 100644 index 000000000..60a2751d3 --- /dev/null +++ b/cmd/ethtest/.editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] +indent_style = space +indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false \ No newline at end of file diff --git a/cmd/ethtest/.gitignore b/cmd/ethtest/.gitignore new file mode 100644 index 000000000..399b6dc88 --- /dev/null +++ b/cmd/ethtest/.gitignore @@ -0,0 +1,18 @@ +# See http://help.github.com/ignore-files/ for more about ignoring files. +# +# If you find yourself ignoring temporary files generated by your text editor +# or operating system, you probably want to add a global ignore instead: +# git config --global core.excludesfile ~/.gitignore_global + +*.swp +/tmp +*/**/*un~ +*un~ +.DS_Store +*/**/.DS_Store +ethereum/ethereum +ethereal/ethereal +example/js +node_modules +bower_components +npm-debug.log diff --git a/cmd/ethtest/.jshintrc b/cmd/ethtest/.jshintrc new file mode 100644 index 000000000..c0ec5f89d --- /dev/null +++ b/cmd/ethtest/.jshintrc @@ -0,0 +1,50 @@ +{ + "predef": [ + "console", + "require", + "equal", + "test", + "testBoth", + "testWithDefault", + "raises", + "deepEqual", + "start", + "stop", + "ok", + "strictEqual", + "module", + "expect", + "reject", + "impl" + ], + + "esnext": true, + "proto": true, + "node" : true, + "browser" : true, + "browserify" : true, + + "boss" : true, + "curly": false, + "debug": true, + "devel": true, + "eqeqeq": true, + "evil": true, + "forin": false, + "immed": false, + "laxbreak": false, + "newcap": true, + "noarg": true, + "noempty": false, + "nonew": false, + "nomen": false, + "onevar": false, + "plusplus": false, + "regexp": false, + "undef": true, + "sub": true, + "strict": false, + "white": false, + "shadow": true, + "eqnull": true +} \ No newline at end of file diff --git a/cmd/ethtest/.npmignore b/cmd/ethtest/.npmignore new file mode 100644 index 000000000..5bbffe4fd --- /dev/null +++ b/cmd/ethtest/.npmignore @@ -0,0 +1,9 @@ +example/js +node_modules +test +.gitignore +.editorconfig +.travis.yml +.npmignore +component.json +testling.html \ No newline at end of file diff --git a/cmd/ethtest/.travis.yml b/cmd/ethtest/.travis.yml new file mode 100644 index 000000000..fafacbd5a --- /dev/null +++ b/cmd/ethtest/.travis.yml @@ -0,0 +1,11 @@ +language: node_js +node_js: + - "0.11" + - "0.10" +before_script: + - npm install + - npm install jshint +script: + - "jshint *.js lib" +after_script: + - npm run-script gulp diff --git a/cmd/ethtest/LICENSE b/cmd/ethtest/LICENSE new file mode 100644 index 000000000..0f187b873 --- /dev/null +++ b/cmd/ethtest/LICENSE @@ -0,0 +1,14 @@ +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 . \ No newline at end of file diff --git a/cmd/ethtest/README.md b/cmd/ethtest/README.md new file mode 100644 index 000000000..865b62c6b --- /dev/null +++ b/cmd/ethtest/README.md @@ -0,0 +1,79 @@ +# Ethereum JavaScript API + +This is the Ethereum compatible JavaScript API using `Promise`s +which implements the [Generic JSON RPC](https://github.com/ethereum/wiki/wiki/Generic-JSON-RPC) spec. It's available on npm as a node module and also for bower and component as an embeddable js + +[![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![dependency status][dep-image]][dep-url] [![dev dependency status][dep-dev-image]][dep-dev-url] + + + +## Installation + +### Node.js + + npm install ethereum.js + +### For browser +Bower + + bower install ethereum.js + +Component + + component install ethereum/ethereum.js + +* Include `ethereum.min.js` in your html file. +* Include [es6-promise](https://github.com/jakearchibald/es6-promise) or another ES6-Shim if your browser doesn't support ECMAScript 6. + +## Usage +Require the library: + + var web3 = require('web3'); + +Set a provider (QtProvider, WebSocketProvider, HttpRpcProvider) + + var web3.setProvider(new web3.providers.WebSocketProvider('ws://localhost:40404/eth')); + +There you go, now you can use it: + +``` +web3.eth.coinbase.then(function(result){ + console.log(result); + return web3.eth.balanceAt(result); +}).then(function(balance){ + console.log(web3.toDecimal(balance)); +}).catch(function(err){ + console.log(err); +}); +``` + + +For another example see `example/index.html`. + +## Building + +* `gulp build` + + +### Testing + +**Please note this repo is in it's early stage.** + +If you'd like to run a WebSocket ethereum node check out +[go-ethereum](https://github.com/ethereum/go-ethereum). + +To install ethereum and spawn a node: + +``` +go get github.com/ethereum/go-ethereum/ethereum +ethereum -ws -loglevel=4 +``` + +[npm-image]: https://badge.fury.io/js/ethereum.js.png +[npm-url]: https://npmjs.org/package/ethereum.js +[travis-image]: https://travis-ci.org/ethereum/ethereum.js.svg +[travis-url]: https://travis-ci.org/ethereum/ethereum.js +[dep-image]: https://david-dm.org/ethereum/ethereum.js.svg +[dep-url]: https://david-dm.org/ethereum/ethereum.js +[dep-dev-image]: https://david-dm.org/ethereum/ethereum.js/dev-status.svg +[dep-dev-url]: https://david-dm.org/ethereum/ethereum.js#info=devDependencies \ No newline at end of file diff --git a/cmd/ethtest/bower.json b/cmd/ethtest/bower.json new file mode 100644 index 000000000..cedae9023 --- /dev/null +++ b/cmd/ethtest/bower.json @@ -0,0 +1,51 @@ +{ + "name": "ethereum.js", + "namespace": "ethereum", + "version": "0.0.3", + "description": "Ethereum Compatible JavaScript API", + "main": ["./dist/ethereum.js", "./dist/ethereum.min.js"], + "dependencies": { + "es6-promise": "#master" + }, + "repository": { + "type": "git", + "url": "https://github.com/ethereum/ethereum.js.git" + }, + "homepage": "https://github.com/ethereum/ethereum.js", + "bugs": { + "url": "https://github.com/ethereum/ethereum.js/issues" + }, + "keywords": [ + "ethereum", + "javascript", + "API" + ], + "authors": [ + { + "name": "Marek Kotewicz", + "email": "marek@ethdev.com", + "homepage": "https://github.com/debris" + }, + { + "name": "Marian Oancea", + "email": "marian@ethdev.com", + "homepage": "https://github.com/cubedro" + } + ], + "license": "LGPL-3.0", + "ignore": [ + "example", + "lib", + "node_modules", + "package.json", + ".bowerrc", + ".editorconfig", + ".gitignore", + ".jshintrc", + ".npmignore", + ".travis.yml", + "gulpfile.js", + "index.js", + "**/*.txt" + ] +} \ No newline at end of file diff --git a/cmd/ethtest/dist/ethereum.js b/cmd/ethtest/dist/ethereum.js new file mode 100644 index 000000000..b64c15b9e --- /dev/null +++ b/cmd/ethtest/dist/ethereum.js @@ -0,0 +1,20 @@ +require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;oi&&(code=hex.charCodeAt(i),0!==code);i+=2)str+=String.fromCharCode(parseInt(hex.substr(i,2),16));return str},toDecimal:function(val){return parseInt(val,16)},fromAscii:function(str,pad){pad=void 0===pad?32:pad;for(var hex=this.toHex(str);hex.length<2*pad;)hex+="00";return"0x"+hex},eth:{prototype:Object(),watch:function(params){return new Filter(params,ethWatch)}},db:{prototype:Object()},shh:{prototype:Object(),watch:function(params){return new Filter(params,shhWatch)}},on:function(event,id,cb){return void 0===web3._events[event]&&(web3._events[event]={}),web3._events[event][id]=cb,this},off:function(event,id){return void 0!==web3._events[event]&&delete web3._events[event][id],this},trigger:function(event,id,data){var cb,callbacks=web3._events[event];callbacks&&callbacks[id]&&(cb=callbacks[id])(data)}};setupMethods(web3.eth,ethMethods()),setupProperties(web3.eth,ethProperties()),setupMethods(web3.db,dbMethods()),setupMethods(web3.shh,shhMethods()),ethWatch={changed:"eth_changed"},setupMethods(ethWatch,ethWatchMethods()),shhWatch={changed:"shh_changed"},setupMethods(shhWatch,shhWatchMethods()),ProviderManager=function(){var self,poll;this.queued=[],this.polls=[],this.ready=!1,this.provider=void 0,this.id=1,self=this,(poll=function(){self.provider&&self.provider.poll&&self.polls.forEach(function(data){data.data._id=self.id,self.id++,self.provider.poll(data.data,data.id)}),setTimeout(poll,12e3)})()},ProviderManager.prototype.send=function(data,cb){data._id=this.id,cb&&(web3._callbacks[data._id]=cb),data.args=data.args||[],this.id++,void 0!==this.provider?this.provider.send(data):(console.warn("provider is not set"),this.queued.push(data))},ProviderManager.prototype.set=function(provider){void 0!==this.provider&&void 0!==this.provider.unload&&this.provider.unload(),this.provider=provider,this.ready=!0},ProviderManager.prototype.sendQueued=function(){for(var i=0;this.queued.length;i++)this.send(this.queued[i])},ProviderManager.prototype.installed=function(){return void 0!==this.provider},ProviderManager.prototype.startPolling=function(data,pollId){this.provider&&this.provider.poll&&this.polls.push({data:data,id:pollId})},ProviderManager.prototype.stopPolling=function(pollId){var i,poll;for(i=this.polls.length;i--;)poll=this.polls[i],poll.id===pollId&&this.polls.splice(i,1)},web3.provider=new ProviderManager,web3.setProvider=function(provider){provider.onmessage=messageHandler,web3.provider.set(provider),web3.provider.sendQueued()},web3.haveProvider=function(){return!!web3.provider.provider},Filter=function(options,impl){this.impl=impl,this.callbacks=[];var self=this;this.promise=impl.newFilter(options),this.promise.then(function(id){self.id=id,web3.on(impl.changed,id,self.trigger.bind(self)),web3.provider.startPolling({call:impl.changed,args:[id]},id)})},Filter.prototype.arrived=function(callback){this.changed(callback)},Filter.prototype.changed=function(callback){var self=this;this.promise.then(function(id){self.callbacks.push(callback)})},Filter.prototype.trigger=function(messages){for(var i=0;ii&&(code=hex.charCodeAt(i),0!==code);i+=2)str+=String.fromCharCode(parseInt(hex.substr(i,2),16));return str},toDecimal:function(val){return parseInt(val,16)},fromAscii:function(str,pad){pad=void 0===pad?32:pad;for(var hex=this.toHex(str);hex.length<2*pad;)hex+=\"00\";return\"0x\"+hex},eth:{prototype:Object(),watch:function(params){return new Filter(params,ethWatch)}},db:{prototype:Object()},shh:{prototype:Object(),watch:function(params){return new Filter(params,shhWatch)}},on:function(event,id,cb){return void 0===web3._events[event]&&(web3._events[event]={}),web3._events[event][id]=cb,this},off:function(event,id){return void 0!==web3._events[event]&&delete web3._events[event][id],this},trigger:function(event,id,data){var cb,callbacks=web3._events[event];callbacks&&callbacks[id]&&(cb=callbacks[id])(data)}};setupMethods(web3.eth,ethMethods()),setupProperties(web3.eth,ethProperties()),setupMethods(web3.db,dbMethods()),setupMethods(web3.shh,shhMethods()),ethWatch={changed:\"eth_changed\"},setupMethods(ethWatch,ethWatchMethods()),shhWatch={changed:\"shh_changed\"},setupMethods(shhWatch,shhWatchMethods()),ProviderManager=function(){var self,poll;this.queued=[],this.polls=[],this.ready=!1,this.provider=void 0,this.id=1,self=this,(poll=function(){self.provider&&self.provider.poll&&self.polls.forEach(function(data){data.data._id=self.id,self.id++,self.provider.poll(data.data,data.id)}),setTimeout(poll,12e3)})()},ProviderManager.prototype.send=function(data,cb){data._id=this.id,cb&&(web3._callbacks[data._id]=cb),data.args=data.args||[],this.id++,void 0!==this.provider?this.provider.send(data):(console.warn(\"provider is not set\"),this.queued.push(data))},ProviderManager.prototype.set=function(provider){void 0!==this.provider&&void 0!==this.provider.unload&&this.provider.unload(),this.provider=provider,this.ready=!0},ProviderManager.prototype.sendQueued=function(){for(var i=0;this.queued.length;i++)this.send(this.queued[i])},ProviderManager.prototype.installed=function(){return void 0!==this.provider},ProviderManager.prototype.startPolling=function(data,pollId){this.provider&&this.provider.poll&&this.polls.push({data:data,id:pollId})},ProviderManager.prototype.stopPolling=function(pollId){var i,poll;for(i=this.polls.length;i--;)poll=this.polls[i],poll.id===pollId&&this.polls.splice(i,1)},web3.provider=new ProviderManager,web3.setProvider=function(provider){provider.onmessage=messageHandler,web3.provider.set(provider),web3.provider.sendQueued()},web3.haveProvider=function(){return!!web3.provider.provider},Filter=function(options,impl){this.impl=impl,this.callbacks=[];var self=this;this.promise=impl.newFilter(options),this.promise.then(function(id){self.id=id,web3.on(impl.changed,id,self.trigger.bind(self)),web3.provider.startPolling({call:impl.changed,args:[id]},id)})},Filter.prototype.arrived=function(callback){this.changed(callback)},Filter.prototype.changed=function(callback){var self=this;this.promise.then(function(id){self.callbacks.push(callback)})},Filter.prototype.trigger=function(messages){for(var i=0;ir&&(e=t.charCodeAt(r),0!==e);r+=2)n+=String.fromCharCode(parseInt(t.substr(r,2),16));return n},toDecimal:function(t){return parseInt(t,16)},fromAscii:function(t,e){e=void 0===e?32:e;for(var n=this.toHex(t);n.length<2*e;)n+="00";return"0x"+n},eth:{prototype:Object(),watch:function(t){return new a(t,o)}},db:{prototype:Object()},shh:{prototype:Object(),watch:function(t){return new a(t,i)}},on:function(t,e,n){return void 0===g._events[t]&&(g._events[t]={}),g._events[t][e]=n,this},off:function(t,e){return void 0!==g._events[t]&&delete g._events[t][e],this},trigger:function(t,e,n){var r,o=g._events[t];o&&o[e]&&(r=o[e])(n)}};f(g.eth,u()),v(g.eth,c()),f(g.db,l()),f(g.shh,h()),o={changed:"eth_changed"},f(o,p()),i={changed:"shh_changed"},f(i,d()),s=function(){var t,e;this.queued=[],this.polls=[],this.ready=!1,this.provider=void 0,this.id=1,t=this,(e=function(){t.provider&&t.provider.poll&&t.polls.forEach(function(e){e.data._id=t.id,t.id++,t.provider.poll(e.data,e.id)}),setTimeout(e,12e3)})()},s.prototype.send=function(t,e){t._id=this.id,e&&(g._callbacks[t._id]=e),t.args=t.args||[],this.id++,void 0!==this.provider?this.provider.send(t):(console.warn("provider is not set"),this.queued.push(t))},s.prototype.set=function(t){void 0!==this.provider&&void 0!==this.provider.unload&&this.provider.unload(),this.provider=t,this.ready=!0},s.prototype.sendQueued=function(){for(var t=0;this.queued.length;t++)this.send(this.queued[t])},s.prototype.installed=function(){return void 0!==this.provider},s.prototype.startPolling=function(t,e){this.provider&&this.provider.poll&&this.polls.push({data:t,id:e})},s.prototype.stopPolling=function(t){var e,n;for(e=this.polls.length;e--;)n=this.polls[e],n.id===t&&this.polls.splice(e,1)},g.provider=new s,g.setProvider=function(t){t.onmessage=r,g.provider.set(t),g.provider.sendQueued()},g.haveProvider=function(){return!!g.provider.provider},a=function(t,e){this.impl=e,this.callbacks=[];var n=this;this.promise=e.newFilter(t),this.promise.then(function(t){n.id=t,g.on(e.changed,t,n.trigger.bind(n)),g.provider.startPolling({call:e.changed,args:[t]},t)})},a.prototype.arrived=function(t){this.changed(t)},a.prototype.changed=function(t){var e=this;this.promise.then(function(){e.callbacks.push(t)})},a.prototype.trigger=function(t){for(var e=0;e + + + + + + + + +

contract

+
+
+ +
+ +
+ + + diff --git a/cmd/ethtest/example/index.html b/cmd/ethtest/example/index.html new file mode 100644 index 000000000..d0bf094ef --- /dev/null +++ b/cmd/ethtest/example/index.html @@ -0,0 +1,41 @@ + + + + + + + + + +

coinbase balance

+ +
+
+
+
+ + + diff --git a/cmd/ethtest/example/node-app.js b/cmd/ethtest/example/node-app.js new file mode 100644 index 000000000..f63fa9115 --- /dev/null +++ b/cmd/ethtest/example/node-app.js @@ -0,0 +1,16 @@ +#!/usr/bin/env node + +require('es6-promise').polyfill(); + +var web3 = require("../index.js"); + +web3.setProvider(new web3.providers.HttpRpcProvider('http://localhost:8080')); + +web3.eth.coinbase.then(function(result){ + console.log(result); + return web3.eth.balanceAt(result); +}).then(function(balance){ + console.log(web3.toDecimal(balance)); +}).catch(function(err){ + console.log(err); +}); \ No newline at end of file diff --git a/cmd/ethtest/gulpfile.js b/cmd/ethtest/gulpfile.js new file mode 100644 index 000000000..9e0717d8b --- /dev/null +++ b/cmd/ethtest/gulpfile.js @@ -0,0 +1,123 @@ +#!/usr/bin/env node + +'use strict'; + +var path = require('path'); + +var del = require('del'); +var gulp = require('gulp'); +var browserify = require('browserify'); +var jshint = require('gulp-jshint'); +var uglify = require('gulp-uglify'); +var rename = require('gulp-rename'); +var envify = require('envify/custom'); +var unreach = require('unreachable-branch-transform'); +var source = require('vinyl-source-stream'); +var exorcist = require('exorcist'); +var bower = require('bower'); + +var DEST = './dist/'; + +var build = function(src, dst) { + return browserify({ + debug: true, + insert_global_vars: false, + detectGlobals: false, + bundleExternal: false + }) + .require('./' + src + '.js', {expose: 'web3'}) + .add('./' + src + '.js') + .transform('envify', { + NODE_ENV: 'build' + }) + .transform('unreachable-branch-transform') + .transform('uglifyify', { + mangle: false, + compress: { + dead_code: false, + conditionals: true, + unused: false, + hoist_funs: true, + hoist_vars: true, + negate_iife: false + }, + beautify: true, + warnings: true + }) + .bundle() + .pipe(exorcist(path.join( DEST, dst + '.js.map'))) + .pipe(source(dst + '.js')) + .pipe(gulp.dest( DEST )); +}; + +var buildDev = function(src, dst) { + return browserify({ + debug: true, + insert_global_vars: false, + detectGlobals: false, + bundleExternal: false + }) + .require('./' + src + '.js', {expose: 'web3'}) + .add('./' + src + '.js') + .transform('envify', { + NODE_ENV: 'build' + }) + .transform('unreachable-branch-transform') + .bundle() + .pipe(exorcist(path.join( DEST, dst + '.js.map'))) + .pipe(source(dst + '.js')) + .pipe(gulp.dest( DEST )); +}; + +var uglifyFile = function(file) { + return gulp.src( DEST + file + '.js') + .pipe(uglify()) + .pipe(rename(file + '.min.js')) + .pipe(gulp.dest( DEST )); +}; + +gulp.task('bower', function(cb){ + bower.commands.install().on('end', function (installed){ + console.log(installed); + cb(); + }); +}); + +gulp.task('lint', function(){ + return gulp.src(['./*.js', './lib/*.js']) + .pipe(jshint()) + .pipe(jshint.reporter('default')); +}); + +gulp.task('clean', ['lint'], function(cb) { + del([ DEST ], cb); +}); + +gulp.task('build', ['clean'], function () { + return build('index', 'ethereum'); +}); + +gulp.task('buildQt', ['clean'], function () { + return build('index_qt', 'ethereum'); +}); + +gulp.task('buildDev', ['clean'], function () { + return buildDev('index', 'ethereum'); +}); + +gulp.task('uglify', ['build'], function(){ + return uglifyFile('ethereum'); +}); + +gulp.task('uglifyQt', ['buildQt'], function () { + return uglifyFile('ethereum'); +}); + +gulp.task('watch', function() { + gulp.watch(['./lib/*.js'], ['lint', 'prepare', 'build']); +}); + +gulp.task('default', ['bower', 'lint', 'build', 'uglify']); +gulp.task('qt', ['bower', 'lint', 'buildQt', 'uglifyQt']); +gulp.task('dev', ['bower', 'lint', 'buildDev']); + diff --git a/cmd/ethtest/index.js b/cmd/ethtest/index.js new file mode 100644 index 000000000..c2de7e735 --- /dev/null +++ b/cmd/ethtest/index.js @@ -0,0 +1,8 @@ +var web3 = require('./lib/main'); +web3.providers.WebSocketProvider = require('./lib/websocket'); +web3.providers.HttpRpcProvider = require('./lib/httprpc'); +web3.providers.QtProvider = require('./lib/qt'); +web3.providers.AutoProvider = require('./lib/autoprovider'); +web3.contract = require('./lib/contract'); + +module.exports = web3; diff --git a/cmd/ethtest/index_qt.js b/cmd/ethtest/index_qt.js new file mode 100644 index 000000000..d5e47597e --- /dev/null +++ b/cmd/ethtest/index_qt.js @@ -0,0 +1,5 @@ +var web3 = require('./lib/main'); +web3.providers.QtProvider = require('./lib/qt'); +web3.contract = require('./lib/contract'); + +module.exports = web3; diff --git a/cmd/ethtest/lib/abi.js b/cmd/ethtest/lib/abi.js new file mode 100644 index 000000000..2cff503d3 --- /dev/null +++ b/cmd/ethtest/lib/abi.js @@ -0,0 +1,218 @@ +/* + 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 . +*/ +/** @file abi.js + * @authors: + * Marek Kotewicz + * Gav Wood + * @date 2014 + */ + +// TODO: make these be actually accurate instead of falling back onto JS's doubles. +var hexToDec = function (hex) { + return parseInt(hex, 16).toString(); +}; + +var decToHex = function (dec) { + return parseInt(dec).toString(16); +}; + +var findIndex = function (array, callback) { + var end = false; + var i = 0; + for (; i < array.length && !end; i++) { + end = callback(array[i]); + } + return end ? i - 1 : -1; +}; + +var findMethodIndex = function (json, methodName) { + return findIndex(json, function (method) { + return method.name === methodName; + }); +}; + +var padLeft = function (string, chars) { + return Array(chars - string.length + 1).join("0") + string; +}; + +var setupInputTypes = function () { + var prefixedType = function (prefix) { + return function (type, value) { + var expected = prefix; + if (type.indexOf(expected) !== 0) { + return false; + } + + var padding = parseInt(type.slice(expected.length)) / 8; + if (typeof value === "number") + value = value.toString(16); + else if (value.indexOf('0x') === 0) + value = value.substr(2); + else + value = (+value).toString(16); + return padLeft(value, padding * 2); + }; + }; + + var namedType = function (name, padding, formatter) { + return function (type, value) { + if (type !== name) { + return false; + } + + return padLeft(formatter ? formatter(value) : value, padding * 2); + }; + }; + + var formatBool = function (value) { + return value ? '0x1' : '0x0'; + }; + + return [ + prefixedType('uint'), + prefixedType('int'), + prefixedType('hash'), + namedType('address', 20), + namedType('bool', 1, formatBool), + ]; +}; + +var inputTypes = setupInputTypes(); + +var toAbiInput = function (json, methodName, params) { + var bytes = ""; + var index = findMethodIndex(json, methodName); + + if (index === -1) { + return; + } + + bytes = "0x" + padLeft(index.toString(16), 2); + var method = json[index]; + + for (var i = 0; i < method.inputs.length; i++) { + var found = false; + for (var j = 0; j < inputTypes.length && !found; j++) { + found = inputTypes[j](method.inputs[i].type, params[i]); + } + if (!found) { + console.error('unsupported json type: ' + method.inputs[i].type); + } + bytes += found; + } + return bytes; +}; + +var setupOutputTypes = function () { + var prefixedType = function (prefix) { + return function (type) { + var expected = prefix; + if (type.indexOf(expected) !== 0) { + return -1; + } + + var padding = parseInt(type.slice(expected.length)) / 8; + return padding * 2; + }; + }; + + var namedType = function (name, padding) { + return function (type) { + return name === type ? padding * 2 : -1; + }; + }; + + var formatInt = function (value) { + return value.length <= 8 ? +parseInt(value, 16) : hexToDec(value); + }; + + var formatHash = function (value) { + return "0x" + value; + }; + + var formatBool = function (value) { + return value === '1' ? true : false; + }; + + return [ + { padding: prefixedType('uint'), format: formatInt }, + { padding: prefixedType('int'), format: formatInt }, + { padding: prefixedType('hash'), format: formatHash }, + { padding: namedType('address', 20) }, + { padding: namedType('bool', 1), format: formatBool } + ]; +}; + +var outputTypes = setupOutputTypes(); + +var fromAbiOutput = function (json, methodName, output) { + var index = findMethodIndex(json, methodName); + + if (index === -1) { + return; + } + + output = output.slice(2); + + var result = []; + var method = json[index]; + for (var i = 0; i < method.outputs.length; i++) { + var padding = -1; + for (var j = 0; j < outputTypes.length && padding === -1; j++) { + padding = outputTypes[j].padding(method.outputs[i].type); + } + + if (padding === -1) { + // not found output parsing + continue; + } + var res = output.slice(0, padding); + var formatter = outputTypes[j - 1].format; + result.push(formatter ? formatter(res) : ("0x" + res)); + output = output.slice(padding); + } + + return result; +}; + +var inputParser = function (json) { + var parser = {}; + json.forEach(function (method) { + parser[method.name] = function () { + var params = Array.prototype.slice.call(arguments); + return toAbiInput(json, method.name, params); + }; + }); + + return parser; +}; + +var outputParser = function (json) { + var parser = {}; + json.forEach(function (method) { + parser[method.name] = function (output) { + return fromAbiOutput(json, method.name, output); + }; + }); + + return parser; +}; + +module.exports = { + inputParser: inputParser, + outputParser: outputParser +}; diff --git a/cmd/ethtest/lib/autoprovider.js b/cmd/ethtest/lib/autoprovider.js new file mode 100644 index 000000000..bfbc3ab6e --- /dev/null +++ b/cmd/ethtest/lib/autoprovider.js @@ -0,0 +1,103 @@ +/* + 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 . +*/ +/** @file autoprovider.js + * @authors: + * Marek Kotewicz + * Marian Oancea + * @date 2014 + */ + +/* + * @brief if qt object is available, uses QtProvider, + * if not tries to connect over websockets + * if it fails, it uses HttpRpcProvider + */ + +// TODO: work out which of the following two lines it is supposed to be... +//if (process.env.NODE_ENV !== 'build') { +if ("build" !== 'build') {/* + var WebSocket = require('ws'); // jshint ignore:line + var web3 = require('./main.js'); // jshint ignore:line +*/} + +var AutoProvider = function (userOptions) { + if (web3.haveProvider()) { + return; + } + + // before we determine what provider we are, we have to cache request + this.sendQueue = []; + this.onmessageQueue = []; + + if (navigator.qt) { + this.provider = new web3.providers.QtProvider(); + return; + } + + userOptions = userOptions || {}; + var options = { + httprpc: userOptions.httprpc || 'http://localhost:8080', + websockets: userOptions.websockets || 'ws://localhost:40404/eth' + }; + + var self = this; + var closeWithSuccess = function (success) { + ws.close(); + if (success) { + self.provider = new web3.providers.WebSocketProvider(options.websockets); + } else { + self.provider = new web3.providers.HttpRpcProvider(options.httprpc); + self.poll = self.provider.poll.bind(self.provider); + } + self.sendQueue.forEach(function (payload) { + self.provider(payload); + }); + self.onmessageQueue.forEach(function (handler) { + self.provider.onmessage = handler; + }); + }; + + var ws = new WebSocket(options.websockets); + + ws.onopen = function() { + closeWithSuccess(true); + }; + + ws.onerror = function() { + closeWithSuccess(false); + }; +}; + +AutoProvider.prototype.send = function (payload) { + if (this.provider) { + this.provider.send(payload); + return; + } + this.sendQueue.push(payload); +}; + +Object.defineProperty(AutoProvider.prototype, 'onmessage', { + set: function (handler) { + if (this.provider) { + this.provider.onmessage = handler; + return; + } + this.onmessageQueue.push(handler); + } +}); + +module.exports = AutoProvider; diff --git a/cmd/ethtest/lib/contract.js b/cmd/ethtest/lib/contract.js new file mode 100644 index 000000000..17b077484 --- /dev/null +++ b/cmd/ethtest/lib/contract.js @@ -0,0 +1,65 @@ +/* + 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 . +*/ +/** @file contract.js + * @authors: + * Marek Kotewicz + * @date 2014 + */ + +// TODO: work out which of the following two lines it is supposed to be... +//if (process.env.NODE_ENV !== 'build') { +if ("build" !== 'build') {/* + var web3 = require('./web3'); // jshint ignore:line +*/} +var abi = require('./abi'); + +var contract = function (address, desc) { + var inputParser = abi.inputParser(desc); + var outputParser = abi.outputParser(desc); + + var contract = {}; + + desc.forEach(function (method) { + contract[method.name] = function () { + var params = Array.prototype.slice.call(arguments); + var parsed = inputParser[method.name].apply(null, params); + + var onSuccess = function (result) { + return outputParser[method.name](result); + }; + + return { + call: function (extra) { + extra = extra || {}; + extra.to = address; + extra.data = parsed; + return web3.eth.call(extra).then(onSuccess); + }, + transact: function (extra) { + extra = extra || {}; + extra.to = address; + extra.data = parsed; + return web3.eth.transact(extra).then(onSuccess); + } + }; + }; + }); + + return contract; +}; + +module.exports = contract; diff --git a/cmd/ethtest/lib/httprpc.js b/cmd/ethtest/lib/httprpc.js new file mode 100644 index 000000000..ee6b5c307 --- /dev/null +++ b/cmd/ethtest/lib/httprpc.js @@ -0,0 +1,95 @@ +/* + 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 . +*/ +/** @file httprpc.js + * @authors: + * Marek Kotewicz + * Marian Oancea + * @date 2014 + */ + +// TODO: work out which of the following two lines it is supposed to be... +//if (process.env.NODE_ENV !== 'build') { +if ("build" !== "build") {/* + var XMLHttpRequest = require('xmlhttprequest').XMLHttpRequest; // jshint ignore:line +*/} + +var HttpRpcProvider = function (host) { + this.handlers = []; + this.host = host; +}; + +function formatJsonRpcObject(object) { + return { + jsonrpc: '2.0', + method: object.call, + params: object.args, + id: object._id + }; +} + +function formatJsonRpcMessage(message) { + var object = JSON.parse(message); + + return { + _id: object.id, + data: object.result, + error: object.error + }; +} + +HttpRpcProvider.prototype.sendRequest = function (payload, cb) { + var data = formatJsonRpcObject(payload); + + var request = new XMLHttpRequest(); + request.open("POST", this.host, true); + request.send(JSON.stringify(data)); + request.onreadystatechange = function () { + if (request.readyState === 4 && cb) { + cb(request); + } + }; +}; + +HttpRpcProvider.prototype.send = function (payload) { + var self = this; + this.sendRequest(payload, function (request) { + self.handlers.forEach(function (handler) { + handler.call(self, formatJsonRpcMessage(request.responseText)); + }); + }); +}; + +HttpRpcProvider.prototype.poll = function (payload, id) { + var self = this; + this.sendRequest(payload, function (request) { + var parsed = JSON.parse(request.responseText); + if (parsed.error || (parsed.result instanceof Array ? parsed.result.length === 0 : !parsed.result)) { + return; + } + self.handlers.forEach(function (handler) { + handler.call(self, {_event: payload.call, _id: id, data: parsed.result}); + }); + }); +}; + +Object.defineProperty(HttpRpcProvider.prototype, "onmessage", { + set: function (handler) { + this.handlers.push(handler); + } +}); + +module.exports = HttpRpcProvider; diff --git a/cmd/ethtest/lib/main.js b/cmd/ethtest/lib/main.js new file mode 100644 index 000000000..59c60cfa8 --- /dev/null +++ b/cmd/ethtest/lib/main.js @@ -0,0 +1,494 @@ +/* + 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 . +*/ +/** @file main.js + * @authors: + * Jeffrey Wilcke + * Marek Kotewicz + * Marian Oancea + * Gav Wood + * @date 2014 + */ + +function flattenPromise (obj) { + if (obj instanceof Promise) { + return Promise.resolve(obj); + } + + if (obj instanceof Array) { + return new Promise(function (resolve) { + var promises = obj.map(function (o) { + return flattenPromise(o); + }); + + return Promise.all(promises).then(function (res) { + for (var i = 0; i < obj.length; i++) { + obj[i] = res[i]; + } + resolve(obj); + }); + }); + } + + if (obj instanceof Object) { + return new Promise(function (resolve) { + var keys = Object.keys(obj); + var promises = keys.map(function (key) { + return flattenPromise(obj[key]); + }); + + return Promise.all(promises).then(function (res) { + for (var i = 0; i < keys.length; i++) { + obj[keys[i]] = res[i]; + } + resolve(obj); + }); + }); + } + + return Promise.resolve(obj); +} + +var web3Methods = function () { + return [ + { name: 'sha3', call: 'web3_sha3' } + ]; +}; + +var ethMethods = function () { + var blockCall = function (args) { + return typeof args[0] === "string" ? "eth_blockByHash" : "eth_blockByNumber"; + }; + + 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 methods = [ + { 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' }, + { name: 'call', call: 'eth_call' }, + { name: 'block', call: blockCall }, + { name: 'transaction', call: transactionCall }, + { name: 'uncle', call: uncleCall }, + { name: 'compilers', call: 'eth_compilers' }, + { name: 'lll', call: 'eth_lll' }, + { name: 'solidity', call: 'eth_solidity' }, + { name: 'serpent', call: 'eth_serpent' }, + { name: 'logs', call: 'eth_logs' } + ]; + return methods; +}; + +var ethProperties = function () { + return [ + { 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: 'account', getter: 'eth_account' }, + { name: 'accounts', getter: 'eth_accounts' }, + { name: 'peerCount', getter: 'eth_peerCount' }, + { name: 'defaultBlock', getter: 'eth_defaultBlock', setter: 'eth_setDefaultBlock' }, + { name: 'number', getter: 'eth_number'} + ]; +}; + +var dbMethods = function () { + return [ + { name: 'put', call: 'db_put' }, + { name: 'get', call: 'db_get' }, + { name: 'putString', call: 'db_putString' }, + { name: 'getString', call: 'db_getString' } + ]; +}; + +var shhMethods = function () { + return [ + { name: 'post', call: 'shh_post' }, + { name: 'newIdentity', call: 'shh_newIdentity' }, + { name: 'haveIdentity', call: 'shh_haveIdentity' }, + { name: 'newGroup', call: 'shh_newGroup' }, + { name: 'addToGroup', call: 'shh_addToGroup' } + ]; +}; + +var ethWatchMethods = function () { + var newFilter = function (args) { + return typeof args[0] === 'string' ? 'eth_newFilterString' : 'eth_newFilter'; + }; + + return [ + { name: 'newFilter', call: newFilter }, + { name: 'uninstallFilter', call: 'eth_uninstallFilter' }, + { name: 'getMessages', call: 'eth_filterLogs' } + ]; +}; + +var shhWatchMethods = function () { + return [ + { name: 'newFilter', call: 'shh_newFilter' }, + { name: 'uninstallFilter', call: 'shh_uninstallFilter' }, + { name: 'getMessage', call: 'shh_getMessages' } + ]; +}; + +var setupMethods = function (obj, methods) { + methods.forEach(function (method) { + obj[method.name] = function () { + return flattenPromise(Array.prototype.slice.call(arguments)).then(function (args) { + var call = typeof method.call === "function" ? method.call(args) : method.call; + return {call: call, args: args}; + }).then(function (request) { + return new Promise(function (resolve, reject) { + web3.provider.send(request, function (err, result) { + if (!err) { + resolve(result); + return; + } + reject(err); + }); + }); + }).catch(function(err) { + console.error(err); + }); + }; + }); +}; + +var setupProperties = function (obj, properties) { + properties.forEach(function (property) { + var proto = {}; + proto.get = function () { + return new Promise(function(resolve, reject) { + web3.provider.send({call: property.getter}, function(err, result) { + if (!err) { + resolve(result); + return; + } + reject(err); + }); + }); + }; + if (property.setter) { + proto.set = function (val) { + return flattenPromise([val]).then(function (args) { + return new Promise(function (resolve) { + web3.provider.send({call: property.setter, args: args}, function (err, result) { + if (!err) { + resolve(result); + return; + } + reject(err); + }); + }); + }).catch(function (err) { + console.error(err); + }); + }; + } + Object.defineProperty(obj, property.name, proto); + }); +}; + +// TODO: import from a dependency, don't duplicate. +var hexToDec = function (hex) { + return parseInt(hex, 16).toString(); +}; + +var decToHex = function (dec) { + return parseInt(dec).toString(16); +}; + + +var web3 = { + _callbacks: {}, + _events: {}, + providers: {}, + + toAscii: function(hex) { + // Find termination + var str = ""; + var i = 0, l = hex.length; + if (hex.substring(0, 2) === '0x') + i = 2; + for(; i < l; i+=2) { + var code = hex.charCodeAt(i); + if(code === 0) { + break; + } + + str += String.fromCharCode(parseInt(hex.substr(i, 2), 16)); + } + + return str; + }, + + fromAscii: function(str, pad) { + pad = pad === undefined ? 32 : pad; + var hex = this.toHex(str); + while(hex.length < pad*2) + hex += "00"; + return "0x" + hex; + }, + + toDecimal: function (val) { + return hexToDec(val.substring(2)); + }, + + fromDecimal: function (val) { + return "0x" + decToHex(val); + }, + + toEth: function(str) { + var val = typeof str === "string" ? str.indexOf('0x') == 0 ? parseInt(str.substr(2), 16) : parseInt(str) : str; + var unit = 0; + var units = [ 'wei', 'Kwei', 'Mwei', 'Gwei', 'szabo', 'finney', 'ether', 'grand', 'Mether', 'Gether', 'Tether', 'Pether', 'Eether', 'Zether', 'Yether', 'Nether', 'Dether', 'Vether', 'Uether' ]; + while (val > 3000 && unit < units.length - 1) + { + val /= 1000; + unit++; + } + var s = val.toString().length < val.toFixed(2).length ? val.toString() : val.toFixed(2); + while (true) { + var o = s; + s = s.replace(/(\d)(\d\d\d[\.\,])/, function($0, $1, $2) { return $1 + ',' + $2; }); + if (o == s) + break; + } + return s + ' ' + units[unit]; + }, + + eth: { + prototype: Object(), // jshint ignore:line + watch: function (params) { + return new Filter(params, ethWatch); + } + }, + + db: { + prototype: Object() // jshint ignore:line + }, + + shh: { + prototype: Object(), // jshint ignore:line + watch: function (params) { + return new Filter(params, shhWatch); + } + }, + + on: function(event, id, cb) { + if(web3._events[event] === undefined) { + web3._events[event] = {}; + } + + web3._events[event][id] = cb; + return this; + }, + + off: function(event, id) { + if(web3._events[event] !== undefined) { + delete web3._events[event][id]; + } + + return this; + }, + + trigger: function(event, id, data) { + var callbacks = web3._events[event]; + if (!callbacks || !callbacks[id]) { + return; + } + var cb = callbacks[id]; + cb(data); + } +}; + +setupMethods(web3, web3Methods()); +setupMethods(web3.eth, ethMethods()); +setupProperties(web3.eth, ethProperties()); +setupMethods(web3.db, dbMethods()); +setupMethods(web3.shh, shhMethods()); + +var ethWatch = { + changed: 'eth_changed' +}; +setupMethods(ethWatch, ethWatchMethods()); +var shhWatch = { + changed: 'shh_changed' +}; +setupMethods(shhWatch, shhWatchMethods()); + +var ProviderManager = function() { + this.queued = []; + this.polls = []; + this.ready = false; + this.provider = undefined; + this.id = 1; + + var self = this; + var poll = function () { + if (self.provider && self.provider.poll) { + self.polls.forEach(function (data) { + data.data._id = self.id; + self.id++; + self.provider.poll(data.data, data.id); + }); + } + setTimeout(poll, 12000); + }; + poll(); +}; + +ProviderManager.prototype.send = function(data, cb) { + data._id = this.id; + if (cb) { + web3._callbacks[data._id] = cb; + } + + data.args = data.args || []; + this.id++; + + if(this.provider !== undefined) { + this.provider.send(data); + } else { + console.warn("provider is not set"); + this.queued.push(data); + } +}; + +ProviderManager.prototype.set = function(provider) { + if(this.provider !== undefined && this.provider.unload !== undefined) { + this.provider.unload(); + } + + this.provider = provider; + this.ready = true; +}; + +ProviderManager.prototype.sendQueued = function() { + for(var i = 0; this.queued.length; i++) { + // Resend + this.send(this.queued[i]); + } +}; + +ProviderManager.prototype.installed = function() { + return this.provider !== undefined; +}; + +ProviderManager.prototype.startPolling = function (data, pollId) { + if (!this.provider || !this.provider.poll) { + return; + } + this.polls.push({data: data, id: pollId}); +}; + +ProviderManager.prototype.stopPolling = function (pollId) { + for (var i = this.polls.length; i--;) { + var poll = this.polls[i]; + if (poll.id === pollId) { + this.polls.splice(i, 1); + } + } +}; + +web3.provider = new ProviderManager(); + +web3.setProvider = function(provider) { + provider.onmessage = messageHandler; + web3.provider.set(provider); + web3.provider.sendQueued(); +}; + +web3.haveProvider = function() { + return !!web3.provider.provider; +}; + +var Filter = function(options, impl) { + this.impl = impl; + this.callbacks = []; + + var self = this; + this.promise = impl.newFilter(options); + this.promise.then(function (id) { + self.id = id; + web3.on(impl.changed, id, self.trigger.bind(self)); + web3.provider.startPolling({call: impl.changed, args: [id]}, id); + }); +}; + +Filter.prototype.arrived = function(callback) { + this.changed(callback); +}; + +Filter.prototype.changed = function(callback) { + var self = this; + this.promise.then(function(id) { + self.callbacks.push(callback); + }); +}; + +Filter.prototype.trigger = function(messages) { + for(var i = 0; i < this.callbacks.length; i++) { + this.callbacks[i].call(this, messages); + } +}; + +Filter.prototype.uninstall = function() { + var self = this; + this.promise.then(function (id) { + self.impl.uninstallFilter(id); + web3.provider.stopPolling(id); + web3.off(impl.changed, id); + }); +}; + +Filter.prototype.messages = function() { + var self = this; + return this.promise.then(function (id) { + return self.impl.getMessages(id); + }); +}; + +Filter.prototype.logs = function () { + return this.messages(); +}; + +function messageHandler(data) { + if(data._event !== undefined) { + web3.trigger(data._event, data._id, data.data); + return; + } + + if(data._id) { + var cb = web3._callbacks[data._id]; + if (cb) { + cb.call(this, data.error, data.data); + delete web3._callbacks[data._id]; + } + } +} + +module.exports = web3; diff --git a/cmd/ethtest/lib/qt.js b/cmd/ethtest/lib/qt.js new file mode 100644 index 000000000..f02239547 --- /dev/null +++ b/cmd/ethtest/lib/qt.js @@ -0,0 +1,45 @@ +/* + 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 . +*/ +/** @file qt.js + * @authors: + * Jeffrey Wilcke + * Marek Kotewicz + * @date 2014 + */ + +var QtProvider = function() { + this.handlers = []; + + var self = this; + navigator.qt.onmessage = function (message) { + self.handlers.forEach(function (handler) { + handler.call(self, JSON.parse(message.data)); + }); + }; +}; + +QtProvider.prototype.send = function(payload) { + navigator.qt.postMessage(JSON.stringify(payload)); +}; + +Object.defineProperty(QtProvider.prototype, "onmessage", { + set: function(handler) { + this.handlers.push(handler); + } +}); + +module.exports = QtProvider; diff --git a/cmd/ethtest/lib/websocket.js b/cmd/ethtest/lib/websocket.js new file mode 100644 index 000000000..24a072531 --- /dev/null +++ b/cmd/ethtest/lib/websocket.js @@ -0,0 +1,78 @@ +/* + 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 . +*/ +/** @file websocket.js + * @authors: + * Jeffrey Wilcke + * Marek Kotewicz + * Marian Oancea + * @date 2014 + */ + +// TODO: work out which of the following two lines it is supposed to be... +//if (process.env.NODE_ENV !== 'build') { +if ("build" !== "build") {/* + var WebSocket = require('ws'); // jshint ignore:line +*/} + +var WebSocketProvider = function(host) { + // onmessage handlers + this.handlers = []; + // queue will be filled with messages if send is invoked before the ws is ready + this.queued = []; + this.ready = false; + + this.ws = new WebSocket(host); + + var self = this; + this.ws.onmessage = function(event) { + for(var i = 0; i < self.handlers.length; i++) { + self.handlers[i].call(self, JSON.parse(event.data), event); + } + }; + + this.ws.onopen = function() { + self.ready = true; + + for(var i = 0; i < self.queued.length; i++) { + // Resend + self.send(self.queued[i]); + } + }; +}; + +WebSocketProvider.prototype.send = function(payload) { + if(this.ready) { + var data = JSON.stringify(payload); + + this.ws.send(data); + } else { + this.queued.push(payload); + } +}; + +WebSocketProvider.prototype.onMessage = function(handler) { + this.handlers.push(handler); +}; + +WebSocketProvider.prototype.unload = function() { + this.ws.close(); +}; +Object.defineProperty(WebSocketProvider.prototype, "onmessage", { + set: function(provider) { this.onMessage(provider); } +}); + +module.exports = WebSocketProvider; diff --git a/cmd/ethtest/package.json b/cmd/ethtest/package.json new file mode 100644 index 000000000..24141ea2e --- /dev/null +++ b/cmd/ethtest/package.json @@ -0,0 +1,67 @@ +{ + "name": "ethereum.js", + "namespace": "ethereum", + "version": "0.0.5", + "description": "Ethereum Compatible JavaScript API", + "main": "./index.js", + "directories": { + "lib": "./lib" + }, + "dependencies": { + "es6-promise": "*", + "ws": "*", + "xmlhttprequest": "*" + }, + "devDependencies": { + "bower": ">=1.3.0", + "browserify": ">=6.0", + "del": ">=0.1.1", + "envify": "^3.0.0", + "exorcist": "^0.1.6", + "gulp": ">=3.4.0", + "gulp-jshint": ">=1.5.0", + "gulp-rename": ">=1.2.0", + "gulp-uglify": ">=1.0.0", + "jshint": ">=2.5.0", + "uglifyify": "^2.6.0", + "unreachable-branch-transform": "^0.1.0", + "vinyl-source-stream": "^1.0.0" + }, + "scripts": { + "build": "gulp", + "watch": "gulp watch", + "lint": "gulp lint" + }, + "repository": { + "type": "git", + "url": "https://github.com/ethereum/ethereum.js.git" + }, + "homepage": "https://github.com/ethereum/ethereum.js", + "bugs": { + "url": "https://github.com/ethereum/ethereum.js/issues" + }, + "keywords": [ + "ethereum", + "javascript", + "API" + ], + "author": "ethdev.com", + "authors": [ + { + "name": "Jeffery Wilcke", + "email": "jeff@ethdev.com", + "url": "https://github.com/obscuren" + }, + { + "name": "Marek Kotewicz", + "email": "marek@ethdev.com", + "url": "https://github.com/debris" + }, + { + "name": "Marian Oancea", + "email": "marian@ethdev.com", + "url": "https://github.com/cubedro" + } + ], + "license": "LGPL-3.0" +} -- cgit v1.2.3 From 4051c0333f43765a7414a4e0e8ac51e7148b0646 Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 22 Dec 2014 13:23:11 +0100 Subject: Added whisper js api --- cmd/mist/assets/qml/browser.qml | 40 +++++++-- cmd/mist/assets/qml/views/whisper.qml | 2 +- cmd/mist/gui.go | 64 +++++++------- cmd/mist/ui_lib.go | 162 ++++++++++++++++------------------ 4 files changed, 145 insertions(+), 123 deletions(-) (limited to 'cmd') diff --git a/cmd/mist/assets/qml/browser.qml b/cmd/mist/assets/qml/browser.qml index 26fef0377..867260507 100644 --- a/cmd/mist/assets/qml/browser.qml +++ b/cmd/mist/assets/qml/browser.qml @@ -59,15 +59,18 @@ Rectangle { } Component.onCompleted: { - //webview.url = "http://etherian.io" - webview.url = "file:///Users/jeffrey/test.html" + webview.url = "http://etherian.io" } signal messages(var messages, int id); onMessages: { // Bit of a cheat to get proper JSON var m = JSON.parse(JSON.parse(JSON.stringify(messages))) - webview.postEvent("messages", [m, id]); + webview.postEvent("messages", id, m); + } + + function onShhMessage(message, id) { + webview.postEvent("shhChanged", id, message) } Item { @@ -328,6 +331,33 @@ Rectangle { require(1); eth.uninstallFilter(data.args[0]) break; + + + case "shhNewFilter": + require(1); + var id = shh.watch(data.args[0], window); + postData(data._id, id); + break; + + case "newIdentity": + postData(data._id, shh.newIdentity()) + break + + case "post": + require(1); + var params = data.args[0]; + var fields = ["payload", "to", "from"]; + for(var i = 0; i < fields.length; i++) { + params[fields[i]] = params[fields[i]] || ""; + } + if(typeof params.payload === "object") { params.payload = params.payload.join(""); } + params.topics = params.topics || []; + params.priority = params.priority || 1000; + params.ttl = params.ttl || 100; + + console.log(JSON.stringify(params)) + shh.post(params.payload, params.to, params.from, params.topics, params.priority, params.ttl); + break; } } catch(e) { console.log(data.call + ": " + e) @@ -349,8 +379,8 @@ Rectangle { function postData(seed, data) { webview.experimental.postMessage(JSON.stringify({data: data, _id: seed})) } - function postEvent(event, data) { - webview.experimental.postMessage(JSON.stringify({data: data, _event: event})) + function postEvent(event, id, data) { + webview.experimental.postMessage(JSON.stringify({data: data, _id: id, _event: event})) } function onWatchedCb(data, id) { diff --git a/cmd/mist/assets/qml/views/whisper.qml b/cmd/mist/assets/qml/views/whisper.qml index 80d401301..ffe391666 100644 --- a/cmd/mist/assets/qml/views/whisper.qml +++ b/cmd/mist/assets/qml/views/whisper.qml @@ -24,7 +24,7 @@ Rectangle { var t = shh.watch({}, root) } - function onMessage(message) { + function onShhMessage(message, i) { whisperModel.insert(0, {from: message.from, payload: eth.toAscii(message.payload)}) } diff --git a/cmd/mist/gui.go b/cmd/mist/gui.go index e858d7c61..1152f0dcd 100644 --- a/cmd/mist/gui.go +++ b/cmd/mist/gui.go @@ -43,38 +43,6 @@ import ( "gopkg.in/qml.v1" ) -/* -func LoadExtension(path string) (uintptr, error) { - lib, err := ffi.NewLibrary(path) - if err != nil { - return 0, err - } - - so, err := lib.Fct("sharedObject", ffi.Pointer, nil) - if err != nil { - return 0, err - } - - ptr := so() - - err = lib.Close() - if err != nil { - return 0, err - } - - return ptr.Interface().(uintptr), nil -} -*/ -/* - vec, errr := LoadExtension("/Users/jeffrey/Desktop/build-libqmltest-Desktop_Qt_5_2_1_clang_64bit-Debug/liblibqmltest_debug.dylib") - fmt.Printf("Fetched vec with addr: %#x\n", vec) - if errr != nil { - fmt.Println(errr) - } else { - context.SetVar("vec", (unsafe.Pointer)(vec)) - } -*/ - var guilogger = logger.NewLogger("GUI") type Gui struct { @@ -535,3 +503,35 @@ func (gui *Gui) privateKey() string { func (gui *Gui) address() []byte { return gui.eth.KeyManager().Address() } + +/* +func LoadExtension(path string) (uintptr, error) { + lib, err := ffi.NewLibrary(path) + if err != nil { + return 0, err + } + + so, err := lib.Fct("sharedObject", ffi.Pointer, nil) + if err != nil { + return 0, err + } + + ptr := so() + + err = lib.Close() + if err != nil { + return 0, err + } + + return ptr.Interface().(uintptr), nil +} +*/ +/* + vec, errr := LoadExtension("/Users/jeffrey/Desktop/build-libqmltest-Desktop_Qt_5_2_1_clang_64bit-Debug/liblibqmltest_debug.dylib") + fmt.Printf("Fetched vec with addr: %#x\n", vec) + if errr != nil { + fmt.Println(errr) + } else { + context.SetVar("vec", (unsafe.Pointer)(vec)) + } +*/ diff --git a/cmd/mist/ui_lib.go b/cmd/mist/ui_lib.go index fd4ffcb84..4a92f6479 100644 --- a/cmd/mist/ui_lib.go +++ b/cmd/mist/ui_lib.go @@ -225,6 +225,83 @@ func (self *UiLib) StartDebugger() { dbWindow.Show() } +func (self *UiLib) Transact(params map[string]interface{}) (string, error) { + object := mapToTxParams(params) + + return self.JSXEth.Transact( + object["from"], + object["to"], + object["value"], + object["gas"], + object["gasPrice"], + object["data"], + ) +} + +func (self *UiLib) Compile(code string) (string, error) { + bcode, err := ethutil.Compile(code, false) + if err != nil { + return err.Error(), err + } + + return ethutil.Bytes2Hex(bcode), err +} + +func (self *UiLib) Call(params map[string]interface{}) (string, error) { + object := mapToTxParams(params) + + return self.JSXEth.Execute( + object["to"], + object["value"], + object["gas"], + object["gasPrice"], + object["data"], + ) +} + +func (self *UiLib) AddLocalTransaction(to, data, gas, gasPrice, value string) int { + return self.miner.AddLocalTx(&miner.LocalTx{ + To: ethutil.Hex2Bytes(to), + Data: ethutil.Hex2Bytes(data), + Gas: gas, + GasPrice: gasPrice, + Value: value, + }) - 1 +} + +func (self *UiLib) RemoveLocalTransaction(id int) { + self.miner.RemoveLocalTx(id) +} + +func (self *UiLib) SetGasPrice(price string) { + self.miner.MinAcceptedGasPrice = ethutil.Big(price) +} + +func (self *UiLib) ToggleMining() bool { + if !self.miner.Mining() { + self.miner.Start() + + return true + } else { + self.miner.Stop() + + return false + } +} + +func (self *UiLib) ToHex(data string) string { + return "0x" + ethutil.Bytes2Hex([]byte(data)) +} + +func (self *UiLib) ToAscii(data string) string { + start := 0 + if len(data) > 1 && data[0:2] == "0x" { + start = 2 + } + return string(ethutil.Hex2Bytes(data[start:])) +} + +/// Ethereum filter methods func (self *UiLib) NewFilter(object map[string]interface{}) (id int) { filter := qt.NewFilterFromMap(object, self.eth) filter.MessageCallback = func(messages state.Messages) { @@ -312,88 +389,3 @@ func mapToTxParams(object map[string]interface{}) map[string]string { return conv } - -func (self *UiLib) Transact(params map[string]interface{}) (string, error) { - object := mapToTxParams(params) - - return self.JSXEth.Transact( - object["from"], - object["to"], - object["value"], - object["gas"], - object["gasPrice"], - object["data"], - ) -} - -func (self *UiLib) Compile(code string) (string, error) { - bcode, err := ethutil.Compile(code, false) - if err != nil { - return err.Error(), err - } - - return ethutil.Bytes2Hex(bcode), err -} - -func (self *UiLib) Call(params map[string]interface{}) (string, error) { - object := mapToTxParams(params) - - return self.JSXEth.Execute( - object["to"], - object["value"], - object["gas"], - object["gasPrice"], - object["data"], - ) -} - -func (self *UiLib) AddLocalTransaction(to, data, gas, gasPrice, value string) int { - return self.miner.AddLocalTx(&miner.LocalTx{ - To: ethutil.Hex2Bytes(to), - Data: ethutil.Hex2Bytes(data), - Gas: gas, - GasPrice: gasPrice, - Value: value, - }) - 1 -} - -func (self *UiLib) RemoveLocalTransaction(id int) { - self.miner.RemoveLocalTx(id) -} - -func (self *UiLib) SetGasPrice(price string) { - self.miner.MinAcceptedGasPrice = ethutil.Big(price) -} - -func (self *UiLib) ToggleMining() bool { - if !self.miner.Mining() { - self.miner.Start() - - return true - } else { - self.miner.Stop() - - return false - } -} - -func (self *UiLib) ToHex(data string) string { - return "0x" + ethutil.Bytes2Hex([]byte(data)) -} - -func (self *UiLib) ToAscii(data string) string { - start := 0 - if len(data) > 1 && data[0:2] == "0x" { - start = 2 - } - return string(ethutil.Hex2Bytes(data[start:])) -} - -/* -// XXX Refactor me & MOVE -func (self *Ethereum) InstallFilter(filter *core.Filter) (id int) { - return self.filterManager.InstallFilter(filter) -} -func (self *Ethereum) UninstallFilter(id int) { self.filterManager.UninstallFilter(id) } -func (self *Ethereum) GetFilter(id int) *core.Filter { return self.filterManager.GetFilter(id) } -*/ -- cgit v1.2.3 From e32f7baa0d5d949a84a3b29c57220f837eae356a Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 22 Dec 2014 14:59:52 +0100 Subject: Concat and pad data --- cmd/mist/assets/qml/browser.qml | 5 +++-- cmd/mist/assets/qml/views/whisper.qml | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'cmd') diff --git a/cmd/mist/assets/qml/browser.qml b/cmd/mist/assets/qml/browser.qml index 867260507..1425f60c0 100644 --- a/cmd/mist/assets/qml/browser.qml +++ b/cmd/mist/assets/qml/browser.qml @@ -59,7 +59,8 @@ Rectangle { } Component.onCompleted: { - webview.url = "http://etherian.io" + //webview.url = "http://etherian.io" + webview.url = "file:///Users/jeffrey/test.html" } signal messages(var messages, int id); @@ -350,7 +351,7 @@ Rectangle { for(var i = 0; i < fields.length; i++) { params[fields[i]] = params[fields[i]] || ""; } - if(typeof params.payload === "object") { params.payload = params.payload.join(""); } + if(typeof params.payload !== "object") { params.payload = [params.payload]; } //params.payload = params.payload.join(""); } params.topics = params.topics || []; params.priority = params.priority || 1000; params.ttl = params.ttl || 100; diff --git a/cmd/mist/assets/qml/views/whisper.qml b/cmd/mist/assets/qml/views/whisper.qml index ffe391666..56c4f1b07 100644 --- a/cmd/mist/assets/qml/views/whisper.qml +++ b/cmd/mist/assets/qml/views/whisper.qml @@ -52,7 +52,7 @@ Rectangle { Button { text: "Send" onClicked: { - shh.post(eth.toHex(data.text), "", identity, topics.text.split(","), 500, 50) + shh.post([eth.toHex(data.text)], "", identity, topics.text.split(","), 500, 50) } } } -- cgit v1.2.3 From 4b52cd512d3c54451e680fcc6c3d67d059065bec Mon Sep 17 00:00:00 2001 From: obscuren Date: Mon, 22 Dec 2014 15:01:52 +0100 Subject: Removal of "debug" url :) --- cmd/mist/assets/qml/browser.qml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'cmd') diff --git a/cmd/mist/assets/qml/browser.qml b/cmd/mist/assets/qml/browser.qml index 1425f60c0..abaab4f15 100644 --- a/cmd/mist/assets/qml/browser.qml +++ b/cmd/mist/assets/qml/browser.qml @@ -59,8 +59,7 @@ Rectangle { } Component.onCompleted: { - //webview.url = "http://etherian.io" - webview.url = "file:///Users/jeffrey/test.html" + webview.url = "http://etherian.io" } signal messages(var messages, int id); -- cgit v1.2.3 From 4cd79d8ddd7608d60344b13fe4bda7315429d1d9 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 23 Dec 2014 13:48:44 +0100 Subject: Refactored block & Transaction * Includes new rlp decoder --- cmd/ethereum/repl/repl.go | 6 ------ cmd/utils/cmd.go | 2 +- cmd/utils/vm_env.go | 12 ++++++------ 3 files changed, 7 insertions(+), 13 deletions(-) (limited to 'cmd') diff --git a/cmd/ethereum/repl/repl.go b/cmd/ethereum/repl/repl.go index 4a7880ff4..822aaa19d 100644 --- a/cmd/ethereum/repl/repl.go +++ b/cmd/ethereum/repl/repl.go @@ -86,12 +86,6 @@ func (self *JSRepl) Stop() { } func (self *JSRepl) parseInput(code string) { - defer func() { - if r := recover(); r != nil { - fmt.Println("[native] error", r) - } - }() - value, err := self.re.Run(code) if err != nil { fmt.Println(err) diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go index 3e3ac617a..2b24ac532 100644 --- a/cmd/utils/cmd.go +++ b/cmd/utils/cmd.go @@ -325,7 +325,7 @@ func BlockDo(ethereum *eth.Ethereum, hash []byte) error { return fmt.Errorf("unknown block %x", hash) } - parent := ethereum.ChainManager().GetBlock(block.PrevHash) + parent := ethereum.ChainManager().GetBlock(block.ParentHash()) _, err := ethereum.BlockManager().TransitionState(parent.State(), parent, block) if err != nil { diff --git a/cmd/utils/vm_env.go b/cmd/utils/vm_env.go index 461a797c2..be6249e82 100644 --- a/cmd/utils/vm_env.go +++ b/cmd/utils/vm_env.go @@ -30,15 +30,15 @@ func NewEnv(state *state.StateDB, block *types.Block, transactor []byte, value * } func (self *VMEnv) Origin() []byte { return self.transactor } -func (self *VMEnv) BlockNumber() *big.Int { return self.block.Number } -func (self *VMEnv) PrevHash() []byte { return self.block.PrevHash } -func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase } -func (self *VMEnv) Time() int64 { return self.block.Time } -func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty } +func (self *VMEnv) BlockNumber() *big.Int { return self.block.Number() } +func (self *VMEnv) PrevHash() []byte { return self.block.ParentHash() } +func (self *VMEnv) Coinbase() []byte { return self.block.Coinbase() } +func (self *VMEnv) Time() int64 { return self.block.Time() } +func (self *VMEnv) Difficulty() *big.Int { return self.block.Difficulty() } func (self *VMEnv) BlockHash() []byte { return self.block.Hash() } +func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit() } func (self *VMEnv) Value() *big.Int { return self.value } func (self *VMEnv) State() *state.StateDB { return self.state } -func (self *VMEnv) GasLimit() *big.Int { return self.block.GasLimit } func (self *VMEnv) Depth() int { return self.depth } func (self *VMEnv) SetDepth(i int) { self.depth = i } func (self *VMEnv) AddLog(log state.Log) { -- cgit v1.2.3 From 9e5257b83b8572077b9c26e4ae9a9443f765bf6e Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 23 Dec 2014 14:33:15 +0100 Subject: Chain importer --- cmd/ethereum/flags.go | 2 ++ cmd/ethereum/main.go | 28 +++++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) (limited to 'cmd') diff --git a/cmd/ethereum/flags.go b/cmd/ethereum/flags.go index 72f1db458..d27b739c3 100644 --- a/cmd/ethereum/flags.go +++ b/cmd/ethereum/flags.go @@ -58,6 +58,7 @@ var ( DumpHash string DumpNumber int VmType int + ImportChain string ) // flags specific to cli client @@ -104,6 +105,7 @@ func Init() { 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 fiven 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") diff --git a/cmd/ethereum/main.go b/cmd/ethereum/main.go index fff9aedf8..f16244a2d 100644 --- a/cmd/ethereum/main.go +++ b/cmd/ethereum/main.go @@ -18,6 +18,7 @@ package main import ( + "bytes" "fmt" "os" "runtime" @@ -26,6 +27,7 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/rlp" ) const ( @@ -38,6 +40,10 @@ var clilogger = logger.NewLogger("CLI") func main() { runtime.GOMAXPROCS(runtime.NumCPU()) + defer func() { + logger.Flush() + }() + utils.HandleInterrupt() // precedence: code-internal flag default < config file < environment variables < command line @@ -112,6 +118,27 @@ func main() { utils.StartMining(ethereum) } + if len(ImportChain) > 0 { + clilogger.Infof("importing chain '%s'\n", ImportChain) + c, err := ethutil.ReadAllFile(ImportChain) + if err != nil { + clilogger.Infoln(err) + return + } + var chain types.Blocks + if err := rlp.Decode(bytes.NewReader([]byte(c)), &chain); err != nil { + clilogger.Infoln(err) + return + } + + ethereum.ChainManager().Reset() + if err := ethereum.ChainManager().InsertChain(chain); err != nil { + clilogger.Infoln(err) + return + } + clilogger.Infof("imported %d blocks\n", len(chain)) + } + // better reworked as cases if StartJsConsole { InitJsConsole(ethereum) @@ -131,5 +158,4 @@ func main() { // this blocks the thread ethereum.WaitForShutdown() - logger.Flush() } -- cgit v1.2.3 From e2e3fa3d11b37c8a22ebafe9c02dfd8089ac4d51 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 23 Dec 2014 14:44:45 +0100 Subject: Updated Mist to use new blocks --- cmd/mist/gui.go | 8 ++++---- cmd/mist/html_container.go | 2 +- cmd/mist/qml_container.go | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) (limited to 'cmd') diff --git a/cmd/mist/gui.go b/cmd/mist/gui.go index 1152f0dcd..e5e18bbaa 100644 --- a/cmd/mist/gui.go +++ b/cmd/mist/gui.go @@ -221,7 +221,7 @@ func (gui *Gui) setInitialChain(ancientBlocks bool) { sBlk := gui.eth.ChainManager().LastBlockHash() blk := gui.eth.ChainManager().GetBlock(sBlk) for ; blk != nil; blk = gui.eth.ChainManager().GetBlock(sBlk) { - sBlk = blk.PrevHash + sBlk = blk.ParentHash() gui.processBlock(blk, true) } @@ -322,7 +322,7 @@ func (gui *Gui) readPreviousTransactions() { } func (gui *Gui) processBlock(block *types.Block, initial bool) { - name := strings.Trim(gui.pipe.World().Config().Get("NameReg").Storage(block.Coinbase).Str(), "\x00") + name := strings.Trim(gui.pipe.World().Config().Get("NameReg").Storage(block.Coinbase()).Str(), "\x00") b := xeth.NewJSBlock(block) b.Name = name @@ -400,7 +400,7 @@ func (gui *Gui) update() { switch ev := ev.(type) { case core.NewBlockEvent: gui.processBlock(ev.Block, false) - if bytes.Compare(ev.Block.Coinbase, gui.address()) == 0 { + if bytes.Compare(ev.Block.Coinbase(), gui.address()) == 0 { gui.setWalletValue(gui.eth.ChainManager().State().GetBalance(gui.address()), nil) } @@ -438,7 +438,7 @@ func (gui *Gui) update() { case <-peerUpdateTicker.C: gui.setPeerInfo() case <-generalUpdateTicker.C: - statusText := "#" + gui.eth.ChainManager().CurrentBlock().Number.String() + statusText := "#" + gui.eth.ChainManager().CurrentBlock().Number().String() lastBlockLabel.Set("text", statusText) miningLabel.Set("text", "Mining @ "+strconv.FormatInt(gui.uiLib.miner.GetPow().GetHashrate(), 10)+"Khash") diff --git a/cmd/mist/html_container.go b/cmd/mist/html_container.go index b3fc219fa..bd11ccd57 100644 --- a/cmd/mist/html_container.go +++ b/cmd/mist/html_container.go @@ -139,7 +139,7 @@ func (app *HtmlApplication) Window() *qml.Window { } func (app *HtmlApplication) NewBlock(block *types.Block) { - b := &xeth.JSBlock{Number: int(block.BlockInfo().Number), Hash: ethutil.Bytes2Hex(block.Hash())} + b := &xeth.JSBlock{Number: int(block.NumberU64()), Hash: ethutil.Bytes2Hex(block.Hash())} app.webView.Call("onNewBlockCb", b) } diff --git a/cmd/mist/qml_container.go b/cmd/mist/qml_container.go index a0a46f9b1..ed24737d0 100644 --- a/cmd/mist/qml_container.go +++ b/cmd/mist/qml_container.go @@ -66,7 +66,7 @@ func (app *QmlApplication) NewWatcher(quitChan chan bool) { // Events func (app *QmlApplication) NewBlock(block *types.Block) { - pblock := &xeth.JSBlock{Number: int(block.BlockInfo().Number), Hash: ethutil.Bytes2Hex(block.Hash())} + pblock := &xeth.JSBlock{Number: int(block.NumberU64()), Hash: ethutil.Bytes2Hex(block.Hash())} app.win.Call("onNewBlockCb", pblock) } -- cgit v1.2.3 From 34f72ddb3d5a01d6c45c75604bc030c287d51fb2 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 23 Dec 2014 15:18:48 +0100 Subject: Decode from stream directly --- cmd/ethereum/main.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'cmd') diff --git a/cmd/ethereum/main.go b/cmd/ethereum/main.go index f16244a2d..12e22a438 100644 --- a/cmd/ethereum/main.go +++ b/cmd/ethereum/main.go @@ -18,7 +18,6 @@ package main import ( - "bytes" "fmt" "os" "runtime" @@ -120,13 +119,13 @@ func main() { if len(ImportChain) > 0 { clilogger.Infof("importing chain '%s'\n", ImportChain) - c, err := ethutil.ReadAllFile(ImportChain) + fh, err := os.OpenFile(ImportChain, os.O_RDONLY, os.ModePerm) if err != nil { clilogger.Infoln(err) return } var chain types.Blocks - if err := rlp.Decode(bytes.NewReader([]byte(c)), &chain); err != nil { + if err := rlp.Decode(fh, &chain); err != nil { clilogger.Infoln(err) return } -- cgit v1.2.3 From 7d2353f24dad8bba8914b4014117fe73248c211c Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 23 Dec 2014 15:31:03 +0100 Subject: Close the file --- cmd/ethereum/main.go | 2 ++ 1 file changed, 2 insertions(+) (limited to 'cmd') diff --git a/cmd/ethereum/main.go b/cmd/ethereum/main.go index 12e22a438..d704140d4 100644 --- a/cmd/ethereum/main.go +++ b/cmd/ethereum/main.go @@ -124,6 +124,8 @@ func main() { clilogger.Infoln(err) return } + defer fh.Close() + var chain types.Blocks if err := rlp.Decode(fh, &chain); err != nil { clilogger.Infoln(err) -- cgit v1.2.3 From 1054c155db8ac59b97b81fa7a7a20f2239eb1e82 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 23 Dec 2014 15:37:03 +0100 Subject: Moved import to utils --- cmd/ethereum/main.go | 20 ++------------------ cmd/utils/cmd.go | 24 ++++++++++++++++++++++++ 2 files changed, 26 insertions(+), 18 deletions(-) (limited to 'cmd') diff --git a/cmd/ethereum/main.go b/cmd/ethereum/main.go index d704140d4..2e0a5663a 100644 --- a/cmd/ethereum/main.go +++ b/cmd/ethereum/main.go @@ -26,7 +26,6 @@ import ( "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/logger" - "github.com/ethereum/go-ethereum/rlp" ) const ( @@ -118,26 +117,11 @@ func main() { } if len(ImportChain) > 0 { - clilogger.Infof("importing chain '%s'\n", ImportChain) - fh, err := os.OpenFile(ImportChain, os.O_RDONLY, os.ModePerm) + err := utils.ImportChain(ethereum, ImportChain) if err != nil { clilogger.Infoln(err) - return } - defer fh.Close() - - var chain types.Blocks - if err := rlp.Decode(fh, &chain); err != nil { - clilogger.Infoln(err) - return - } - - ethereum.ChainManager().Reset() - if err := ethereum.ChainManager().InsertChain(chain); err != nil { - clilogger.Infoln(err) - return - } - clilogger.Infof("imported %d blocks\n", len(chain)) + return } // better reworked as cases diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go index 2b24ac532..c0a5d1c97 100644 --- a/cmd/utils/cmd.go +++ b/cmd/utils/cmd.go @@ -13,6 +13,7 @@ import ( "runtime" "bitbucket.org/kardianos/osext" + "github.com/ethereum/go-ethereum/core/types" "github.com/ethereum/go-ethereum/crypto" "github.com/ethereum/go-ethereum/eth" "github.com/ethereum/go-ethereum/ethdb" @@ -20,6 +21,7 @@ import ( "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/miner" "github.com/ethereum/go-ethereum/p2p" + "github.com/ethereum/go-ethereum/rlp" "github.com/ethereum/go-ethereum/rpc" "github.com/ethereum/go-ethereum/xeth" ) @@ -335,3 +337,25 @@ func BlockDo(ethereum *eth.Ethereum, hash []byte) error { return nil } + +func ImportChain(ethereum *eth.Ethereum, fn string) error { + clilogger.Infof("importing chain '%s'\n", ImportChain) + 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 { + return err + } + + ethereum.ChainManager().Reset() + if err := ethereum.ChainManager().InsertChain(chain); err != nil { + return err + } + clilogger.Infof("imported %d blocks\n", len(chain)) + + return nil +} -- cgit v1.2.3 From f468a9a0e236f8467012ffe35c1d8ff58e30a81a Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 23 Dec 2014 15:46:46 +0100 Subject: Enable websockets for mist. Closes #218 --- cmd/mist/main.go | 4 ++++ cmd/utils/websockets.go | 5 +++++ 2 files changed, 9 insertions(+) (limited to 'cmd') diff --git a/cmd/mist/main.go b/cmd/mist/main.go index eaf0af0c7..5f809f1c5 100644 --- a/cmd/mist/main.go +++ b/cmd/mist/main.go @@ -69,6 +69,10 @@ func run() error { utils.StartRpc(ethereum, RpcPort) } + if StartWebSockets { + utils.StartWebSockets(ethereum) + } + gui := NewWindow(ethereum, config, clientIdentity, KeyRing, LogLevel) gui.stdLog = stdLog diff --git a/cmd/utils/websockets.go b/cmd/utils/websockets.go index d3ba50e78..cf9ebba92 100644 --- a/cmd/utils/websockets.go +++ b/cmd/utils/websockets.go @@ -3,10 +3,13 @@ package utils import ( "github.com/ethereum/go-ethereum" "github.com/ethereum/go-ethereum/ethutil" + "github.com/ethereum/go-ethereum/logger" "github.com/ethereum/go-ethereum/websocket" "github.com/ethereum/go-ethereum/xeth" ) +var wslogger = logger.NewLogger("WS") + func args(v ...interface{}) []interface{} { return v } @@ -106,6 +109,8 @@ func (self *WebSocketServer) Serv() { } func StartWebSockets(eth *eth.Ethereum) { + wslogger.Infoln("Starting WebSockets") + sock := NewWebSocketServer(eth) go sock.Serv() } -- cgit v1.2.3 From 780abaec988df302e0c98f1a35e9af35b5623746 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 23 Dec 2014 18:35:36 +0100 Subject: Switched to new trie --- cmd/ethereum/main.go | 6 +++--- cmd/utils/cmd.go | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) (limited to 'cmd') diff --git a/cmd/ethereum/main.go b/cmd/ethereum/main.go index 2e0a5663a..e4070aa47 100644 --- a/cmd/ethereum/main.go +++ b/cmd/ethereum/main.go @@ -21,6 +21,7 @@ import ( "fmt" "os" "runtime" + "time" "github.com/ethereum/go-ethereum/cmd/utils" "github.com/ethereum/go-ethereum/core/types" @@ -97,9 +98,6 @@ func main() { os.Exit(1) } - // block.GetRoot() does not exist - //fmt.Printf("RLP: %x\nstate: %x\nhash: %x\n", ethutil.Rlp(block), block.GetRoot(), block.Hash()) - // Leave the Println. This needs clean output for piping fmt.Printf("%s\n", block.State().Dump()) @@ -117,10 +115,12 @@ func main() { } if len(ImportChain) > 0 { + start := time.Now() err := utils.ImportChain(ethereum, ImportChain) if err != nil { clilogger.Infoln(err) } + clilogger.Infoln("export done in", time.Since(start)) return } diff --git a/cmd/utils/cmd.go b/cmd/utils/cmd.go index c0a5d1c97..466c51383 100644 --- a/cmd/utils/cmd.go +++ b/cmd/utils/cmd.go @@ -339,7 +339,7 @@ func BlockDo(ethereum *eth.Ethereum, hash []byte) error { } func ImportChain(ethereum *eth.Ethereum, fn string) error { - clilogger.Infof("importing chain '%s'\n", ImportChain) + clilogger.Infof("importing chain '%s'\n", fn) fh, err := os.OpenFile(fn, os.O_RDONLY, os.ModePerm) if err != nil { return err -- cgit v1.2.3 From c9f963a77e6e728c90e08c0e0008f1dc40df1fe0 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 24 Dec 2014 11:30:04 +0100 Subject: Bump --- cmd/ethereum/main.go | 2 +- cmd/mist/main.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'cmd') diff --git a/cmd/ethereum/main.go b/cmd/ethereum/main.go index 2a3c46054..30107c145 100644 --- a/cmd/ethereum/main.go +++ b/cmd/ethereum/main.go @@ -30,7 +30,7 @@ import ( const ( ClientIdentifier = "Ethereum(G)" - Version = "0.7.10" + Version = "0.7.11" ) var clilogger = logger.NewLogger("CLI") diff --git a/cmd/mist/main.go b/cmd/mist/main.go index eaf0af0c7..c6dc80171 100644 --- a/cmd/mist/main.go +++ b/cmd/mist/main.go @@ -31,7 +31,7 @@ import ( const ( ClientIdentifier = "Mist" - Version = "0.7.10" + Version = "0.7.11" ) var ethereum *eth.Ethereum -- cgit v1.2.3 From dc7c584a4de371e449752dce5b5e90b26c83d0bb Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 24 Dec 2014 14:54:06 +0100 Subject: export => import --- cmd/ethereum/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'cmd') diff --git a/cmd/ethereum/main.go b/cmd/ethereum/main.go index 3f9a2a838..7efee31e7 100644 --- a/cmd/ethereum/main.go +++ b/cmd/ethereum/main.go @@ -120,7 +120,7 @@ func main() { if err != nil { clilogger.Infoln(err) } - clilogger.Infoln("export done in", time.Since(start)) + clilogger.Infoln("import done in", time.Since(start)) return } -- cgit v1.2.3 From 1085960ed8550eb64ae7031b43b1174c8f1c8f94 Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 30 Dec 2014 15:58:40 +0100 Subject: fixed trie --- cmd/evm/main.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'cmd') diff --git a/cmd/evm/main.go b/cmd/evm/main.go index 2bdfdfa9f..66bba7289 100644 --- a/cmd/evm/main.go +++ b/cmd/evm/main.go @@ -37,8 +37,8 @@ import ( "github.com/ethereum/go-ethereum/ethdb" "github.com/ethereum/go-ethereum/ethutil" "github.com/ethereum/go-ethereum/logger" + "github.com/ethereum/go-ethereum/ptrie" "github.com/ethereum/go-ethereum/state" - "github.com/ethereum/go-ethereum/trie" "github.com/ethereum/go-ethereum/vm" ) @@ -65,7 +65,7 @@ func main() { ethutil.ReadConfig("/tmp/evmtest", "/tmp/evm", "") db, _ := ethdb.NewMemDatabase() - statedb := state.New(trie.New(db, "")) + statedb := state.New(ptrie.New(nil, db)) sender := statedb.NewStateObject([]byte("sender")) receiver := statedb.NewStateObject([]byte("receiver")) //receiver.SetCode([]byte(*code)) -- cgit v1.2.3 From 89244981a8a9f190a6afc74ec2c584692f04dcdd Mon Sep 17 00:00:00 2001 From: obscuren Date: Tue, 30 Dec 2014 17:09:54 +0100 Subject: Additional checking on gas --- cmd/ethtest/main.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'cmd') diff --git a/cmd/ethtest/main.go b/cmd/ethtest/main.go index 94ab779db..96ef94e40 100644 --- a/cmd/ethtest/main.go +++ b/cmd/ethtest/main.go @@ -95,10 +95,15 @@ func RunVmTest(js string) (failed int) { failed = 1 } - gexp := ethutil.Big(test.Gas) - if gexp.Cmp(gas) != 0 { - log.Printf("%s's gas failed. Expected %v, got %v\n", name, gexp, gas) + if len(test.Gas) == 0 && err == nil { + log.Printf("0 gas indicates error but no error given by VM") failed = 1 + } else { + gexp := ethutil.Big(test.Gas) + if gexp.Cmp(gas) != 0 { + log.Printf("%s's gas failed. Expected %v, got %v\n", name, gexp, gas) + failed = 1 + } } for addr, account := range test.Post { -- cgit v1.2.3