diff --git a/net.png b/net.png new file mode 100644 index 000000000..65a20ea00 Binary files /dev/null and b/net.png differ diff --git a/net.pxm b/net.pxm new file mode 100644 index 000000000..20d45d08c Binary files /dev/null and b/net.pxm differ diff --git a/new.png b/new.png new file mode 100644 index 000000000..e80096748 Binary files /dev/null and b/new.png differ diff --git a/tx.png b/tx.png new file mode 100644 index 000000000..62204c315 Binary files /dev/null and b/tx.png differ diff --git a/tx.pxm b/tx.pxm new file mode 100644 index 000000000..881420da9 Binary files /dev/null and b/tx.pxm differ diff --git a/ui/gui.go b/ui/gui.go index 6e30b5891..556e682a9 100644 --- a/ui/gui.go +++ b/ui/gui.go @@ -9,6 +9,7 @@ import ( "github.com/ethereum/eth-go/ethdb" "github.com/ethereum/eth-go/ethutil" "github.com/niemeyer/qml" + "math/big" "strings" ) @@ -62,9 +63,8 @@ func New(ethereum *eth.Ethereum) *Gui { panic(err) } - data, _ := ethutil.Config.Db.Get([]byte("KeyRing")) - keyRing := ethutil.NewValueFromBytes(data) - addr := keyRing.Get(1).Bytes() + key := ethutil.Config.Db.GetKeys()[0] + addr := key.Address() ethereum.BlockManager.WatchAddr(addr) @@ -127,7 +127,7 @@ func (ui *Gui) setInitialBlockChain() { } func (ui *Gui) readPreviousTransactions() { - it := ui.txDb.Db().NewIterator(nil) + it := ui.txDb.Db().NewIterator(nil, nil) for it.Next() { tx := ethchain.NewTransactionFromBytes(it.Value()) @@ -140,45 +140,50 @@ func (ui *Gui) ProcessBlock(block *ethchain.Block) { ui.win.Root().Call("addBlock", NewBlockFromBlock(block)) } -func (ui *Gui) ProcessTransaction(tx *ethchain.Transaction) { - ui.txDb.Put(tx.Hash(), tx.RlpEncode()) - - ui.win.Root().Call("addTx", NewTxFromTransaction(tx)) - - // TODO replace with general subscribe model -} - // Simple go routine function that updates the list of peers in the GUI func (ui *Gui) update() { - txChan := make(chan ethchain.TxMsg) + txChan := make(chan ethchain.TxMsg, 1) ui.eth.TxPool.Subscribe(txChan) account := ui.eth.BlockManager.GetAddrState(ui.addr).Account + unconfirmedFunds := new(big.Int) ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(account.Amount))) for { select { case txMsg := <-txChan: tx := txMsg.Tx - ui.txDb.Put(tx.Hash(), tx.RlpEncode()) - ui.win.Root().Call("addTx", NewTxFromTransaction(tx)) - // TODO FOR THE LOVE OF EVERYTHING GOOD IN THIS WORLD REFACTOR ME if txMsg.Type == ethchain.TxPre { if bytes.Compare(tx.Sender(), ui.addr) == 0 { - ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v (- %v)", ethutil.CurrencyToString(account.Amount), ethutil.CurrencyToString(tx.Value))) + ui.win.Root().Call("addTx", NewTxFromTransaction(tx)) + ui.txDb.Put(tx.Hash(), tx.RlpEncode()) + ui.eth.BlockManager.GetAddrState(ui.addr).Nonce += 1 - fmt.Println("Nonce", ui.eth.BlockManager.GetAddrState(ui.addr).Nonce) + unconfirmedFunds.Sub(unconfirmedFunds, tx.Value) } else if bytes.Compare(tx.Recipient, ui.addr) == 0 { - ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v (+ %v)", ethutil.CurrencyToString(account.Amount), ethutil.CurrencyToString(tx.Value))) + ui.win.Root().Call("addTx", NewTxFromTransaction(tx)) + ui.txDb.Put(tx.Hash(), tx.RlpEncode()) + + unconfirmedFunds.Add(unconfirmedFunds, tx.Value) } + + pos := "+" + if unconfirmedFunds.Cmp(big.NewInt(0)) >= 0 { + pos = "-" + } + val := ethutil.CurrencyToString(new(big.Int).Abs(ethutil.BigCopy(unconfirmedFunds))) + str := fmt.Sprintf("%v (%s %v)", ethutil.CurrencyToString(account.Amount), pos, val) + + ui.win.Root().Call("setWalletValue", str) } else { + amount := account.Amount if bytes.Compare(tx.Sender(), ui.addr) == 0 { - amount := account.Amount.Sub(account.Amount, tx.Value) - ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(amount))) + amount.Sub(account.Amount, tx.Value) } else if bytes.Compare(tx.Recipient, ui.addr) == 0 { - amount := account.Amount.Sub(account.Amount, tx.Value) - ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(amount))) + amount.Add(account.Amount, tx.Value) } + + ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(amount))) } } diff --git a/wallet.qml b/wallet.qml index 04c1ffaed..8c91039fc 100644 --- a/wallet.qml +++ b/wallet.qml @@ -15,35 +15,6 @@ ApplicationWindow { title: "Ethereal" - toolBar: ToolBar { - id: mainToolbar - - RowLayout { - width: parent.width - Button { - text: "Send" - onClicked: { - console.log(eth.createTx(txReceiver.text, txAmount.text, codeView.text)) - } - } - - TextField { - id: txAmount - width: 200 - placeholderText: "Amount" - } - - TextField { - id: txReceiver - width: 300 - placeholderText: "Receiver Address (or empty for contract)" - Layout.fillWidth: true - } - - } - } - - MenuBar { Menu { title: "File" @@ -86,35 +57,61 @@ ApplicationWindow { property var blockModel: ListModel { id: blockModel } - function setView(view) { - mainView.visible = false - transactionView.visible = false - view.visible = true - } + + function setView(view) { + networkView.visible = false + historyView.visible = false + newTxView.visible = false + view.visible = true + //root.title = "Ethereal - " = view.title + } SplitView { anchors.fill: parent - + resizing: false Rectangle { id: menu - width: 200 + Layout.minimumWidth: 80 + Layout.maximumWidth: 80 anchors.bottom: parent.bottom anchors.top: parent.top - color: "#D9DDE7" + //color: "#D9DDE7" + color: "#252525" - GridLayout { - columns: 1 - Button { - text: "Main" - onClicked: { - setView(mainView) + ColumnLayout { + y: 50 + anchors.left: parent.left + anchors.right: parent.right + height: 200 + Image { + source: "tx.png" + anchors.horizontalCenter: parent.horizontalCenter + MouseArea { + anchors.fill: parent + onClicked: { + setView(historyView) + } } } - Button { - text: "Transactions" - onClicked: { - setView(transactionView) + Image { + source: "new.png" + anchors.horizontalCenter: parent.horizontalCenter + MouseArea { + anchors.fill: parent + onClicked: { + setView(newTxView) + } + } + } + Image { + source: "net.png" + anchors.horizontalCenter: parent.horizontalCenter + MouseArea { + anchors.fill: parent + onClicked: { + setView(networkView) + } } } } @@ -126,8 +123,8 @@ ApplicationWindow { } Rectangle { - id: transactionView - visible: false + id: historyView + property var title: "Transactions" anchors.right: parent.right anchors.left: menu.right anchors.bottom: parent.bottom @@ -135,40 +132,73 @@ ApplicationWindow { TableView { id: txTableView anchors.fill: parent - TableViewColumn{ role: "hash" ; title: "#" ; width: 150 } TableViewColumn{ role: "value" ; title: "Value" ; width: 100 } - TableViewColumn{ role: "address" ; title: "Address" ; } + TableViewColumn{ role: "address" ; title: "Address" ; width: 430 } model: txModel } } Rectangle { - id: mainView + id: newTxView + property var title: "New transaction" + visible: false anchors.right: parent.right + anchors.left: menu.right anchors.bottom: parent.bottom anchors.top: parent.top - SplitView { - id: splitView - height: 200 - anchors.top: parent.top - anchors.right: parent.right - anchors.left: parent.left + color: "#00000000" + ColumnLayout { + width: 400 + anchors.left: parent.left + anchors.top: parent.top + anchors.leftMargin: 5 + anchors.topMargin: 5 + TextField { + id: txAmount + width: 200 + placeholderText: "Amount" + } + + TextField { + id: txReceiver + placeholderText: "Receiver Address (or empty for contract)" + Layout.fillWidth: true + } + + Label { + text: "Transaction data" + } TextArea { id: codeView + anchors.topMargin: 5 + Layout.fillWidth: true width: parent.width /2 } - TextArea { - readOnly: true + Button { + text: "Send" + onClicked: { + console.log(eth.createTx(txReceiver.text, txAmount.text, codeView.text)) + } } } + } + + + Rectangle { + id: networkView + property var title: "Network" + visible: false + anchors.right: parent.right + anchors.bottom: parent.bottom + anchors.top: parent.top TableView { id: blockTable width: parent.width - anchors.top: splitView.bottom + anchors.top: parent.top anchors.bottom: logView.top TableViewColumn{ role: "number" ; title: "#" ; width: 100 } TableViewColumn{ role: "hash" ; title: "Hash" ; width: 560 } @@ -210,8 +240,13 @@ ApplicationWindow { RowLayout { anchors.fill: parent Button { + property var enabled: true id: connectButton - onClicked: ui.connect() + onClicked: { + if(this.enabled) { + ui.connect(this) + } + } text: "Connect" } Button {