From 94b12f7804bfb32763c9bbbce323af5d84c74910 Mon Sep 17 00:00:00 2001 From: zelig Date: Tue, 15 Jul 2014 00:05:18 +0100 Subject: [PATCH 01/16] fix start mining --- utils/cmd.go | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/utils/cmd.go b/utils/cmd.go index 889726b04938..dfd867d64fe6 100644 --- a/utils/cmd.go +++ b/utils/cmd.go @@ -124,6 +124,7 @@ func NewDatabase() ethutil.Database { } func NewClientIdentity(clientIdentifier, version, customIdentifier string) *ethwire.SimpleClientIdentity { + logger.Infoln("identity created") return ethwire.NewSimpleClientIdentity(clientIdentifier, version, customIdentifier) } @@ -209,10 +210,10 @@ var miner ethminer.Miner func StartMining(ethereum *eth.Ethereum) bool { if !ethereum.Mining { ethereum.Mining = true - addr := ethereum.KeyManager().Address() go func() { + logger.Infoln("Start mining") miner = ethminer.NewDefaultMiner(addr, ethereum) // Give it some time to connect with peers time.Sleep(3 * time.Second) @@ -220,8 +221,6 @@ func StartMining(ethereum *eth.Ethereum) bool { time.Sleep(5 * time.Second) } - logger.Infoln("Miner started") - miner := ethminer.NewDefaultMiner(addr, ethereum) miner.Start() }() RegisterInterrupt(func(os.Signal) { @@ -235,7 +234,7 @@ func StartMining(ethereum *eth.Ethereum) bool { func StopMining(ethereum *eth.Ethereum) bool { if ethereum.Mining { miner.Stop() - logger.Infoln("Miner stopped") + logger.Infoln("Stopped mining") ethereum.Mining = false return true } From 75a7a4c97c350e911f4d721e940a59c0740ae967 Mon Sep 17 00:00:00 2001 From: zelig Date: Tue, 15 Jul 2014 01:13:39 +0100 Subject: [PATCH 02/16] ethreact - use ethreact.Event, - increased buffered event channels, - subscribe after loop reading from channel starts --- ethereal/ext_app.go | 9 +-- ethereal/gui.go | 107 +++++++++++++++++---------------- ethereum/javascript_runtime.go | 17 +++--- 3 files changed, 68 insertions(+), 65 deletions(-) diff --git a/ethereal/ext_app.go b/ethereal/ext_app.go index 17c342a1b93c..736b059e5028 100644 --- a/ethereal/ext_app.go +++ b/ethereal/ext_app.go @@ -4,6 +4,7 @@ import ( "fmt" "github.com/ethereum/eth-go/ethchain" "github.com/ethereum/eth-go/ethpub" + "github.com/ethereum/eth-go/ethreact" "github.com/ethereum/eth-go/ethutil" "github.com/go-qml/qml" ) @@ -24,8 +25,8 @@ type AppContainer interface { type ExtApplication struct { *ethpub.PEthereum - blockChan chan ethutil.React - changeChan chan ethutil.React + blockChan chan ethreact.Event + changeChan chan ethreact.Event quitChan chan bool watcherQuitChan chan bool @@ -37,8 +38,8 @@ type ExtApplication struct { func NewExtApplication(container AppContainer, lib *UiLib) *ExtApplication { app := &ExtApplication{ ethpub.NewPEthereum(lib.eth), - make(chan ethutil.React, 1), - make(chan ethutil.React, 1), + make(chan ethreact.Event, 10), + make(chan ethreact.Event, 10), make(chan bool), make(chan bool), container, diff --git a/ethereal/gui.go b/ethereal/gui.go index 9f28045f8660..eb0c50cc3674 100644 --- a/ethereal/gui.go +++ b/ethereal/gui.go @@ -8,6 +8,7 @@ import ( "github.com/ethereum/eth-go/ethdb" "github.com/ethereum/eth-go/ethlog" "github.com/ethereum/eth-go/ethpub" + "github.com/ethereum/eth-go/ethreact" "github.com/ethereum/eth-go/ethutil" "github.com/ethereum/eth-go/ethwire" "github.com/ethereum/go-ethereum/utils" @@ -143,7 +144,7 @@ func (gui *Gui) showWallet(context *qml.Context) (*qml.Window, error) { gui.readPreviousTransactions() gui.setPeerInfo() - go gui.update() + gui.update() return win, nil } @@ -266,21 +267,10 @@ func (gui *Gui) setWalletValue(amount, unconfirmedFunds *big.Int) { func (gui *Gui) update() { reactor := gui.eth.Reactor() - blockChan := make(chan ethutil.React, 1) - txChan := make(chan ethutil.React, 1) - objectChan := make(chan ethutil.React, 1) - peerChan := make(chan ethutil.React, 1) - - reactor.Subscribe("newBlock", blockChan) - reactor.Subscribe("newTx:pre", txChan) - reactor.Subscribe("newTx:post", txChan) - - nameReg := ethpub.EthereumConfig(gui.eth.StateManager()).NameReg() - if nameReg != nil { - reactor.Subscribe("object:"+string(nameReg.Address()), objectChan) - } - reactor.Subscribe("peerList", peerChan) - + blockChan := make(chan ethreact.Event, 1) + txChan := make(chan ethreact.Event, 1) + objectChan := make(chan ethreact.Event, 1) + peerChan := make(chan ethreact.Event, 1) ticker := time.NewTicker(5 * time.Second) state := gui.eth.StateManager().TransState() @@ -288,54 +278,65 @@ func (gui *Gui) update() { unconfirmedFunds := new(big.Int) gui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(state.GetAccount(gui.address()).Amount))) - for { - select { - case b := <-blockChan: - block := b.Resource.(*ethchain.Block) - gui.processBlock(block, false) - if bytes.Compare(block.Coinbase, gui.address()) == 0 { - gui.setWalletValue(gui.eth.StateManager().CurrentState().GetAccount(gui.address()).Amount, nil) - } + go func() { + for { + select { + case b := <-blockChan: + block := b.Resource.(*ethchain.Block) + gui.processBlock(block, false) + if bytes.Compare(block.Coinbase, gui.address()) == 0 { + gui.setWalletValue(gui.eth.StateManager().CurrentState().GetAccount(gui.address()).Amount, nil) + } - case txMsg := <-txChan: - tx := txMsg.Resource.(*ethchain.Transaction) + case txMsg := <-txChan: + tx := txMsg.Resource.(*ethchain.Transaction) - if txMsg.Event == "newTx:pre" { - object := state.GetAccount(gui.address()) + if txMsg.Name == "newTx:pre" { + object := state.GetAccount(gui.address()) - if bytes.Compare(tx.Sender(), gui.address()) == 0 { - gui.win.Root().Call("addTx", ethpub.NewPTx(tx), "send") - gui.txDb.Put(tx.Hash(), tx.RlpEncode()) + if bytes.Compare(tx.Sender(), gui.address()) == 0 { + gui.win.Root().Call("addTx", ethpub.NewPTx(tx), "send") + gui.txDb.Put(tx.Hash(), tx.RlpEncode()) - unconfirmedFunds.Sub(unconfirmedFunds, tx.Value) - } else if bytes.Compare(tx.Recipient, gui.address()) == 0 { - gui.win.Root().Call("addTx", ethpub.NewPTx(tx), "recv") - gui.txDb.Put(tx.Hash(), tx.RlpEncode()) + unconfirmedFunds.Sub(unconfirmedFunds, tx.Value) + } else if bytes.Compare(tx.Recipient, gui.address()) == 0 { + gui.win.Root().Call("addTx", ethpub.NewPTx(tx), "recv") + gui.txDb.Put(tx.Hash(), tx.RlpEncode()) - unconfirmedFunds.Add(unconfirmedFunds, tx.Value) - } + unconfirmedFunds.Add(unconfirmedFunds, tx.Value) + } - gui.setWalletValue(object.Amount, unconfirmedFunds) - } else { - object := state.GetAccount(gui.address()) - if bytes.Compare(tx.Sender(), gui.address()) == 0 { - object.SubAmount(tx.Value) - } else if bytes.Compare(tx.Recipient, gui.address()) == 0 { - object.AddAmount(tx.Value) - } + gui.setWalletValue(object.Amount, unconfirmedFunds) + } else { + object := state.GetAccount(gui.address()) + if bytes.Compare(tx.Sender(), gui.address()) == 0 { + object.SubAmount(tx.Value) + } else if bytes.Compare(tx.Recipient, gui.address()) == 0 { + object.AddAmount(tx.Value) + } - gui.setWalletValue(object.Amount, nil) + gui.setWalletValue(object.Amount, nil) - state.UpdateStateObject(object) + state.UpdateStateObject(object) + } + case <-objectChan: + gui.loadAddressBook() + case <-peerChan: + gui.setPeerInfo() + case <-ticker.C: + gui.setPeerInfo() } - case <-objectChan: - gui.loadAddressBook() - case <-peerChan: - gui.setPeerInfo() - case <-ticker.C: - gui.setPeerInfo() } + }() + reactor.Subscribe("newBlock", blockChan) + reactor.Subscribe("newTx:pre", txChan) + reactor.Subscribe("newTx:post", txChan) + + nameReg := ethpub.EthereumConfig(gui.eth.StateManager()).NameReg() + if nameReg != nil { + reactor.Subscribe("object:"+string(nameReg.Address()), objectChan) } + reactor.Subscribe("peerList", peerChan) } func (gui *Gui) setPeerInfo() { diff --git a/ethereum/javascript_runtime.go b/ethereum/javascript_runtime.go index 852a5048794d..998ff7520e30 100644 --- a/ethereum/javascript_runtime.go +++ b/ethereum/javascript_runtime.go @@ -6,6 +6,7 @@ import ( "github.com/ethereum/eth-go/ethchain" "github.com/ethereum/eth-go/ethlog" "github.com/ethereum/eth-go/ethpub" + "github.com/ethereum/eth-go/ethreact" "github.com/ethereum/eth-go/ethutil" "github.com/ethereum/go-ethereum/utils" "github.com/obscuren/otto" @@ -22,8 +23,8 @@ type JSRE struct { vm *otto.Otto lib *ethpub.PEthereum - blockChan chan ethutil.React - changeChan chan ethutil.React + blockChan chan ethreact.Event + changeChan chan ethreact.Event quitChan chan bool objectCb map[string][]otto.Value @@ -48,8 +49,8 @@ func NewJSRE(ethereum *eth.Ethereum) *JSRE { ethereum, otto.New(), ethpub.NewPEthereum(ethereum), - make(chan ethutil.React, 1), - make(chan ethutil.React, 1), + make(chan ethreact.Event, 10), + make(chan ethreact.Event, 10), make(chan bool), make(map[string][]otto.Value), } @@ -64,6 +65,10 @@ func NewJSRE(ethereum *eth.Ethereum) *JSRE { // We have to make sure that, whoever calls this, calls "Stop" go re.mainLoop() + // Subscribe to events + reactor := ethereum.Reactor() + reactor.Subscribe("newBlock", self.blockChan) + re.Bind("eth", &JSEthereum{re.lib, re.vm}) re.initStdFuncs() @@ -108,10 +113,6 @@ func (self *JSRE) Stop() { } func (self *JSRE) mainLoop() { - // Subscribe to events - reactor := self.ethereum.Reactor() - reactor.Subscribe("newBlock", self.blockChan) - out: for { select { From 74abc457ada9ef17c39c488a9e7625cecd4e6141 Mon Sep 17 00:00:00 2001 From: zelig Date: Mon, 21 Jul 2014 19:26:01 +0100 Subject: [PATCH 03/16] reactor event channels have large buffer to allow more tolerance --- ethereal/ext_app.go | 4 ++-- ethereal/gui.go | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/ethereal/ext_app.go b/ethereal/ext_app.go index 736b059e5028..ee723fc3db41 100644 --- a/ethereal/ext_app.go +++ b/ethereal/ext_app.go @@ -38,8 +38,8 @@ type ExtApplication struct { func NewExtApplication(container AppContainer, lib *UiLib) *ExtApplication { app := &ExtApplication{ ethpub.NewPEthereum(lib.eth), - make(chan ethreact.Event, 10), - make(chan ethreact.Event, 10), + make(chan ethreact.Event, 100), + make(chan ethreact.Event, 100), make(chan bool), make(chan bool), container, diff --git a/ethereal/gui.go b/ethereal/gui.go index bfae97050d67..9bc11e81ec22 100644 --- a/ethereal/gui.go +++ b/ethereal/gui.go @@ -281,12 +281,12 @@ func (self *Gui) getObjectByName(objectName string) qml.Object { func (gui *Gui) update() { var ( - blockChan = make(chan ethreact.Event, 1) - txChan = make(chan ethreact.Event, 1) - objectChan = make(chan ethreact.Event, 1) - peerChan = make(chan ethreact.Event, 1) - chainSyncChan = make(chan ethreact.Event, 1) - miningChan = make(chan ethreact.Event, 1) + blockChan = make(chan ethreact.Event, 100) + txChan = make(chan ethreact.Event, 100) + objectChan = make(chan ethreact.Event, 100) + peerChan = make(chan ethreact.Event, 100) + chainSyncChan = make(chan ethreact.Event, 100) + miningChan = make(chan ethreact.Event, 100) ) peerUpdateTicker := time.NewTicker(5 * time.Second) From 2f5c95610feb77dd714bf9295d6127bef58f31bc Mon Sep 17 00:00:00 2001 From: zelig Date: Mon, 21 Jul 2014 19:55:47 +0100 Subject: [PATCH 04/16] use logger instead of fmt for error in ext_app --- ethereal/ext_app.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/ethereal/ext_app.go b/ethereal/ext_app.go index ee723fc3db41..ac745ae377b1 100644 --- a/ethereal/ext_app.go +++ b/ethereal/ext_app.go @@ -1,7 +1,6 @@ package main import ( - "fmt" "github.com/ethereum/eth-go/ethchain" "github.com/ethereum/eth-go/ethpub" "github.com/ethereum/eth-go/ethreact" @@ -58,8 +57,7 @@ func (app *ExtApplication) run() { err := app.container.Create() if err != nil { - fmt.Println(err) - + logger.Errorln(err) return } From 97004f7eb22ab30ba1acc5dd3ee2f17b5466d41a Mon Sep 17 00:00:00 2001 From: obscuren Date: Fri, 25 Jul 2014 10:41:57 +0200 Subject: [PATCH 05/16] wip export --- ethereal/assets/qml/wallet.qml | 34 ++++++++++++++++++++++++++++++++-- ethereal/gui.go | 3 +++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/ethereal/assets/qml/wallet.qml b/ethereal/assets/qml/wallet.qml index eef49824f1de..aadc90e3b475 100644 --- a/ethereal/assets/qml/wallet.qml +++ b/ethereal/assets/qml/wallet.qml @@ -26,6 +26,22 @@ ApplicationWindow { shortcut: "Ctrl+o" onTriggered: openAppDialog.open() } + + MenuSeparator {} + + MenuItem { + text: "Import key" + shortcut: "Ctrl+i" + onTriggered: importDialog.open() + } + + MenuItem { + text: "Export keys" + shortcut: "Ctrl+e" + onTriggered: exportDialog.open() + } + + //MenuSeparator {} } Menu { @@ -375,9 +391,7 @@ ApplicationWindow { //ui.open(openAppDialog.fileUrl.toString()) //ui.openHtml(Qt.resolvedUrl(ui.assetPath("test.html"))) var path = openAppDialog.fileUrl.toString() - console.log(path) var ext = path.split('.').pop() - console.log(ext) if(ext == "html" || ext == "htm") { ui.openHtml(path) }else if(ext == "qml"){ @@ -386,6 +400,22 @@ ApplicationWindow { } } + FileDialog { + id: exportDialog + title: "Export keys" + onAccepted: { + } + } + + FileDialog { + id: importDialog + title: "Import key" + onAccepted: { + var path = this.fileUrl.toString() + ui.importKey(path) + } + } + statusBar: StatusBar { height: 30 RowLayout { diff --git a/ethereal/gui.go b/ethereal/gui.go index df01cddda0c7..832200176f7c 100644 --- a/ethereal/gui.go +++ b/ethereal/gui.go @@ -155,6 +155,9 @@ func (gui *Gui) showWallet(context *qml.Context) (*qml.Window, error) { return win, nil } +func (gui *Gui) ImportKey(filePath string) { +} + func (gui *Gui) showKeyImport(context *qml.Context) (*qml.Window, error) { context.SetVar("lib", gui) component, err := gui.engine.LoadFile(gui.uiLib.AssetPath("qml/first_run.qml")) From 5c9fd19105c572ea717a8bc04758dcf3e71af47e Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 30 Jul 2014 00:17:23 +0200 Subject: [PATCH 06/16] A few start up optimisations --- ethereal/assets/qml/wallet.qml | 2 +- ethereal/gui.go | 4 ++-- ethereal/html_container.go | 13 +++++++------ ethereal/qml_container.go | 2 +- 4 files changed, 11 insertions(+), 10 deletions(-) diff --git a/ethereal/assets/qml/wallet.qml b/ethereal/assets/qml/wallet.qml index aadc90e3b475..50ff73060ca4 100644 --- a/ethereal/assets/qml/wallet.qml +++ b/ethereal/assets/qml/wallet.qml @@ -690,7 +690,7 @@ ApplicationWindow { anchors.left: aboutIcon.right anchors.leftMargin: 10 font.pointSize: 12 - text: "

Ethereal


Development

Jeffrey Wilcke
Maran Hidskes
Viktor Trón
" + text: "

Ethereal - Adrastea


Development

Jeffrey Wilcke
Maran Hidskes
Viktor Trón
" } } diff --git a/ethereal/gui.go b/ethereal/gui.go index 832200176f7c..573f68959fdd 100644 --- a/ethereal/gui.go +++ b/ethereal/gui.go @@ -144,10 +144,10 @@ func (gui *Gui) showWallet(context *qml.Context) (*qml.Window, error) { win := gui.createWindow(component) go func() { - gui.setInitialBlockChain() + go gui.setInitialBlockChain() gui.loadAddressBook() - gui.readPreviousTransactions() gui.setPeerInfo() + gui.readPreviousTransactions() }() go gui.update() diff --git a/ethereal/html_container.go b/ethereal/html_container.go index b00d3f78e07c..40a9f55842af 100644 --- a/ethereal/html_container.go +++ b/ethereal/html_container.go @@ -2,17 +2,18 @@ package main import ( "errors" + "io/ioutil" + "net/url" + "os" + "path" + "path/filepath" + "github.com/ethereum/eth-go/ethchain" "github.com/ethereum/eth-go/ethpub" "github.com/ethereum/eth-go/ethstate" "github.com/ethereum/eth-go/ethutil" "github.com/go-qml/qml" "github.com/howeyc/fsnotify" - "io/ioutil" - "net/url" - "os" - "path" - "path/filepath" ) type HtmlApplication struct { @@ -41,7 +42,7 @@ func (app *HtmlApplication) Create() error { return errors.New("Ethereum package not yet supported") // TODO - ethutil.OpenPackage(app.path) + //ethutil.OpenPackage(app.path) } win := component.CreateWindow(nil) diff --git a/ethereal/qml_container.go b/ethereal/qml_container.go index 1b420ee21978..53ff13c2f354 100644 --- a/ethereal/qml_container.go +++ b/ethereal/qml_container.go @@ -25,7 +25,7 @@ func (app *QmlApplication) Create() error { path := string(app.path) // For some reason for windows we get /c:/path/to/something, windows doesn't like the first slash but is fine with the others so we are removing it - if string(app.path[0]) == "/" && runtime.GOOS == "windows" { + if app.path[0] == '/' && runtime.GOOS == "windows" { path = app.path[1:] } From 719b7784f38a8ee6158d4d5a9230a98041f140b1 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 30 Jul 2014 00:30:57 +0200 Subject: [PATCH 07/16] Renamed to balance --- ethereal/debugger.go | 24 ++++++------------------ ethereal/gui.go | 17 +++++++++-------- 2 files changed, 15 insertions(+), 26 deletions(-) diff --git a/ethereal/debugger.go b/ethereal/debugger.go index 096387405703..1cf5e0b6642e 100644 --- a/ethereal/debugger.go +++ b/ethereal/debugger.go @@ -2,15 +2,16 @@ package main import ( "fmt" + "math/big" + "strconv" + "strings" + "github.com/ethereum/eth-go/ethchain" "github.com/ethereum/eth-go/ethstate" "github.com/ethereum/eth-go/ethutil" "github.com/ethereum/eth-go/ethvm" "github.com/ethereum/go-ethereum/utils" "github.com/go-qml/qml" - "math/big" - "strconv" - "strings" ) type DebuggerWindow struct { @@ -134,26 +135,13 @@ func (self *DebuggerWindow) Debug(valueStr, gasStr, gasPriceStr, scriptStr, data state := self.lib.eth.StateManager().TransState() account := self.lib.eth.StateManager().TransState().GetAccount(keyPair.Address()) contract := ethstate.NewStateObject([]byte{0}) - contract.Amount = value + contract.Balance = value self.SetAsm(script) - callerClosure := ethvm.NewClosure(account, contract, script, gas, gasPrice) - block := self.lib.eth.BlockChain().CurrentBlock - /* - vm := ethchain.NewVm(state, self.lib.eth.StateManager(), ethchain.RuntimeVars{ - Block: block, - Origin: account.Address(), - BlockNumber: block.Number, - PrevHash: block.PrevHash, - Coinbase: block.Coinbase, - Time: block.Time, - Diff: block.Difficulty, - Value: ethutil.Big(valueStr), - }) - */ + callerClosure := ethvm.NewClosure(account, contract, script, gas, gasPrice) env := utils.NewEnv(state, block, account.Address(), value) vm := ethvm.New(env) vm.Verbose = true diff --git a/ethereal/gui.go b/ethereal/gui.go index 573f68959fdd..31d4248b2aef 100644 --- a/ethereal/gui.go +++ b/ethereal/gui.go @@ -3,6 +3,11 @@ package main import ( "bytes" "fmt" + "math/big" + "strconv" + "strings" + "time" + "github.com/ethereum/eth-go" "github.com/ethereum/eth-go/ethchain" "github.com/ethereum/eth-go/ethdb" @@ -13,10 +18,6 @@ import ( "github.com/ethereum/eth-go/ethwire" "github.com/ethereum/go-ethereum/utils" "github.com/go-qml/qml" - "math/big" - "strconv" - "strings" - "time" ) var logger = ethlog.NewLogger("GUI") @@ -313,7 +314,7 @@ func (gui *Gui) update() { state := gui.eth.StateManager().TransState() unconfirmedFunds := new(big.Int) - gui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(state.GetAccount(gui.address()).Amount))) + gui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(state.GetAccount(gui.address()).Balance))) gui.getObjectByName("syncProgressIndicator").Set("visible", !gui.eth.IsUpToDate()) lastBlockLabel := gui.getObjectByName("lastBlockLabel") @@ -324,7 +325,7 @@ func (gui *Gui) update() { block := b.Resource.(*ethchain.Block) gui.processBlock(block, false) if bytes.Compare(block.Coinbase, gui.address()) == 0 { - gui.setWalletValue(gui.eth.StateManager().CurrentState().GetAccount(gui.address()).Amount, nil) + gui.setWalletValue(gui.eth.StateManager().CurrentState().GetAccount(gui.address()).Balance, nil) } case txMsg := <-txChan: @@ -345,7 +346,7 @@ func (gui *Gui) update() { unconfirmedFunds.Add(unconfirmedFunds, tx.Value) } - gui.setWalletValue(object.Amount, unconfirmedFunds) + gui.setWalletValue(object.Balance, unconfirmedFunds) } else { object := state.GetAccount(gui.address()) if bytes.Compare(tx.Sender(), gui.address()) == 0 { @@ -354,7 +355,7 @@ func (gui *Gui) update() { object.AddAmount(tx.Value) } - gui.setWalletValue(object.Amount, nil) + gui.setWalletValue(object.Balance, nil) state.UpdateStateObject(object) } From 23f83f53ccd71e5aefa9faf93e3527a589d1e487 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 30 Jul 2014 01:05:40 +0200 Subject: [PATCH 08/16] Upped version number --- ethereal/main.go | 7 ++++--- ethereum/main.go | 5 +++-- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/ethereal/main.go b/ethereal/main.go index 0f99be88659a..04a04536d29d 100644 --- a/ethereal/main.go +++ b/ethereal/main.go @@ -1,16 +1,17 @@ package main import ( + "os" + "runtime" + "github.com/ethereum/eth-go/ethlog" "github.com/ethereum/go-ethereum/utils" "github.com/go-qml/qml" - "os" - "runtime" ) const ( ClientIdentifier = "Ethereal" - Version = "0.6.0" + Version = "0.6.1" ) func main() { diff --git a/ethereum/main.go b/ethereum/main.go index 217991074891..9ece8133dacd 100644 --- a/ethereum/main.go +++ b/ethereum/main.go @@ -1,15 +1,16 @@ package main import ( + "runtime" + "github.com/ethereum/eth-go/ethlog" "github.com/ethereum/eth-go/ethutil" "github.com/ethereum/go-ethereum/utils" - "runtime" ) const ( ClientIdentifier = "Ethereum(G)" - Version = "0.6.0" + Version = "0.6.1" ) var logger = ethlog.NewLogger("CLI") From 5501679642321f3ad17b6dd7f25e3c090c1405df Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 30 Jul 2014 15:33:42 +0200 Subject: [PATCH 09/16] Updated README to include Cpt. Obv. --- README.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/README.md b/README.md index 790ee541e1c1..e22bfc4ec39e 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,12 @@ Ethereum [![Build Status](https://travis-ci.org/ethereum/go-ethereum.png?branch=master)](https://travis-ci.org/ethereum/go-ethereum) +Master [![Build +Status](http://cpt-obvious.ethercasts.com:8010/buildstatusimage?builder=go-ethereum-master-docker)](http://cpt-obvious.ethercasts.com:8010/builders/go-ethereum-master-docker/builds/-1) + +Develop [![Build +Status](http://cpt-obvious.ethercasts.com:8010/buildstatusimage?builder=go-ethereum-develop-docker)](http://cpt-obvious.ethercasts.com:8010/builders/go-ethereum-develop-docker/builds/-1) + Ethereum Go Client © 2014 Jeffrey Wilcke. Current state: Proof of Concept 0.6.0. From 834803f1e8ce45040045359185c8b8d75f63de2c Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 30 Jul 2014 15:34:36 +0200 Subject: [PATCH 10/16] Update --- README.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/README.md b/README.md index e22bfc4ec39e..186c979bc934 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,8 @@ Ethereum ======== -[![Build Status](https://travis-ci.org/ethereum/go-ethereum.png?branch=master)](https://travis-ci.org/ethereum/go-ethereum) - Master [![Build -Status](http://cpt-obvious.ethercasts.com:8010/buildstatusimage?builder=go-ethereum-master-docker)](http://cpt-obvious.ethercasts.com:8010/builders/go-ethereum-master-docker/builds/-1) - -Develop [![Build +Status](http://cpt-obvious.ethercasts.com:8010/buildstatusimage?builder=go-ethereum-master-docker)](http://cpt-obvious.ethercasts.com:8010/builders/go-ethereum-master-docker/builds/-1) Develop [![Build Status](http://cpt-obvious.ethercasts.com:8010/buildstatusimage?builder=go-ethereum-develop-docker)](http://cpt-obvious.ethercasts.com:8010/builders/go-ethereum-develop-docker/builds/-1) Ethereum Go Client © 2014 Jeffrey Wilcke. From 852d1ee395feabaa0e72265106374a0df197db9a Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 6 Aug 2014 09:53:12 +0200 Subject: [PATCH 11/16] State dumps --- ethereum/flags.go | 10 ++++++- ethereum/main.go | 31 +++++++++++++++++++++- ethereum/repl/javascript_runtime.go | 41 ++++++++++++++++++++++++++--- 3 files changed, 76 insertions(+), 6 deletions(-) diff --git a/ethereum/flags.go b/ethereum/flags.go index 4f59ddf060d8..5ed208411b17 100644 --- a/ethereum/flags.go +++ b/ethereum/flags.go @@ -3,10 +3,11 @@ package main import ( "flag" "fmt" - "github.com/ethereum/eth-go/ethlog" "os" "os/user" "path" + + "github.com/ethereum/eth-go/ethlog" ) var Identifier string @@ -31,6 +32,9 @@ var LogFile string var ConfigFile string var DebugFile string var LogLevel int +var Dump bool +var DumpHash string +var DumpNumber int // flags specific to cli client var StartMining bool @@ -71,6 +75,10 @@ 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(&Dump, "dump", false, "output the ethereum state in JSON format. Sub args [number, hash]") + flag.StringVar(&DumpHash, "hash", "", "specify arg in hex") + flag.IntVar(&DumpNumber, "number", -1, "specify arg in number") + flag.BoolVar(&StartMining, "mine", false, "start dagger mining") flag.BoolVar(&StartJsConsole, "js", false, "launches javascript console") diff --git a/ethereum/main.go b/ethereum/main.go index 9ece8133dacd..17838997c4b7 100644 --- a/ethereum/main.go +++ b/ethereum/main.go @@ -1,8 +1,11 @@ package main import ( + "fmt" + "os" "runtime" + "github.com/ethereum/eth-go/ethchain" "github.com/ethereum/eth-go/ethlog" "github.com/ethereum/eth-go/ethutil" "github.com/ethereum/go-ethereum/utils" @@ -24,7 +27,7 @@ func main() { Init() // parsing command line // If the difftool option is selected ignore all other log output - if DiffTool { + if DiffTool || Dump { LogLevel = 0 } @@ -47,6 +50,32 @@ func main() { ethereum := utils.NewEthereum(db, clientIdentity, keyManager, UseUPnP, OutboundPort, MaxPeer) + if Dump { + var block *ethchain.Block + + if len(DumpHash) == 0 && DumpNumber == -1 { + block = ethereum.BlockChain().CurrentBlock + } else if len(DumpHash) > 0 { + block = ethereum.BlockChain().GetBlock(ethutil.Hex2Bytes(DumpHash)) + } else { + block = ethereum.BlockChain().GetBlockByNumber(uint64(DumpNumber)) + } + + if block == nil { + fmt.Fprintln(os.Stderr, "block not found") + + // We want to output valid JSON + fmt.Println("{}") + + os.Exit(1) + } + + // Leave the Println. This needs clean output for piping + fmt.Println(block.State().Dump()) + + os.Exit(0) + } + if ShowGenesis { utils.ShowGenesis(ethereum) } diff --git a/ethereum/repl/javascript_runtime.go b/ethereum/repl/javascript_runtime.go index f5aea2dd920a..29b5f442f608 100644 --- a/ethereum/repl/javascript_runtime.go +++ b/ethereum/repl/javascript_runtime.go @@ -2,6 +2,11 @@ package ethrepl import ( "fmt" + "io/ioutil" + "os" + "path" + "path/filepath" + "github.com/ethereum/eth-go" "github.com/ethereum/eth-go/ethchain" "github.com/ethereum/eth-go/ethlog" @@ -11,10 +16,6 @@ import ( "github.com/ethereum/eth-go/ethutil" "github.com/ethereum/go-ethereum/utils" "github.com/obscuren/otto" - "io/ioutil" - "os" - "path" - "path/filepath" ) var jsrelogger = ethlog.NewLogger("JSRE") @@ -147,12 +148,44 @@ func (self *JSRE) initStdFuncs() { eth.Set("stopMining", self.stopMining) eth.Set("startMining", self.startMining) eth.Set("execBlock", self.execBlock) + eth.Set("dump", self.dump) } /* * The following methods are natively implemented javascript functions */ +func (self *JSRE) dump(call otto.FunctionCall) otto.Value { + var state *ethstate.State + + if len(call.ArgumentList) > 0 { + var block *ethchain.Block + if call.Argument(0).IsNumber() { + num, _ := call.Argument(0).ToInteger() + block = self.ethereum.BlockChain().GetBlockByNumber(uint64(num)) + } else if call.Argument(0).IsString() { + hash, _ := call.Argument(0).ToString() + block = self.ethereum.BlockChain().GetBlock(ethutil.Hex2Bytes(hash)) + } else { + fmt.Println("invalid argument for dump. Either hex string or number") + } + + if block == nil { + fmt.Println("block not found") + + return otto.UndefinedValue() + } + + state = block.State() + } else { + state = self.ethereum.StateManager().CurrentState() + } + + fmt.Println(state.Dump()) + + return otto.UndefinedValue() +} + func (self *JSRE) stopMining(call otto.FunctionCall) otto.Value { v, _ := self.vm.ToValue(utils.StopMining(self.ethereum)) return v From c7afb5fb72579fb61139a6365c380a4d9370a7b9 Mon Sep 17 00:00:00 2001 From: obscuren Date: Wed, 6 Aug 2014 10:05:34 +0200 Subject: [PATCH 12/16] output dump string, not undefined --- ethereum/repl/javascript_runtime.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ethereum/repl/javascript_runtime.go b/ethereum/repl/javascript_runtime.go index 29b5f442f608..026e6f374c1d 100644 --- a/ethereum/repl/javascript_runtime.go +++ b/ethereum/repl/javascript_runtime.go @@ -181,9 +181,9 @@ func (self *JSRE) dump(call otto.FunctionCall) otto.Value { state = self.ethereum.StateManager().CurrentState() } - fmt.Println(state.Dump()) + v, _ := self.vm.ToValue(state.Dump()) - return otto.UndefinedValue() + return v } func (self *JSRE) stopMining(call otto.FunctionCall) otto.Value { From bbe896875e8b51143ebea759dfd9f25a4bcc2b2f Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 7 Aug 2014 00:27:58 +0200 Subject: [PATCH 13/16] Typo. Fixes #107 --- ethereal/assets/qml/wallet.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ethereal/assets/qml/wallet.qml b/ethereal/assets/qml/wallet.qml index 50ff73060ca4..84022a230a54 100644 --- a/ethereal/assets/qml/wallet.qml +++ b/ethereal/assets/qml/wallet.qml @@ -992,7 +992,7 @@ ApplicationWindow { var gasPrice = txGasPrice.text + denomModel.get(gasDenom.currentIndex).zeros; var res = eth.create(txFuelRecipient.text, value, txGas.text, gasPrice, codeView.text) if(res[1]) { - txResult.text = "Your contract could not be send over the network:\n" + txResult.text = "Your contract could not be sent over the network:\n" txResult.text += res[1].error() txResult.text += "" mainContractColumn.state = "ERROR" From a915ba17edb0e8d2369d79036c0dc9585c0201ec Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 7 Aug 2014 15:12:25 +0200 Subject: [PATCH 14/16] Support the ".eth" TLD through the DnsContract --- ethereal/assets/qml/webapp.qml | 149 ++++++++++++++++++++------------- 1 file changed, 92 insertions(+), 57 deletions(-) diff --git a/ethereal/assets/qml/webapp.qml b/ethereal/assets/qml/webapp.qml index 5e4c035d8da9..15177e3fd07c 100644 --- a/ethereal/assets/qml/webapp.qml +++ b/ethereal/assets/qml/webapp.qml @@ -21,19 +21,54 @@ ApplicationWindow { id: root anchors.fill: parent state: "inspectorShown" + TextField { + anchors { + top: parent.top + left: parent.left + right: parent.right + } + id: uriNav + //text: webview.url + + Keys.onReturnPressed: { + var reg = /(^https?\:\/\/(?:www\.)?)([a-zA-Z0-9_\-]*\.eth)(.*)/ + + var uri = this.text; + if(reg.test(uri)) { + this.text.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 += ip.join("."); + } else { + uri += domain; + } + + uri += path; + }); + } + + console.log("connecting to ...", uri) + + webview.url = uri; + } + } WebView { objectName: "webView" id: webview - anchors.fill: parent - /* - anchors { - left: parent.left - right: parent.right - bottom: sizeGrip.top - top: parent.top - } - */ + anchors { + left: parent.left + right: parent.right + bottom: parent.bottom + top: uriNav.bottom + } onTitleChanged: { window.title = title } experimental.preferences.javascriptEnabled: true experimental.preferences.navigatorQtObjectEnabled: true @@ -46,50 +81,50 @@ ApplicationWindow { try { switch(data.call) { - case "getCoinBase": - postData(data._seed, eth.getCoinBase()) + case "getCoinBase": + postData(data._seed, eth.getCoinBase()) - break - case "getIsListening": - postData(data._seed, eth.getIsListening()) + break + case "getIsListening": + postData(data._seed, eth.getIsListening()) - break - case "getIsMining": - postData(data._seed, eth.getIsMining()) + break + case "getIsMining": + postData(data._seed, eth.getIsMining()) - break - case "getPeerCount": - postData(data._seed, eth.getPeerCount()) + break + case "getPeerCount": + postData(data._seed, eth.getPeerCount()) - break + break - case "getTxCountAt": - require(1) - postData(data._seed, eth.getTxCountAt(data.args[0])) + case "getTxCountAt": + require(1) + postData(data._seed, eth.getTxCountAt(data.args[0])) - break - case "getBlockByNumber": + break + case "getBlockByNumber": var block = eth.getBlock(data.args[0]) postData(data._seed, block) break - case "getBlockByHash": + case "getBlockByHash": var block = eth.getBlock(data.args[0]) postData(data._seed, block) break - case "transact": + case "transact": require(5) var tx = eth.transact(data.args[0], data.args[1], data.args[2],data.args[3],data.args[4],data.args[5]) postData(data._seed, tx) break - case "create": + case "create": postData(data._seed, null) break - case "getStorage": + case "getStorage": require(2); var stateObject = eth.getStateObject(data.args[0]) @@ -97,52 +132,52 @@ ApplicationWindow { postData(data._seed, storage) break - case "getStateKeyVals": - require(1); - var stateObject = eth.getStateObject(data.args[0]).stateKeyVal(true) - postData(data._seed,stateObject) + case "getStateKeyVals": + require(1); + var stateObject = eth.getStateObject(data.args[0]).stateKeyVal(true) + postData(data._seed,stateObject) break - case "getTransactionsFor": - require(1); - var txs = eth.getTransactionsFor(data.args[0], true) - postData(data._seed, txs) + case "getTransactionsFor": + require(1); + var txs = eth.getTransactionsFor(data.args[0], true) + postData(data._seed, txs) - break - case "getBalance": + break + case "getBalance": require(1); postData(data._seed, eth.getStateObject(data.args[0]).value()); break - case "getKey": + case "getKey": var key = eth.getKey().privateKey; postData(data._seed, key) break - case "watch": + case "watch": require(1) eth.watch(data.args[0], data.args[1]); break - case "disconnect": + case "disconnect": require(1) postData(data._seed, null) break; - case "set": - console.log("'Set' has been depcrecated") - /* - for(var key in data.args) { - if(webview.hasOwnProperty(key)) { - window[key] = data.args[key]; - } - } - */ + case "set": + console.log("'Set' has been depcrecated") + /* + for(var key in data.args) { + if(webview.hasOwnProperty(key)) { + window[key] = data.args[key]; + } + } + */ break; - case "getSecretToAddress": + case "getSecretToAddress": require(1) postData(data._seed, eth.secretToAddress(data.args[0])) break; - case "debug": + case "debug": console.log(data.args[0]); break; } @@ -191,12 +226,12 @@ ApplicationWindow { inspector.visible = false }else{ inspector.visible = true - inspector.url = webview.experimental.remoteInspectorUrl + inspector.url = webview.experimental.remoteInspectorUrl } } onDoubleClicked: { - console.log('refreshing') - webView.reload() + console.log('refreshing') + webView.reload() } anchors.fill: parent } From 4dc5855dfe08bd427e931d03f2c7ae9105688f67 Mon Sep 17 00:00:00 2001 From: obscuren Date: Thu, 7 Aug 2014 16:35:47 +0200 Subject: [PATCH 15/16] Regular browser option added --- ethereal/assets/ext/home.html | 21 +++++++++++++++++++++ ethereal/assets/qml/wallet.qml | 5 +++++ ethereal/ui_lib.go | 7 ++++++- 3 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 ethereal/assets/ext/home.html diff --git a/ethereal/assets/ext/home.html b/ethereal/assets/ext/home.html new file mode 100644 index 000000000000..54af76991124 --- /dev/null +++ b/ethereal/assets/ext/home.html @@ -0,0 +1,21 @@ + + + +Ethereum + + + + + +

Ethereum

+ + + + diff --git a/ethereal/assets/qml/wallet.qml b/ethereal/assets/qml/wallet.qml index 84022a230a54..92641fb3ef15 100644 --- a/ethereal/assets/qml/wallet.qml +++ b/ethereal/assets/qml/wallet.qml @@ -27,6 +27,11 @@ ApplicationWindow { onTriggered: openAppDialog.open() } + MenuItem { + text: "Browser" + onTriggered: ui.openBrowser() + } + MenuSeparator {} MenuItem { diff --git a/ethereal/ui_lib.go b/ethereal/ui_lib.go index 6a62fa1df298..42c5c9ad2dd0 100644 --- a/ethereal/ui_lib.go +++ b/ethereal/ui_lib.go @@ -1,10 +1,11 @@ package main import ( + "path" + "github.com/ethereum/eth-go" "github.com/ethereum/eth-go/ethutil" "github.com/go-qml/qml" - "path" ) type memAddr struct { @@ -42,6 +43,10 @@ func (ui *UiLib) OpenHtml(path string) { go app.run() } +func (ui *UiLib) OpenBrowser() { + ui.OpenHtml("file://" + ui.AssetPath("ext/home.html")) +} + func (ui *UiLib) Muted(content string) { component, err := ui.engine.LoadFile(ui.AssetPath("qml/muted.qml")) if err != nil { From 51a2087081ec0c8a9d0d739c344929c8494e13b6 Mon Sep 17 00:00:00 2001 From: obscuren Date: Sun, 10 Aug 2014 14:57:42 +0100 Subject: [PATCH 16/16] Minor issues --- ethereal/assets/ext/home.html | 2 +- ethereal/assets/ext/messaging.js | 117 +++++++++++++++++++++++++++++++ ethereal/assets/qml/wallet.qml | 111 ++++++++++++++++++++++++----- ethereal/gui.go | 72 +++++++++++++++---- 4 files changed, 269 insertions(+), 33 deletions(-) create mode 100644 ethereal/assets/ext/messaging.js diff --git a/ethereal/assets/ext/home.html b/ethereal/assets/ext/home.html index 54af76991124..86a659d65f34 100644 --- a/ethereal/assets/ext/home.html +++ b/ethereal/assets/ext/home.html @@ -14,7 +14,7 @@ -

Ethereum

+

... Ethereum ...

diff --git a/ethereal/assets/ext/messaging.js b/ethereal/assets/ext/messaging.js new file mode 100644 index 000000000000..e7bc63020220 --- /dev/null +++ b/ethereal/assets/ext/messaging.js @@ -0,0 +1,117 @@ +function handleMessage(message) { + console.log("[onMessageReceived]: ", message.data) + // TODO move to messaging.js + var data = JSON.parse(message.data) + + try { + switch(data.call) { + case "getCoinBase": + postData(data._seed, eth.getCoinBase()) + + break + case "getIsListening": + postData(data._seed, eth.getIsListening()) + + break + case "getIsMining": + postData(data._seed, eth.getIsMining()) + + break + case "getPeerCount": + postData(data._seed, eth.getPeerCount()) + + break + + case "getTxCountAt": + require(1) + postData(data._seed, eth.getTxCountAt(data.args[0])) + + break + case "getBlockByNumber": + var block = eth.getBlock(data.args[0]) + postData(data._seed, block) + + break + case "getBlockByHash": + var block = eth.getBlock(data.args[0]) + postData(data._seed, block) + + break + case "transact": + require(5) + + var tx = eth.transact(data.args[0], data.args[1], data.args[2],data.args[3],data.args[4],data.args[5]) + postData(data._seed, tx) + + break + case "create": + postData(data._seed, null) + + break + case "getStorage": + require(2); + + var stateObject = eth.getStateObject(data.args[0]) + var storage = stateObject.getStorage(data.args[1]) + postData(data._seed, storage) + + break + case "getStateKeyVals": + require(1); + var stateObject = eth.getStateObject(data.args[0]).stateKeyVal(true) + postData(data._seed,stateObject) + + break + case "getTransactionsFor": + require(1); + var txs = eth.getTransactionsFor(data.args[0], true) + postData(data._seed, txs) + + break + case "getBalance": + require(1); + + postData(data._seed, eth.getStateObject(data.args[0]).value()); + + break + case "getKey": + var key = eth.getKey().privateKey; + + postData(data._seed, key) + break + case "watch": + require(1) + eth.watch(data.args[0], data.args[1]); + break + case "disconnect": + require(1) + postData(data._seed, null) + break; + case "set": + console.log("'Set' has been depcrecated") + /* + for(var key in data.args) { + if(webview.hasOwnProperty(key)) { + window[key] = data.args[key]; + } + } + */ + break; + case "getSecretToAddress": + require(1) + postData(data._seed, eth.secretToAddress(data.args[0])) + break; + case "debug": + console.log(data.args[0]); + break; + } + } catch(e) { + console.log(data.call + ": " + e) + + postData(data._seed, null); + } +} + +function postData(seed, data) { + webview.experimental.postMessage(JSON.stringify({data: data, _seed: seed})) +} diff --git a/ethereal/assets/qml/wallet.qml b/ethereal/assets/qml/wallet.qml index 92641fb3ef15..e3ef148b0b70 100644 --- a/ethereal/assets/qml/wallet.qml +++ b/ethereal/assets/qml/wallet.qml @@ -56,6 +56,13 @@ ApplicationWindow { shortcut: "Ctrl+d" onTriggered: ui.startDebugger() } + + MenuItem { + text: "Import Tx" + onTriggered: { + txImportDialog.visible = true + } + } } Menu { @@ -98,6 +105,7 @@ ApplicationWindow { historyView.visible = false newTxView.visible = false infoView.visible = false + pendingTxView.visible = false view.visible = true //root.title = "Ethereal - " = view.title } @@ -161,6 +169,17 @@ ApplicationWindow { } } } + + Image { + source: "../tx.png" + anchors.horizontalCenter: parent.horizontalCenter + MouseArea { + anchors.fill: parent + onClicked: { + setView(pendingTxView) + } + } + } } } @@ -365,6 +384,28 @@ ApplicationWindow { } } + Rectangle { + anchors.fill: parent + visible: false + id: pendingTxView + property var title: "Pending Transactions" + + property var pendingTxModel: ListModel { + id: pendingTxModel + } + + TableView { + id: pendingTxTableView + anchors.fill: parent + TableViewColumn{ role: "value" ; title: "Value" ; width: 100 } + TableViewColumn{ role: "from" ; title: "sender" ; width: 230 } + TableViewColumn{ role: "to" ; title: "Reciever" ; width: 230 } + TableViewColumn{ role: "contract" ; title: "Contract" ; width: 100 } + + model: pendingTxModel + } + } + /* signal addPlugin(string name) Component { @@ -500,6 +541,36 @@ ApplicationWindow { } } + Window { + id: txImportDialog + minimumWidth: 270 + maximumWidth: 270 + maximumHeight: 50 + minimumHeight: 50 + TextField { + id: txImportField + width: 170 + anchors.verticalCenter: parent.verticalCenter + anchors.left: parent.left + anchors.leftMargin: 10 + onAccepted: { + } + } + Button { + anchors.left: txImportField.right + anchors.verticalCenter: parent.verticalCenter + anchors.leftMargin: 5 + text: "Import" + onClicked: { + eth.importTx(txImportField.text) + txImportField.visible = false + } + } + Component.onCompleted: { + addrField.focus = true + } + } + Window { id: popup visible: false @@ -719,7 +790,7 @@ ApplicationWindow { walletValueLabel.text = value } - function addTx(tx, inout) { + function addTx(type, tx, inout) { var isContract if (tx.contract == true){ isContract = "Yes" @@ -727,13 +798,19 @@ ApplicationWindow { isContract = "No" } - var address; - if(inout == "recv") { - address = tx.sender; - } else { - address = tx.address; + + if(type == "post") { + var address; + if(inout == "recv") { + address = tx.sender; + } else { + address = tx.address; + } + + txModel.insert(0, {inout: inout, hash: tx.hash, address: address, value: tx.value, contract: isContract}) + } else if(type == "pre") { + pendingTxModel.insert(0, {hash: tx.hash, to: tx.address, from: tx.sender, value: tx.value, contract: isContract}) } - txModel.insert(0, {inout: inout, hash: tx.hash, address: address, value: tx.value, contract: isContract}) } function addBlock(block, initial) { @@ -749,7 +826,7 @@ ApplicationWindow { if(initial){ blockModel.append({number: block.number, name: block.name, gasLimit: block.gasLimit, gasUsed: block.gasUsed, coinbase: block.coinbase, hash: block.hash, txs: txs, txAmount: amount, time: block.time, prettyTime: convertToPretty(block.time)}) - }else{ + } else { blockModel.insert(0, {number: block.number, name: block.name, gasLimit: block.gasLimit, gasUsed: block.gasUsed, coinbase: block.coinbase, hash: block.hash, txs: txs, txAmount: amount, time: block.time, prettyTime: convertToPretty(block.time)}) } } @@ -805,7 +882,7 @@ ApplicationWindow { // ****************************************** Window { id: peerWindow - //flags: Qt.CustomizeWindowHint | Qt.Tool | Qt.WindowCloseButtonHint + //flags: Qt.CustomizeWindowHint | Qt.Tool | Qt.WindowCloseButtonHint height: 200 width: 700 Rectangle { @@ -932,10 +1009,10 @@ ApplicationWindow { placeholderText: "Gas" text: "500" /* - onTextChanged: { - contractFormReady() - } - */ + onTextChanged: { + contractFormReady() + } + */ } Label { id: atLabel @@ -949,10 +1026,10 @@ ApplicationWindow { text: "10" validator: RegExpValidator { regExp: /\d*/ } /* - onTextChanged: { - contractFormReady() - } - */ + onTextChanged: { + contractFormReady() + } + */ } ComboBox { diff --git a/ethereal/gui.go b/ethereal/gui.go index 61f7b1099a7b..36e147ba97f7 100644 --- a/ethereal/gui.go +++ b/ethereal/gui.go @@ -13,6 +13,7 @@ import ( "github.com/ethereum/eth-go/ethdb" "github.com/ethereum/eth-go/ethlog" "github.com/ethereum/eth-go/ethminer" + "github.com/ethereum/eth-go/ethpipe" "github.com/ethereum/eth-go/ethpub" "github.com/ethereum/eth-go/ethreact" "github.com/ethereum/eth-go/ethutil" @@ -236,20 +237,54 @@ func (gui *Gui) loadAddressBook() { } } -func (gui *Gui) readPreviousTransactions() { - it := gui.txDb.Db().NewIterator(nil, nil) +func (gui *Gui) insertTransaction(window string, tx *ethchain.Transaction) { + nameReg := ethpipe.New(gui.eth).World().Config().Get("NameReg") addr := gui.address() - for it.Next() { - tx := ethchain.NewTransactionFromBytes(it.Value()) - var inout string - if bytes.Compare(tx.Sender(), addr) == 0 { - inout = "send" + var inout string + if bytes.Compare(tx.Sender(), addr) == 0 { + inout = "send" + } else { + inout = "recv" + } + + var ( + ptx = ethpub.NewPTx(tx) + send = nameReg.Storage(tx.Sender()) + rec = nameReg.Storage(tx.Recipient) + s, r string + ) + + if tx.CreatesContract() { + rec = nameReg.Storage(tx.CreationAddress()) + } + + if send.Len() != 0 { + s = strings.Trim(send.Str(), "\x00") + } else { + s = ethutil.Bytes2Hex(tx.Sender()) + } + if rec.Len() != 0 { + r = strings.Trim(rec.Str(), "\x00") + } else { + if tx.CreatesContract() { + r = ethutil.Bytes2Hex(tx.CreationAddress()) } else { - inout = "recv" + r = ethutil.Bytes2Hex(tx.Recipient) } + } + ptx.Sender = s + ptx.Address = r + + gui.win.Root().Call("addTx", window, ptx, inout) +} - gui.win.Root().Call("addTx", ethpub.NewPTx(tx), inout) +func (gui *Gui) readPreviousTransactions() { + it := gui.txDb.Db().NewIterator(nil, nil) + for it.Next() { + tx := ethchain.NewTransactionFromBytes(it.Value()) + + gui.insertTransaction("post", tx) } it.Release() @@ -322,24 +357,26 @@ func (gui *Gui) update() { object := state.GetAccount(gui.address()) if bytes.Compare(tx.Sender(), gui.address()) == 0 { - gui.win.Root().Call("addTx", ethpub.NewPTx(tx), "send") - gui.txDb.Put(tx.Hash(), tx.RlpEncode()) - unconfirmedFunds.Sub(unconfirmedFunds, tx.Value) } else if bytes.Compare(tx.Recipient, gui.address()) == 0 { - gui.win.Root().Call("addTx", ethpub.NewPTx(tx), "recv") - gui.txDb.Put(tx.Hash(), tx.RlpEncode()) - unconfirmedFunds.Add(unconfirmedFunds, tx.Value) } gui.setWalletValue(object.Balance, unconfirmedFunds) + + gui.insertTransaction("pre", tx) } else { object := state.GetAccount(gui.address()) if bytes.Compare(tx.Sender(), gui.address()) == 0 { object.SubAmount(tx.Value) + + gui.win.Root().Call("addTx", "post", ethpub.NewPTx(tx), "send") + gui.txDb.Put(tx.Hash(), tx.RlpEncode()) } else if bytes.Compare(tx.Recipient, gui.address()) == 0 { object.AddAmount(tx.Value) + + gui.win.Root().Call("addTx", "post", ethpub.NewPTx(tx), "recv") + gui.txDb.Put(tx.Hash(), tx.RlpEncode()) } gui.setWalletValue(object.Balance, nil) @@ -422,6 +459,11 @@ func (gui *Gui) Create(recipient, value, gas, gasPrice, data string) (*ethpub.PR return gui.pub.Transact(gui.privateKey(), recipient, value, gas, gasPrice, data) } +func (self *Gui) ImportTx(rlpTx string) { + tx := ethchain.NewTransactionFromBytes(ethutil.Hex2Bytes(rlpTx)) + self.eth.TxPool().QueueTransaction(tx) +} + func (gui *Gui) SetCustomIdentifier(customIdentifier string) { gui.clientIdentity.SetCustomIdentifier(customIdentifier) gui.config.Save("id", customIdentifier)