aboutsummaryrefslogtreecommitdiffstats
path: root/cmd/mist
diff options
context:
space:
mode:
authorAlexandre Van de Sande <alex.vandesande@ethdev.com>2015-02-16 21:43:30 +0800
committerAlexandre Van de Sande <alex.vandesande@ethdev.com>2015-02-16 21:43:30 +0800
commit3068e2688d88912ec33f3d80fd0fe26c4e897dcd (patch)
treeee32ccd17faf650f3e933e9a2d8b4ab52f0d7746 /cmd/mist
parent1878630b591b039fadb6f88e15340d04f4af3ed1 (diff)
parent68f6ddc5aaa7ff29d09c1519ccd38d9cf16c0f75 (diff)
downloaddexon-3068e2688d88912ec33f3d80fd0fe26c4e897dcd.tar.gz
dexon-3068e2688d88912ec33f3d80fd0fe26c4e897dcd.tar.zst
dexon-3068e2688d88912ec33f3d80fd0fe26c4e897dcd.zip
merge conflicts
Diffstat (limited to 'cmd/mist')
-rw-r--r--cmd/mist/assets/examples/coin.html26
-rw-r--r--cmd/mist/assets/examples/coin.js65
-rw-r--r--cmd/mist/assets/examples/info.html4
-rw-r--r--cmd/mist/assets/qml/main.qml98
-rw-r--r--cmd/mist/assets/qml/views/browser.qml69
-rw-r--r--cmd/mist/assets/qml/views/info.qml12
-rw-r--r--cmd/mist/assets/qml/views/miner.qml21
-rw-r--r--cmd/mist/assets/qml/views/transaction.qml4
-rw-r--r--cmd/mist/assets/qml/views/wallet.qml11
-rw-r--r--cmd/mist/bindings.go9
-rw-r--r--cmd/mist/ext_app.go26
-rw-r--r--cmd/mist/flags.go44
-rw-r--r--cmd/mist/gui.go67
-rw-r--r--cmd/mist/html_container.go14
-rw-r--r--cmd/mist/main.go31
-rw-r--r--cmd/mist/qml_container.go6
-rw-r--r--cmd/mist/ui_lib.go32
17 files changed, 295 insertions, 244 deletions
diff --git a/cmd/mist/assets/examples/coin.html b/cmd/mist/assets/examples/coin.html
index 71b359834..ca7a9c0dd 100644
--- a/cmd/mist/assets/examples/coin.html
+++ b/cmd/mist/assets/examples/coin.html
@@ -7,7 +7,7 @@
</head>
<body>
-<h1>JevCoin <code id="address"></code></h1>
+<h1>JevCoin <code id="contract_addr"></code></h1>
<div>
<strong>Balance</strong>
<span id="balance"></strong>
@@ -58,31 +58,33 @@
}],
"outputs": []
}, {
- "name":"changed",
+ "name":"received",
"type":"event",
"inputs": [
- {"name":"to","type":"address","indexed":true},
{"name":"from","type":"address","indexed":true},
+ {"name":"amount","type":"uint256","indexed":true},
],
}];
var address = localStorage.getItem("address");
// deploy if not exist
if (address == null) {
- var code = "0x60056013565b610132806100356000396000f35b620f4240600033600160a060020a0316600052602052604060002081905550560060e060020a6000350480637bb98a681461002b578063d0679d3414610039578063e3d670d71461004d57005b61003361012d565b60006000f35b610047600435602435610062565b60006000f35b61005860043561010b565b8060005260206000f35b80600033600160a060020a0316600052602052604060002054106100855761008a565b610107565b80600033600160a060020a0316600052602052604060002090815403908190555080600083600160a060020a0316600052602052604060002090815401908190555081600160a060020a031633600160a060020a03167f1863989b4bb7c5c3941722099764574df7a459f9f9c6b6cdca35ddc9731792b860006000a35b5050565b6000600082600160a060020a03166000526020526040600020549050919050565b5b60008156";
- address = web3.eth.transact({
- data: code,
- gasPrice: "1000000000000000",
- gas: "10000",
- });
+ var code = "0x60056013565b61012b806100346000396000f35b6103e8600033600160a060020a0316600052602052604060002081905550560060e060020a6000350480637bb98a681461002b578063d0679d3414610039578063e3d670d71461004d57005b610033610126565b60006000f35b610047600435602435610062565b60006000f35b610058600435610104565b8060005260206000f35b80600033600160a060020a0316600052602052604060002054101561008657610100565b80600033600160a060020a0316600052602052604060002090815403908190555080600083600160a060020a0316600052602052604060002090815401908190555033600160a060020a0316600052806020527ff11e547d796cc64acdf758e7cee90439494fd886a19159454aa61e473fdbafef60406000a15b5050565b6000600082600160a060020a03166000526020526040600020549050919050565b5b60008156";
+ address = web3.eth.transact({data: code});
localStorage.setItem("address", address);
}
- document.querySelector("#address").innerHTML = address.toUpperCase();
+ document.querySelector("#contract_addr").innerHTML = address.toUpperCase();
var contract = web3.eth.contract(address, desc);
- contract.changed({from: eth.accounts[0]}).changed(function() {
+ contract.received({from: eth.coinbase}).changed(function() {
refresh();
});
+
+ var ev = contract.SingleTransact({})
+ ev.watch(function(log) {
+ someElement.innerHTML += "tnaheousnthaoeu";
+ });
+
eth.watch('chain').changed(function() {
refresh();
});
@@ -102,7 +104,6 @@
function transact() {
var to = document.querySelector("#address").value;
-
if( to.length == 0 ) {
to = "0x4205b06c2cfa0e30359edcab94543266cb6fa1d3";
} else {
@@ -116,7 +117,6 @@
refresh();
</script>
-
</html>
<!--
diff --git a/cmd/mist/assets/examples/coin.js b/cmd/mist/assets/examples/coin.js
new file mode 100644
index 000000000..77daac846
--- /dev/null
+++ b/cmd/mist/assets/examples/coin.js
@@ -0,0 +1,65 @@
+var walletABI = [
+ {
+ "name":"confirm",
+ "type":"function",
+ "constant":false,
+ "inputs":[
+ {"name":"_h","type":"hash256"}
+ ],
+ "outputs":[]
+ },{
+ "name":"execute",
+ "constant":false,
+ "type":"function",
+ "inputs":[
+ {"name":"_to","type":"address"},
+ {"name":"_value","type":"uint256"},
+ {"name":"_data","type":"bytes"}
+ ],
+ "outputs":[
+ {"name":"_r","type":"hash256"}
+ ]
+ },{
+ "name":"kill",
+ "type":"function",
+ "constant":false,
+ "inputs":[
+ {"name":"_to","type":"address"}
+ ],
+ "outputs":[]
+ },{
+ "name":"changeOwner",
+ "type":"function",
+ "constant":false,
+ "inputs":[
+ {"name":"_from","type":"address"},
+ {"name":"_to","type":"address"}
+ ],
+ "outputs":[]
+ },{
+ "name":"CashIn",
+ "type":"event",
+ "inputs":[
+ {"indexed":false,"name":"value","type":"uint256"}
+ ]
+ },{
+ "name":"SingleTransact",
+ "type":"event",
+ "inputs":[
+ {"indexed":true,"name":"out","type":"string32"},
+ {"indexed":false,"name":"owner","type":"address"},
+ {"indexed":false,"name":"value","type":"uint256"},
+ {"indexed":false,"name":"to","type":"address"}
+ ]
+ },{
+ "name":"MultiTransact",
+ "type":"event",
+ "inputs":[
+ {"indexed":true,"name":"out","type":"string32"},
+ {"indexed":false,"name":"owner","type":"address"},
+ {"indexed":false,"name":"operation","type":"hash256"},
+ {"indexed":false,"name":"value","type":"uint256"},
+ {"indexed":false,"name":"to","type":"address"}
+ ]
+ }
+];
diff --git a/cmd/mist/assets/examples/info.html b/cmd/mist/assets/examples/info.html
index daad8c706..d8816b19f 100644
--- a/cmd/mist/assets/examples/info.html
+++ b/cmd/mist/assets/examples/info.html
@@ -1,8 +1,8 @@
<!doctype>
<html>
-
<head>
+<meta name="badge" content="10">
<script type="text/javascript" src="../ext/bignumber.min.js"></script>
<script type="text/javascript" src="../ext/ethereum.js/dist/ethereum.js"></script>
</head>
@@ -60,7 +60,7 @@
var web3 = require('web3');
var eth = web3.eth;
- web3.setProvider(new web3.providers.HttpSyncProvider('http://localhost:8080'));
+ web3.setProvider(new web3.providers.HttpSyncProvider('http://localhost:8545'));
document.querySelector("#number").innerHTML = eth.number;
document.querySelector("#coinbase").innerHTML = eth.coinbase
diff --git a/cmd/mist/assets/qml/main.qml b/cmd/mist/assets/qml/main.qml
index 1272f8761..03c8e4518 100644
--- a/cmd/mist/assets/qml/main.qml
+++ b/cmd/mist/assets/qml/main.qml
@@ -17,6 +17,7 @@ ApplicationWindow {
// Use this to make the window frameless. But then you'll need to do move and resize by hand
property var ethx : Eth.ethx
+ property var catalog;
width: 1200
height: 820
@@ -39,7 +40,7 @@ ApplicationWindow {
// Takes care of loading all default plugins
Component.onCompleted: {
- var catalog = addPlugin("./views/catalog.qml", {noAdd: true, close: false, section: "begin"});
+ catalog = addPlugin("./views/catalog.qml", {noAdd: true, close: false, section: "begin"});
var wallet = addPlugin("./views/wallet.qml", {noAdd: true, close: false, section: "ethereum", active: true});
addPlugin("./views/miner.qml", {noAdd: true, close: false, section: "ethereum", active: true});
@@ -66,6 +67,7 @@ ApplicationWindow {
urlPane.visible = true;
mainView.anchors.top = divider.bottom
}*/
+
}
function addViews(view, path, options) {
@@ -146,27 +148,10 @@ ApplicationWindow {
Menu {
title: "File"
MenuItem {
- text: "Import App"
- shortcut: "Ctrl+o"
- onTriggered: {
- generalFileDialog.show(true, importApp)
- }
- }
-
- MenuItem {
- text: "Add plugin"
- onTriggered: {
- generalFileDialog.show(true, function(path) {
- addPlugin(path, {close: true, section: "apps"})
- })
- }
- }
-
- MenuItem {
text: "New tab"
shortcut: "Ctrl+t"
onTriggered: {
- newBrowserTab("http://etherian.io");
+ activeView(catalog.view, catalog.menuItem);
}
}
@@ -258,18 +243,6 @@ ApplicationWindow {
}
}
}
-
- Menu {
- title: "GLOBAL SHORTCUTS"
- visible: false
- MenuItem {
- visible: false
- shortcut: "Ctrl+l"
- onTriggered: {
- url.focus = true
- }
- }
- }
}
statusBar: StatusBar {
@@ -285,6 +258,7 @@ ApplicationWindow {
styleColor: "#797979"
}
+ /*
Label {
//y: 6
objectName: "miningLabel"
@@ -303,6 +277,7 @@ ApplicationWindow {
anchors.right: peerGroup.left
anchors.rightMargin: 5
}
+ */
ProgressBar {
visible: false
@@ -335,7 +310,7 @@ ApplicationWindow {
}
Label {
- id: peerLabel
+ id: peerCounterLabel
font.pixelSize: 10
text: "0 / 0"
}
@@ -925,7 +900,6 @@ ApplicationWindow {
}
}
-
function setWalletValue(value) {
walletValueLabel.text = value
}
@@ -935,17 +909,11 @@ ApplicationWindow {
var view = mainView.addPlugin(name)
}
- function setPeers(text) {
- peerLabel.text = text
- }
+ function clearPeers() { peerModel.clear() }
+ function addPeer(peer) { peerModel.append(peer) }
- function addPeer(peer) {
- // We could just append the whole peer object but it cries if you try to alter them
- peerModel.append({ip: peer.ip, port: peer.port, lastResponse:timeAgo(peer.lastSend), latency: peer.latency, version: peer.version, caps: peer.caps})
- }
-
- function resetPeers(){
- peerModel.clear()
+ function setPeerCounters(text) {
+ peerCounterLabel.text = text
}
function timeAgo(unixTs){
@@ -983,9 +951,9 @@ ApplicationWindow {
anchors.fill: parent
id: peerTable
model: peerModel
- TableViewColumn{width: 200; role: "ip" ; title: "IP" }
- TableViewColumn{width: 260; role: "version" ; title: "Version" }
- TableViewColumn{width: 180; role: "caps" ; title: "Capabilities" }
+ TableViewColumn{width: 180; role: "addr" ; title: "Remote Address" }
+ TableViewColumn{width: 280; role: "nodeID" ; title: "Node ID" }
+ TableViewColumn{width: 180; role: "caps" ; title: "Capabilities" }
}
}
}
@@ -1053,37 +1021,25 @@ ApplicationWindow {
Window {
id: addPeerWin
visible: false
- minimumWidth: 300
- maximumWidth: 300
+ minimumWidth: 400
+ maximumWidth: 400
maximumHeight: 50
minimumHeight: 50
title: "Connect to peer"
- ComboBox {
+ TextField {
id: addrField
anchors.verticalCenter: parent.verticalCenter
anchors.left: parent.left
anchors.right: addPeerButton.left
anchors.leftMargin: 10
anchors.rightMargin: 10
+ placeholderText: "enode://<hex node id>:<IP address>:<port>"
onAccepted: {
- eth.connectToPeer(addrField.currentText)
- addPeerWin.visible = false
- }
-
- editable: true
- model: ListModel { id: pastPeers }
-
- Component.onCompleted: {
- pastPeers.insert(0, {text: "poc-8.ethdev.com:30303"})
- /*
- var ips = eth.pastPeers()
- for(var i = 0; i < ips.length; i++) {
- pastPeers.append({text: ips.get(i)})
- }
-
- pastPeers.insert(0, {text: "poc-7.ethdev.com:30303"})
- */
+ if(addrField.text.length != 0) {
+ eth.connectToPeer(addrField.text)
+ addPeerWin.visible = false
+ }
}
}
@@ -1092,14 +1048,16 @@ ApplicationWindow {
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
anchors.rightMargin: 10
- text: "Add"
+ text: "Connect"
onClicked: {
- eth.connectToPeer(addrField.currentText)
- addPeerWin.visible = false
+ if(addrField.text.length != 0) {
+ eth.connectToPeer(addrField.text)
+ addPeerWin.visible = false
+ }
}
}
Component.onCompleted: {
addrField.focus = true
}
}
- } \ No newline at end of file
+ }
diff --git a/cmd/mist/assets/qml/views/browser.qml b/cmd/mist/assets/qml/views/browser.qml
index 3a35c2a65..6ded02fcb 100644
--- a/cmd/mist/assets/qml/views/browser.qml
+++ b/cmd/mist/assets/qml/views/browser.qml
@@ -3,7 +3,7 @@ import QtQuick.Controls 1.0;
import QtQuick.Controls.Styles 1.0
import QtQuick.Layouts 1.0;
import QtWebEngine 1.0
-//import QtWebEngine.experimental 1.0
+import QtWebEngine.experimental 1.0
import QtQuick.Window 2.0;
Rectangle {
@@ -340,41 +340,61 @@ Rectangle {
WebEngineView {
objectName: "webView"
id: webview
+ experimental.settings.javascriptCanAccessClipboard: true
+ experimental.settings.localContentCanAccessRemoteUrls: true
anchors {
left: parent.left
right: parent.right
bottom: parent.bottom
top: navBar.bottom
}
-
- z: 10
-
- onLoadingChanged: {
-
- // this checks if your app has special header tags
+ z: 10
+
+ Timer {
+ interval: 500; running: true; repeat: true
+ onTriggered: {
+ webview.runJavaScript("try{document.querySelector('meta[name=badge]').getAttribute('content')}catch(e){}", function(badge) {
+ if (badge) {
+ menuItem.secondaryTitle = badge;
+ }
+ });
+ }
+ }
+
+ onLoadingChanged: {
if (loadRequest.status == WebEngineView.LoadSucceededStatus) {
webview.runJavaScript("document.title", function(pageTitle) {
menuItem.title = pageTitle;
});
- webView.runJavaScript("document.querySelector(\"meta[name='ethereum-dapp-url-bar-style']\").getAttribute(\"content\")", function(topBarStyle){
+
+ webView.runJavaScript("try{document.querySelector(\"meta[name='ethereum-dapp-url-bar-style']\").getAttribute(\"content\")}catch(e){}", function(topBarStyle){
+ if (!topBarStyle) {
+ showFullUrlBar(true);
+ navBarBackground.visible = true;
+ back.visible = true;
+ appInfoPane.anchors.leftMargin = 0;
+ appInfoPaneShadow.anchors.leftMargin = 0;
+ webview.anchors.topMargin = 0;
+ return;
+ }
+
if (topBarStyle=="transparent") {
// Adjust for a transparent sidebar Dapp
- navBarBackground.visible = false;
- back.visible = false;
- appInfoPane.anchors.leftMargin = -16;
- appInfoPaneShadow.anchors.leftMargin = -16;
- webview.anchors.topMargin = -74;
+ navBarBackground.visible = false;
+ back.visible = false;
+ appInfoPane.anchors.leftMargin = -16;
+ appInfoPaneShadow.anchors.leftMargin = -16;
+ webview.anchors.topMargin = -74;
webview.runJavaScript("document.querySelector('body').classList.add('ethereum-dapp-url-bar-style-transparent')")
} else {
- navBarBackground.visible = true;
- back.visible = true;
- appInfoPane.anchors.leftMargin = 0;
- appInfoPaneShadow.anchors.leftMargin = 0;
- webview.anchors.topMargin = 0;
-
- };
+ navBarBackground.visible = true;
+ back.visible = true;
+ appInfoPane.anchors.leftMargin = 0;
+ appInfoPaneShadow.anchors.leftMargin = 0;
+ webview.anchors.topMargin = 0;
+ };
});
// webView.runJavaScript("document.querySelector(\"link[rel='icon']\").getAttribute(\"href\")", function(sideIcon){
@@ -391,10 +411,13 @@ Rectangle {
var matches = cleanTitle.match(/^[a-z]*\:\/\/([^\/?#]+)(?:[\/?#]|$)/i);
var domain = matches && matches[1];
- appDomain.text = domain
- appTitle.text = webview.title
- showFullUrlBar(false);
+ if (domain)
+ appDomain.text = domain //webview.url.replace("a", "z")
+ if (webview.title)
+ appTitle.text = webview.title
+
+ showFullUrlBar(false);
}
}
onJavaScriptConsoleMessage: {
diff --git a/cmd/mist/assets/qml/views/info.qml b/cmd/mist/assets/qml/views/info.qml
index 14ee0bce1..b2d2f521c 100644
--- a/cmd/mist/assets/qml/views/info.qml
+++ b/cmd/mist/assets/qml/views/info.qml
@@ -32,18 +32,6 @@ Rectangle {
width: 500
}
- Label {
- text: "Client ID"
- }
- TextField {
- text: gui.getCustomIdentifier()
- width: 500
- placeholderText: "Anonymous"
- onTextChanged: {
- gui.setCustomIdentifier(text)
- }
- }
-
TextArea {
objectName: "statsPane"
width: parent.width
diff --git a/cmd/mist/assets/qml/views/miner.qml b/cmd/mist/assets/qml/views/miner.qml
index 193ce37be..6a199a925 100644
--- a/cmd/mist/assets/qml/views/miner.qml
+++ b/cmd/mist/assets/qml/views/miner.qml
@@ -14,6 +14,27 @@ Rectangle {
color: "#00000000"
+ Label {
+ visible: false
+ id: lastBlockLabel
+ objectName: "lastBlockLabel"
+ text: "---"
+ onTextChanged: {
+ //menuItem.secondaryTitle = text
+ }
+ }
+
+ Label {
+ objectName: "miningLabel"
+ visible: false
+ font.pixelSize: 10
+ anchors.right: lastBlockLabel.left
+ anchors.rightMargin: 5
+ onTextChanged: {
+ menuItem.secondaryTitle = text
+ }
+ }
+
ColumnLayout {
spacing: 10
anchors.fill: parent
diff --git a/cmd/mist/assets/qml/views/transaction.qml b/cmd/mist/assets/qml/views/transaction.qml
index 62c762956..df798a9c0 100644
--- a/cmd/mist/assets/qml/views/transaction.qml
+++ b/cmd/mist/assets/qml/views/transaction.qml
@@ -103,7 +103,7 @@ Rectangle {
ComboBox {
id: valueDenom
- currentIndex: 6
+ currentIndex: 5
model: denomModel
}
}
@@ -177,7 +177,7 @@ Rectangle {
mainContractColumn.state = "ERROR"
} else {
txResult.text = "Your transaction has been submitted:\n"
- txOutput.text = res[0].address
+ txOutput.text = res.toString()
mainContractColumn.state = "DONE"
console.log(res)
diff --git a/cmd/mist/assets/qml/views/wallet.qml b/cmd/mist/assets/qml/views/wallet.qml
index 545098284..59dbae848 100644
--- a/cmd/mist/assets/qml/views/wallet.qml
+++ b/cmd/mist/assets/qml/views/wallet.qml
@@ -15,6 +15,15 @@ Rectangle {
objectName: "walletView"
anchors.fill: parent
+ Label {
+ objectName: "balanceLabel"
+ visible: false
+ onTextChanged: {
+ balance.text = text
+ menuItem.secondaryTitle = text
+ }
+ }
+
function onReady() {
setBalance()
}
@@ -95,7 +104,7 @@ Rectangle {
ComboBox {
id: valueDenom
- currentIndex: 6
+ currentIndex: 5
model: denomModel
}
diff --git a/cmd/mist/bindings.go b/cmd/mist/bindings.go
index 706c789b1..9623538a3 100644
--- a/cmd/mist/bindings.go
+++ b/cmd/mist/bindings.go
@@ -64,15 +64,6 @@ func (gui *Gui) Transact(recipient, value, gas, gasPrice, d string) (string, err
return gui.xeth.Transact(recipient, value, gas, gasPrice, data)
}
-func (gui *Gui) SetCustomIdentifier(customIdentifier string) {
- gui.clientIdentity.SetCustomIdentifier(customIdentifier)
- gui.config.Save("id", customIdentifier)
-}
-
-func (gui *Gui) GetCustomIdentifier() string {
- return gui.clientIdentity.GetCustomIdentifier()
-}
-
// functions that allow Gui to implement interface guilogger.LogSystem
func (gui *Gui) SetLogLevel(level logger.LogLevel) {
gui.logLevel = level
diff --git a/cmd/mist/ext_app.go b/cmd/mist/ext_app.go
index 20ec52e60..4831884e5 100644
--- a/cmd/mist/ext_app.go
+++ b/cmd/mist/ext_app.go
@@ -24,7 +24,6 @@ import (
"github.com/ethereum/go-ethereum/core"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/event"
- "github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/ui/qt"
"github.com/ethereum/go-ethereum/xeth"
"github.com/obscuren/qml"
@@ -39,7 +38,6 @@ type AppContainer interface {
NewBlock(*types.Block)
NewWatcher(chan bool)
- Messages(state.Messages, string)
Post(string, int)
}
@@ -79,10 +77,6 @@ func (app *ExtApplication) run() {
return
}
- // Subscribe to events
- mux := app.lib.eth.EventMux()
- app.events = mux.Subscribe(core.NewBlockEvent{}, state.Messages(nil))
-
// Call the main loop
go app.mainLoop()
@@ -126,23 +120,3 @@ func (app *ExtApplication) mainLoop() {
func (self *ExtApplication) Watch(filterOptions map[string]interface{}, identifier string) {
self.filters[identifier] = qt.NewFilterFromMap(filterOptions, self.eth)
}
-
-func (self *ExtApplication) GetMessages(object map[string]interface{}) string {
- /* TODO remove me
- filter := qt.NewFilterFromMap(object, self.eth)
-
- messages := filter.Find()
- var msgs []javascript.JSMessage
- for _, m := range messages {
- msgs = append(msgs, javascript.NewJSMessage(m))
- }
-
- b, err := json.Marshal(msgs)
- if err != nil {
- return "{\"error\":" + err.Error() + "}"
- }
-
- return string(b)
- */
- return ""
-}
diff --git a/cmd/mist/flags.go b/cmd/mist/flags.go
index f042b39b0..eb280f71b 100644
--- a/cmd/mist/flags.go
+++ b/cmd/mist/flags.go
@@ -21,6 +21,7 @@
package main
import (
+ "crypto/ecdsa"
"flag"
"fmt"
"log"
@@ -31,7 +32,9 @@ import (
"runtime"
"bitbucket.org/kardianos/osext"
+ "github.com/ethereum/go-ethereum/crypto"
"github.com/ethereum/go-ethereum/logger"
+ "github.com/ethereum/go-ethereum/p2p/nat"
"github.com/ethereum/go-ethereum/vm"
)
@@ -39,19 +42,18 @@ var (
Identifier string
KeyRing string
KeyStore string
- PMPGateway string
StartRpc bool
StartWebSockets bool
RpcPort int
WsPort int
- UseUPnP bool
- NatType string
OutboundPort string
ShowGenesis bool
AddPeer string
MaxPeer int
GenAddr bool
- SeedNode string
+ BootNodes string
+ NodeKey *ecdsa.PrivateKey
+ NAT nat.Interface
SecretFile string
ExportDir string
NonInteractive bool
@@ -99,6 +101,7 @@ func defaultDataDir() string {
var defaultConfigFile = path.Join(defaultDataDir(), "conf.ini")
func Init() {
+ // TODO: move common flag processing to cmd/utils
flag.Usage = func() {
fmt.Fprintf(os.Stderr, "%s [options] [filename]:\noptions precedence: default < config file < environment variables < command line\n", os.Args[0])
flag.PrintDefaults()
@@ -108,30 +111,51 @@ func Init() {
flag.StringVar(&Identifier, "id", "", "Custom client identifier")
flag.StringVar(&KeyRing, "keyring", "", "identifier for keyring to use")
flag.StringVar(&KeyStore, "keystore", "db", "system to store keyrings: db|file (db)")
- flag.StringVar(&OutboundPort, "port", "30303", "listening port")
- flag.BoolVar(&UseUPnP, "upnp", true, "enable UPnP support")
- flag.IntVar(&MaxPeer, "maxpeer", 30, "maximum desired peers")
flag.IntVar(&RpcPort, "rpcport", 8545, "port to start json-rpc server on")
flag.IntVar(&WsPort, "wsport", 40404, "port to start websocket rpc server on")
flag.BoolVar(&StartRpc, "rpc", true, "start rpc server")
flag.BoolVar(&StartWebSockets, "ws", false, "start websocket server")
flag.BoolVar(&NonInteractive, "y", false, "non-interactive mode (say yes to confirmations)")
- flag.StringVar(&SeedNode, "seednode", "poc-8.ethdev.com:30303", "ip:port of seed node to connect to. Set to blank for skip")
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)")
flag.StringVar(&AssetPath, "asset_path", defaultAssetPath(), "absolute path to GUI assets directory")
+ // Network stuff
+ var (
+ nodeKeyFile = flag.String("nodekey", "", "network private key file")
+ nodeKeyHex = flag.String("nodekeyhex", "", "network private key (for testing)")
+ natstr = flag.String("nat", "any", "port mapping mechanism (any|none|upnp|pmp|extip:<IP>)")
+ )
+ flag.StringVar(&OutboundPort, "port", "30303", "listening port")
+ flag.StringVar(&BootNodes, "bootnodes", "", "space-separated node URLs for discovery bootstrap")
+ flag.IntVar(&MaxPeer, "maxpeer", 30, "maximum desired peers")
+
flag.Parse()
+ var err error
+ if NAT, err = nat.Parse(*natstr); err != nil {
+ log.Fatalf("-nat: %v", err)
+ }
+ switch {
+ case *nodeKeyFile != "" && *nodeKeyHex != "":
+ log.Fatal("Options -nodekey and -nodekeyhex are mutually exclusive")
+ case *nodeKeyFile != "":
+ if NodeKey, err = crypto.LoadECDSA(*nodeKeyFile); err != nil {
+ log.Fatalf("-nodekey: %v", err)
+ }
+ case *nodeKeyHex != "":
+ if NodeKey, err = crypto.HexToECDSA(*nodeKeyHex); err != nil {
+ log.Fatalf("-nodekeyhex: %v", err)
+ }
+ }
+
if VmType >= int(vm.MaxVmTy) {
log.Fatal("Invalid VM type ", VmType)
}
diff --git a/cmd/mist/gui.go b/cmd/mist/gui.go
index edc799abc..208b553d2 100644
--- a/cmd/mist/gui.go
+++ b/cmd/mist/gui.go
@@ -31,6 +31,7 @@ import (
"os"
"path"
"runtime"
+ "sort"
"strconv"
"time"
@@ -41,7 +42,6 @@ import (
"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/ui/qt/qwhisper"
"github.com/ethereum/go-ethereum/xeth"
"github.com/obscuren/qml"
@@ -77,9 +77,8 @@ type Gui struct {
xeth *xeth.XEth
- Session string
- clientIdentity *p2p.SimpleClientIdentity
- config *ethutil.ConfigManager
+ Session string
+ config *ethutil.ConfigManager
plugins map[string]plugin
@@ -87,7 +86,7 @@ type Gui struct {
}
// Create GUI, but doesn't start it
-func NewWindow(ethereum *eth.Ethereum, config *ethutil.ConfigManager, clientIdentity *p2p.SimpleClientIdentity, session string, logLevel int) *Gui {
+func NewWindow(ethereum *eth.Ethereum, config *ethutil.ConfigManager, session string, logLevel int) *Gui {
db, err := ethdb.NewLDBDatabase("tx_database")
if err != nil {
panic(err)
@@ -95,15 +94,14 @@ func NewWindow(ethereum *eth.Ethereum, config *ethutil.ConfigManager, clientIden
xeth := xeth.New(ethereum)
gui := &Gui{eth: ethereum,
- txDb: db,
- xeth: xeth,
- logLevel: logger.LogLevel(logLevel),
- Session: session,
- open: false,
- clientIdentity: clientIdentity,
- config: config,
- plugins: make(map[string]plugin),
- serviceEvents: make(chan ServEv, 1),
+ txDb: db,
+ xeth: xeth,
+ logLevel: logger.LogLevel(logLevel),
+ Session: session,
+ open: false,
+ config: config,
+ plugins: make(map[string]plugin),
+ serviceEvents: make(chan ServEv, 1),
}
data, _ := ethutil.ReadAllFile(path.Join(ethutil.Config.ExecPath, "plugins.json"))
json.Unmarshal([]byte(data), &gui.plugins)
@@ -415,9 +413,9 @@ 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 {
- gui.setWalletValue(gui.eth.ChainManager().State().GetBalance(gui.address()), nil)
- }
+ //gui.setWalletValue(gui.eth.ChainManager().State().GetBalance(gui.address()), nil)
+ balance := ethutil.CurrencyToString(gui.eth.ChainManager().State().GetBalance(gui.address()))
+ gui.getObjectByName("balanceLabel").Set("text", fmt.Sprintf("%v", balance))
case core.TxPreEvent:
tx := ev.Tx
@@ -452,10 +450,11 @@ func (gui *Gui) update() {
case <-peerUpdateTicker.C:
gui.setPeerInfo()
+
case <-generalUpdateTicker.C:
statusText := "#" + gui.eth.ChainManager().CurrentBlock().Number().String()
lastBlockLabel.Set("text", statusText)
- miningLabel.Set("text", "Mining @ "+strconv.FormatInt(gui.uiLib.miner.GetPow().GetHashrate(), 10)+"Khash")
+ miningLabel.Set("text", "Mining @ "+strconv.FormatInt(gui.uiLib.miner.HashRate(), 10)+"/Khash")
/*
blockLength := gui.eth.BlockPool().BlocksProcessed
@@ -502,12 +501,34 @@ NumGC: %d
))
}
+type qmlpeer struct{ Addr, NodeID, Caps string }
+
+type peersByID []*qmlpeer
+
+func (s peersByID) Len() int { return len(s) }
+func (s peersByID) Less(i, j int) bool { return s[i].NodeID < s[j].NodeID }
+func (s peersByID) Swap(i, j int) { s[i], s[j] = s[j], s[i] }
+
func (gui *Gui) setPeerInfo() {
- gui.win.Root().Call("setPeers", fmt.Sprintf("%d / %d", gui.eth.PeerCount(), gui.eth.MaxPeers))
- gui.win.Root().Call("resetPeers")
- //for _, peer := range gui.xeth.Peers() {
- //gui.win.Root().Call("addPeer", peer)
- //}
+ peers := gui.eth.Peers()
+ qpeers := make(peersByID, len(peers))
+ for i, p := range peers {
+ qpeers[i] = &qmlpeer{
+ NodeID: p.ID().String(),
+ Addr: p.RemoteAddr().String(),
+ Caps: fmt.Sprint(p.Caps()),
+ }
+ }
+ // we need to sort the peers because they jump around randomly
+ // otherwise. order returned by eth.Peers is random because they
+ // are taken from a map.
+ sort.Sort(qpeers)
+
+ gui.win.Root().Call("setPeerCounters", fmt.Sprintf("%d / %d", len(peers), gui.eth.MaxPeers()))
+ gui.win.Root().Call("clearPeers")
+ for _, p := range qpeers {
+ gui.win.Root().Call("addPeer", p)
+ }
}
func (gui *Gui) privateKey() string {
diff --git a/cmd/mist/html_container.go b/cmd/mist/html_container.go
index 0909a6abd..e4ea57b9b 100644
--- a/cmd/mist/html_container.go
+++ b/cmd/mist/html_container.go
@@ -31,7 +31,6 @@ import (
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethutil"
- "github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/xeth"
"github.com/howeyc/fsnotify"
"github.com/obscuren/qml"
@@ -144,19 +143,6 @@ func (app *HtmlApplication) NewBlock(block *types.Block) {
app.webView.Call("onNewBlockCb", b)
}
-func (self *HtmlApplication) Messages(messages state.Messages, id string) {
- /* TODO remove me
- var msgs []javascript.JSMessage
- for _, m := range messages {
- msgs = append(msgs, javascript.NewJSMessage(m))
- }
-
- b, _ := json.Marshal(msgs)
-
- self.webView.Call("onWatchedCb", string(b), id)
- */
-}
-
func (app *HtmlApplication) Destroy() {
app.engine.Destroy()
}
diff --git a/cmd/mist/main.go b/cmd/mist/main.go
index 66872a241..32222fbef 100644
--- a/cmd/mist/main.go
+++ b/cmd/mist/main.go
@@ -36,7 +36,7 @@ import (
const (
ClientIdentifier = "Mist"
- Version = "0.8.2"
+ Version = "0.8.3"
)
var ethereum *eth.Ethereum
@@ -52,19 +52,18 @@ func run() error {
config := utils.InitConfig(VmType, ConfigFile, Datadir, "ETH")
ethereum, err := eth.New(&eth.Config{
- Name: ClientIdentifier,
- Version: Version,
- KeyStore: KeyStore,
- DataDir: Datadir,
- LogFile: LogFile,
- LogLevel: LogLevel,
- Identifier: Identifier,
- MaxPeers: MaxPeer,
- Port: OutboundPort,
- NATType: PMPGateway,
- PMPGateway: PMPGateway,
- KeyRing: KeyRing,
- Dial: true,
+ Name: p2p.MakeName(ClientIdentifier, Version),
+ KeyStore: KeyStore,
+ DataDir: Datadir,
+ LogFile: LogFile,
+ LogLevel: LogLevel,
+ MaxPeers: MaxPeer,
+ Port: OutboundPort,
+ NAT: NAT,
+ BootNodes: BootNodes,
+ NodeKey: NodeKey,
+ KeyRing: KeyRing,
+ Dial: true,
})
if err != nil {
mainlogger.Fatalln(err)
@@ -79,12 +78,12 @@ func run() error {
utils.StartWebSockets(ethereum, WsPort)
}
- gui := NewWindow(ethereum, config, ethereum.ClientIdentity().(*p2p.SimpleClientIdentity), KeyRing, LogLevel)
+ gui := NewWindow(ethereum, config, KeyRing, LogLevel)
utils.RegisterInterrupt(func(os.Signal) {
gui.Stop()
})
- go utils.StartEthereum(ethereum, SeedNode)
+ go utils.StartEthereum(ethereum)
fmt.Println("ETH stack took", time.Since(tstart))
diff --git a/cmd/mist/qml_container.go b/cmd/mist/qml_container.go
index 9d76d8fe4..16a055bc0 100644
--- a/cmd/mist/qml_container.go
+++ b/cmd/mist/qml_container.go
@@ -22,12 +22,10 @@
package main
import (
- "fmt"
"runtime"
"github.com/ethereum/go-ethereum/core/types"
"github.com/ethereum/go-ethereum/ethutil"
- "github.com/ethereum/go-ethereum/state"
"github.com/ethereum/go-ethereum/xeth"
"github.com/obscuren/qml"
)
@@ -74,10 +72,6 @@ func (app *QmlApplication) NewBlock(block *types.Block) {
app.win.Call("onNewBlockCb", pblock)
}
-func (self *QmlApplication) Messages(msgs state.Messages, id string) {
- fmt.Println("IMPLEMENT QML APPLICATION MESSAGES METHOD")
-}
-
// Getters
func (app *QmlApplication) Engine() *qml.Engine {
return app.engine
diff --git a/cmd/mist/ui_lib.go b/cmd/mist/ui_lib.go
index 7c5802076..368fb002b 100644
--- a/cmd/mist/ui_lib.go
+++ b/cmd/mist/ui_lib.go
@@ -73,11 +73,6 @@ func (self *UiLib) Notef(args []interface{}) {
guilogger.Infoln(args...)
}
-func (self *UiLib) PastPeers() *ethutil.List {
- return ethutil.NewList([]string{})
- //return ethutil.NewList(eth.PastPeers())
-}
-
func (self *UiLib) ImportTx(rlpTx string) {
tx := types.NewTransactionFromBytes(ethutil.Hex2Bytes(rlpTx))
err := self.eth.TxPool().Add(tx)
@@ -136,15 +131,15 @@ func (ui *UiLib) Muted(content string) {
func (ui *UiLib) Connect(button qml.Object) {
if !ui.connected {
- ui.eth.Start(SeedNode)
+ ui.eth.Start()
ui.connected = true
button.Set("enabled", false)
}
}
-func (ui *UiLib) ConnectToPeer(addr string) {
- if err := ui.eth.SuggestPeer(addr); err != nil {
- guilogger.Infoln(err)
+func (ui *UiLib) ConnectToPeer(nodeURL string) {
+ if err := ui.eth.SuggestPeer(nodeURL); err != nil {
+ guilogger.Infoln("SuggestPeer error: " + err.Error())
}
}
@@ -209,17 +204,20 @@ func (self *UiLib) Call(params map[string]interface{}) (string, error) {
}
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
+ return 0
+ /*
+ 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)
+ //self.miner.RemoveLocalTx(id)
}
func (self *UiLib) SetGasPrice(price string) {