mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-07-19 11:20:45 +00:00
Merge 51a2087081 into b3f25a6ade
This commit is contained in:
commit
e3953837dc
16 changed files with 642 additions and 245 deletions
|
|
@ -1,7 +1,9 @@
|
||||||
Ethereum
|
Ethereum
|
||||||
========
|
========
|
||||||
|
|
||||||
[](https://travis-ci.org/ethereum/go-ethereum)
|
Master [](http://cpt-obvious.ethercasts.com:8010/builders/go-ethereum-master-docker/builds/-1) Develop [](http://cpt-obvious.ethercasts.com:8010/builders/go-ethereum-develop-docker/builds/-1)
|
||||||
|
|
||||||
Ethereum Go Client © 2014 Jeffrey Wilcke.
|
Ethereum Go Client © 2014 Jeffrey Wilcke.
|
||||||
|
|
||||||
|
|
|
||||||
21
ethereal/assets/ext/home.html
Normal file
21
ethereal/assets/ext/home.html
Normal file
|
|
@ -0,0 +1,21 @@
|
||||||
|
<!doctype>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title>Ethereum</title>
|
||||||
|
|
||||||
|
<style type="text/css">
|
||||||
|
h1 {
|
||||||
|
text-align: center;
|
||||||
|
font-family: Courier;
|
||||||
|
font-size: 50pt;
|
||||||
|
margin-top: 25%
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
|
||||||
|
<body>
|
||||||
|
<h1>... Ethereum ...</h1>
|
||||||
|
<!-- ĐΞV --!>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
117
ethereal/assets/ext/messaging.js
Normal file
117
ethereal/assets/ext/messaging.js
Normal file
|
|
@ -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}))
|
||||||
|
}
|
||||||
|
|
@ -26,6 +26,27 @@ ApplicationWindow {
|
||||||
shortcut: "Ctrl+o"
|
shortcut: "Ctrl+o"
|
||||||
onTriggered: openAppDialog.open()
|
onTriggered: openAppDialog.open()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MenuItem {
|
||||||
|
text: "Browser"
|
||||||
|
onTriggered: ui.openBrowser()
|
||||||
|
}
|
||||||
|
|
||||||
|
MenuSeparator {}
|
||||||
|
|
||||||
|
MenuItem {
|
||||||
|
text: "Import key"
|
||||||
|
shortcut: "Ctrl+i"
|
||||||
|
onTriggered: importDialog.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
MenuItem {
|
||||||
|
text: "Export keys"
|
||||||
|
shortcut: "Ctrl+e"
|
||||||
|
onTriggered: exportDialog.open()
|
||||||
|
}
|
||||||
|
|
||||||
|
//MenuSeparator {}
|
||||||
}
|
}
|
||||||
|
|
||||||
Menu {
|
Menu {
|
||||||
|
|
@ -35,6 +56,13 @@ ApplicationWindow {
|
||||||
shortcut: "Ctrl+d"
|
shortcut: "Ctrl+d"
|
||||||
onTriggered: ui.startDebugger()
|
onTriggered: ui.startDebugger()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MenuItem {
|
||||||
|
text: "Import Tx"
|
||||||
|
onTriggered: {
|
||||||
|
txImportDialog.visible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Menu {
|
Menu {
|
||||||
|
|
@ -77,6 +105,7 @@ ApplicationWindow {
|
||||||
historyView.visible = false
|
historyView.visible = false
|
||||||
newTxView.visible = false
|
newTxView.visible = false
|
||||||
infoView.visible = false
|
infoView.visible = false
|
||||||
|
pendingTxView.visible = false
|
||||||
view.visible = true
|
view.visible = true
|
||||||
//root.title = "Ethereal - " = view.title
|
//root.title = "Ethereal - " = view.title
|
||||||
}
|
}
|
||||||
|
|
@ -140,6 +169,17 @@ ApplicationWindow {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Image {
|
||||||
|
source: "../tx.png"
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
MouseArea {
|
||||||
|
anchors.fill: parent
|
||||||
|
onClicked: {
|
||||||
|
setView(pendingTxView)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -344,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)
|
signal addPlugin(string name)
|
||||||
Component {
|
Component {
|
||||||
|
|
@ -375,9 +437,7 @@ ApplicationWindow {
|
||||||
//ui.open(openAppDialog.fileUrl.toString())
|
//ui.open(openAppDialog.fileUrl.toString())
|
||||||
//ui.openHtml(Qt.resolvedUrl(ui.assetPath("test.html")))
|
//ui.openHtml(Qt.resolvedUrl(ui.assetPath("test.html")))
|
||||||
var path = openAppDialog.fileUrl.toString()
|
var path = openAppDialog.fileUrl.toString()
|
||||||
console.log(path)
|
|
||||||
var ext = path.split('.').pop()
|
var ext = path.split('.').pop()
|
||||||
console.log(ext)
|
|
||||||
if(ext == "html" || ext == "htm") {
|
if(ext == "html" || ext == "htm") {
|
||||||
ui.openHtml(path)
|
ui.openHtml(path)
|
||||||
}else if(ext == "qml"){
|
}else if(ext == "qml"){
|
||||||
|
|
@ -386,6 +446,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 {
|
statusBar: StatusBar {
|
||||||
height: 30
|
height: 30
|
||||||
RowLayout {
|
RowLayout {
|
||||||
|
|
@ -465,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 {
|
Window {
|
||||||
id: popup
|
id: popup
|
||||||
visible: false
|
visible: false
|
||||||
|
|
@ -660,7 +766,7 @@ ApplicationWindow {
|
||||||
anchors.left: aboutIcon.right
|
anchors.left: aboutIcon.right
|
||||||
anchors.leftMargin: 10
|
anchors.leftMargin: 10
|
||||||
font.pointSize: 12
|
font.pointSize: 12
|
||||||
text: "<h2>Ethereal</h2><br><h3>Development</h3>Jeffrey Wilcke<br>Maran Hidskes<br>Viktor Trón<br>"
|
text: "<h2>Ethereal - Adrastea</h2><br><h3>Development</h3>Jeffrey Wilcke<br>Maran Hidskes<br>Viktor Trón<br>"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -684,7 +790,7 @@ ApplicationWindow {
|
||||||
walletValueLabel.text = value
|
walletValueLabel.text = value
|
||||||
}
|
}
|
||||||
|
|
||||||
function addTx(tx, inout) {
|
function addTx(type, tx, inout) {
|
||||||
var isContract
|
var isContract
|
||||||
if (tx.contract == true){
|
if (tx.contract == true){
|
||||||
isContract = "Yes"
|
isContract = "Yes"
|
||||||
|
|
@ -692,13 +798,19 @@ ApplicationWindow {
|
||||||
isContract = "No"
|
isContract = "No"
|
||||||
}
|
}
|
||||||
|
|
||||||
var address;
|
|
||||||
if(inout == "recv") {
|
if(type == "post") {
|
||||||
address = tx.sender;
|
var address;
|
||||||
} else {
|
if(inout == "recv") {
|
||||||
address = tx.address;
|
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) {
|
function addBlock(block, initial) {
|
||||||
|
|
@ -714,7 +826,7 @@ ApplicationWindow {
|
||||||
|
|
||||||
if(initial){
|
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)})
|
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)})
|
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)})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -770,7 +882,7 @@ ApplicationWindow {
|
||||||
// ******************************************
|
// ******************************************
|
||||||
Window {
|
Window {
|
||||||
id: peerWindow
|
id: peerWindow
|
||||||
//flags: Qt.CustomizeWindowHint | Qt.Tool | Qt.WindowCloseButtonHint
|
//flags: Qt.CustomizeWindowHint | Qt.Tool | Qt.WindowCloseButtonHint
|
||||||
height: 200
|
height: 200
|
||||||
width: 700
|
width: 700
|
||||||
Rectangle {
|
Rectangle {
|
||||||
|
|
@ -897,10 +1009,10 @@ ApplicationWindow {
|
||||||
placeholderText: "Gas"
|
placeholderText: "Gas"
|
||||||
text: "500"
|
text: "500"
|
||||||
/*
|
/*
|
||||||
onTextChanged: {
|
onTextChanged: {
|
||||||
contractFormReady()
|
contractFormReady()
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
Label {
|
Label {
|
||||||
id: atLabel
|
id: atLabel
|
||||||
|
|
@ -914,10 +1026,10 @@ ApplicationWindow {
|
||||||
text: "10"
|
text: "10"
|
||||||
validator: RegExpValidator { regExp: /\d*/ }
|
validator: RegExpValidator { regExp: /\d*/ }
|
||||||
/*
|
/*
|
||||||
onTextChanged: {
|
onTextChanged: {
|
||||||
contractFormReady()
|
contractFormReady()
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
ComboBox {
|
ComboBox {
|
||||||
|
|
@ -962,7 +1074,7 @@ ApplicationWindow {
|
||||||
var gasPrice = txGasPrice.text + denomModel.get(gasDenom.currentIndex).zeros;
|
var gasPrice = txGasPrice.text + denomModel.get(gasDenom.currentIndex).zeros;
|
||||||
var res = eth.create(txFuelRecipient.text, value, txGas.text, gasPrice, codeView.text)
|
var res = eth.create(txFuelRecipient.text, value, txGas.text, gasPrice, codeView.text)
|
||||||
if(res[1]) {
|
if(res[1]) {
|
||||||
txResult.text = "Your contract <b>could not</b> be send over the network:\n<b>"
|
txResult.text = "Your contract <b>could not</b> be sent over the network:\n<b>"
|
||||||
txResult.text += res[1].error()
|
txResult.text += res[1].error()
|
||||||
txResult.text += "</b>"
|
txResult.text += "</b>"
|
||||||
mainContractColumn.state = "ERROR"
|
mainContractColumn.state = "ERROR"
|
||||||
|
|
|
||||||
|
|
@ -21,19 +21,54 @@ ApplicationWindow {
|
||||||
id: root
|
id: root
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
state: "inspectorShown"
|
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 {
|
WebView {
|
||||||
objectName: "webView"
|
objectName: "webView"
|
||||||
id: webview
|
id: webview
|
||||||
anchors.fill: parent
|
anchors {
|
||||||
/*
|
left: parent.left
|
||||||
anchors {
|
right: parent.right
|
||||||
left: parent.left
|
bottom: parent.bottom
|
||||||
right: parent.right
|
top: uriNav.bottom
|
||||||
bottom: sizeGrip.top
|
}
|
||||||
top: parent.top
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
onTitleChanged: { window.title = title }
|
onTitleChanged: { window.title = title }
|
||||||
experimental.preferences.javascriptEnabled: true
|
experimental.preferences.javascriptEnabled: true
|
||||||
experimental.preferences.navigatorQtObjectEnabled: true
|
experimental.preferences.navigatorQtObjectEnabled: true
|
||||||
|
|
@ -46,50 +81,50 @@ ApplicationWindow {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
switch(data.call) {
|
switch(data.call) {
|
||||||
case "getCoinBase":
|
case "getCoinBase":
|
||||||
postData(data._seed, eth.getCoinBase())
|
postData(data._seed, eth.getCoinBase())
|
||||||
|
|
||||||
break
|
break
|
||||||
case "getIsListening":
|
case "getIsListening":
|
||||||
postData(data._seed, eth.getIsListening())
|
postData(data._seed, eth.getIsListening())
|
||||||
|
|
||||||
break
|
break
|
||||||
case "getIsMining":
|
case "getIsMining":
|
||||||
postData(data._seed, eth.getIsMining())
|
postData(data._seed, eth.getIsMining())
|
||||||
|
|
||||||
break
|
break
|
||||||
case "getPeerCount":
|
case "getPeerCount":
|
||||||
postData(data._seed, eth.getPeerCount())
|
postData(data._seed, eth.getPeerCount())
|
||||||
|
|
||||||
break
|
break
|
||||||
|
|
||||||
case "getTxCountAt":
|
case "getTxCountAt":
|
||||||
require(1)
|
require(1)
|
||||||
postData(data._seed, eth.getTxCountAt(data.args[0]))
|
postData(data._seed, eth.getTxCountAt(data.args[0]))
|
||||||
|
|
||||||
break
|
break
|
||||||
case "getBlockByNumber":
|
case "getBlockByNumber":
|
||||||
var block = eth.getBlock(data.args[0])
|
var block = eth.getBlock(data.args[0])
|
||||||
postData(data._seed, block)
|
postData(data._seed, block)
|
||||||
|
|
||||||
break
|
break
|
||||||
case "getBlockByHash":
|
case "getBlockByHash":
|
||||||
var block = eth.getBlock(data.args[0])
|
var block = eth.getBlock(data.args[0])
|
||||||
postData(data._seed, block)
|
postData(data._seed, block)
|
||||||
|
|
||||||
break
|
break
|
||||||
case "transact":
|
case "transact":
|
||||||
require(5)
|
require(5)
|
||||||
|
|
||||||
var tx = eth.transact(data.args[0], data.args[1], data.args[2],data.args[3],data.args[4],data.args[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)
|
postData(data._seed, tx)
|
||||||
|
|
||||||
break
|
break
|
||||||
case "create":
|
case "create":
|
||||||
postData(data._seed, null)
|
postData(data._seed, null)
|
||||||
|
|
||||||
break
|
break
|
||||||
case "getStorage":
|
case "getStorage":
|
||||||
require(2);
|
require(2);
|
||||||
|
|
||||||
var stateObject = eth.getStateObject(data.args[0])
|
var stateObject = eth.getStateObject(data.args[0])
|
||||||
|
|
@ -97,52 +132,52 @@ ApplicationWindow {
|
||||||
postData(data._seed, storage)
|
postData(data._seed, storage)
|
||||||
|
|
||||||
break
|
break
|
||||||
case "getStateKeyVals":
|
case "getStateKeyVals":
|
||||||
require(1);
|
require(1);
|
||||||
var stateObject = eth.getStateObject(data.args[0]).stateKeyVal(true)
|
var stateObject = eth.getStateObject(data.args[0]).stateKeyVal(true)
|
||||||
postData(data._seed,stateObject)
|
postData(data._seed,stateObject)
|
||||||
|
|
||||||
break
|
break
|
||||||
case "getTransactionsFor":
|
case "getTransactionsFor":
|
||||||
require(1);
|
require(1);
|
||||||
var txs = eth.getTransactionsFor(data.args[0], true)
|
var txs = eth.getTransactionsFor(data.args[0], true)
|
||||||
postData(data._seed, txs)
|
postData(data._seed, txs)
|
||||||
|
|
||||||
break
|
break
|
||||||
case "getBalance":
|
case "getBalance":
|
||||||
require(1);
|
require(1);
|
||||||
|
|
||||||
postData(data._seed, eth.getStateObject(data.args[0]).value());
|
postData(data._seed, eth.getStateObject(data.args[0]).value());
|
||||||
|
|
||||||
break
|
break
|
||||||
case "getKey":
|
case "getKey":
|
||||||
var key = eth.getKey().privateKey;
|
var key = eth.getKey().privateKey;
|
||||||
|
|
||||||
postData(data._seed, key)
|
postData(data._seed, key)
|
||||||
break
|
break
|
||||||
case "watch":
|
case "watch":
|
||||||
require(1)
|
require(1)
|
||||||
eth.watch(data.args[0], data.args[1]);
|
eth.watch(data.args[0], data.args[1]);
|
||||||
break
|
break
|
||||||
case "disconnect":
|
case "disconnect":
|
||||||
require(1)
|
require(1)
|
||||||
postData(data._seed, null)
|
postData(data._seed, null)
|
||||||
break;
|
break;
|
||||||
case "set":
|
case "set":
|
||||||
console.log("'Set' has been depcrecated")
|
console.log("'Set' has been depcrecated")
|
||||||
/*
|
/*
|
||||||
for(var key in data.args) {
|
for(var key in data.args) {
|
||||||
if(webview.hasOwnProperty(key)) {
|
if(webview.hasOwnProperty(key)) {
|
||||||
window[key] = data.args[key];
|
window[key] = data.args[key];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
break;
|
break;
|
||||||
case "getSecretToAddress":
|
case "getSecretToAddress":
|
||||||
require(1)
|
require(1)
|
||||||
postData(data._seed, eth.secretToAddress(data.args[0]))
|
postData(data._seed, eth.secretToAddress(data.args[0]))
|
||||||
break;
|
break;
|
||||||
case "debug":
|
case "debug":
|
||||||
console.log(data.args[0]);
|
console.log(data.args[0]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -191,12 +226,12 @@ ApplicationWindow {
|
||||||
inspector.visible = false
|
inspector.visible = false
|
||||||
}else{
|
}else{
|
||||||
inspector.visible = true
|
inspector.visible = true
|
||||||
inspector.url = webview.experimental.remoteInspectorUrl
|
inspector.url = webview.experimental.remoteInspectorUrl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
onDoubleClicked: {
|
onDoubleClicked: {
|
||||||
console.log('refreshing')
|
console.log('refreshing')
|
||||||
webView.reload()
|
webView.reload()
|
||||||
}
|
}
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,15 +2,16 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/big"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/ethereum/eth-go/ethchain"
|
"github.com/ethereum/eth-go/ethchain"
|
||||||
"github.com/ethereum/eth-go/ethstate"
|
"github.com/ethereum/eth-go/ethstate"
|
||||||
"github.com/ethereum/eth-go/ethutil"
|
"github.com/ethereum/eth-go/ethutil"
|
||||||
"github.com/ethereum/eth-go/ethvm"
|
"github.com/ethereum/eth-go/ethvm"
|
||||||
"github.com/ethereum/go-ethereum/utils"
|
"github.com/ethereum/go-ethereum/utils"
|
||||||
"github.com/go-qml/qml"
|
"github.com/go-qml/qml"
|
||||||
"math/big"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type DebuggerWindow struct {
|
type DebuggerWindow struct {
|
||||||
|
|
@ -134,26 +135,13 @@ func (self *DebuggerWindow) Debug(valueStr, gasStr, gasPriceStr, scriptStr, data
|
||||||
state := self.lib.eth.StateManager().TransState()
|
state := self.lib.eth.StateManager().TransState()
|
||||||
account := self.lib.eth.StateManager().TransState().GetAccount(keyPair.Address())
|
account := self.lib.eth.StateManager().TransState().GetAccount(keyPair.Address())
|
||||||
contract := ethstate.NewStateObject([]byte{0})
|
contract := ethstate.NewStateObject([]byte{0})
|
||||||
contract.Amount = value
|
contract.Balance = value
|
||||||
|
|
||||||
self.SetAsm(script)
|
self.SetAsm(script)
|
||||||
|
|
||||||
callerClosure := ethvm.NewClosure(account, contract, script, gas, gasPrice)
|
|
||||||
|
|
||||||
block := self.lib.eth.BlockChain().CurrentBlock
|
block := self.lib.eth.BlockChain().CurrentBlock
|
||||||
|
|
||||||
/*
|
callerClosure := ethvm.NewClosure(account, contract, script, gas, gasPrice)
|
||||||
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),
|
|
||||||
})
|
|
||||||
*/
|
|
||||||
env := utils.NewEnv(state, block, account.Address(), value)
|
env := utils.NewEnv(state, block, account.Address(), value)
|
||||||
vm := ethvm.New(env)
|
vm := ethvm.New(env)
|
||||||
vm.Verbose = true
|
vm.Verbose = true
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"github.com/ethereum/eth-go/ethchain"
|
"github.com/ethereum/eth-go/ethchain"
|
||||||
"github.com/ethereum/eth-go/ethpub"
|
"github.com/ethereum/eth-go/ethpub"
|
||||||
|
"github.com/ethereum/eth-go/ethreact"
|
||||||
"github.com/ethereum/eth-go/ethstate"
|
"github.com/ethereum/eth-go/ethstate"
|
||||||
"github.com/ethereum/eth-go/ethutil"
|
"github.com/ethereum/eth-go/ethutil"
|
||||||
"github.com/go-qml/qml"
|
"github.com/go-qml/qml"
|
||||||
|
|
@ -25,8 +25,8 @@ type AppContainer interface {
|
||||||
type ExtApplication struct {
|
type ExtApplication struct {
|
||||||
*ethpub.PEthereum
|
*ethpub.PEthereum
|
||||||
|
|
||||||
blockChan chan ethutil.React
|
blockChan chan ethreact.Event
|
||||||
changeChan chan ethutil.React
|
changeChan chan ethreact.Event
|
||||||
quitChan chan bool
|
quitChan chan bool
|
||||||
watcherQuitChan chan bool
|
watcherQuitChan chan bool
|
||||||
|
|
||||||
|
|
@ -38,8 +38,8 @@ type ExtApplication struct {
|
||||||
func NewExtApplication(container AppContainer, lib *UiLib) *ExtApplication {
|
func NewExtApplication(container AppContainer, lib *UiLib) *ExtApplication {
|
||||||
app := &ExtApplication{
|
app := &ExtApplication{
|
||||||
ethpub.NewPEthereum(lib.eth),
|
ethpub.NewPEthereum(lib.eth),
|
||||||
make(chan ethutil.React, 1),
|
make(chan ethreact.Event, 100),
|
||||||
make(chan ethutil.React, 1),
|
make(chan ethreact.Event, 100),
|
||||||
make(chan bool),
|
make(chan bool),
|
||||||
make(chan bool),
|
make(chan bool),
|
||||||
container,
|
container,
|
||||||
|
|
@ -58,8 +58,7 @@ func (app *ExtApplication) run() {
|
||||||
|
|
||||||
err := app.container.Create()
|
err := app.container.Create()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Println(err)
|
logger.Errorln(err)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
254
ethereal/gui.go
254
ethereal/gui.go
|
|
@ -3,20 +3,23 @@ package main
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"math/big"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/ethereum/eth-go"
|
"github.com/ethereum/eth-go"
|
||||||
"github.com/ethereum/eth-go/ethchain"
|
"github.com/ethereum/eth-go/ethchain"
|
||||||
"github.com/ethereum/eth-go/ethdb"
|
"github.com/ethereum/eth-go/ethdb"
|
||||||
"github.com/ethereum/eth-go/ethlog"
|
"github.com/ethereum/eth-go/ethlog"
|
||||||
"github.com/ethereum/eth-go/ethminer"
|
"github.com/ethereum/eth-go/ethminer"
|
||||||
|
"github.com/ethereum/eth-go/ethpipe"
|
||||||
"github.com/ethereum/eth-go/ethpub"
|
"github.com/ethereum/eth-go/ethpub"
|
||||||
|
"github.com/ethereum/eth-go/ethreact"
|
||||||
"github.com/ethereum/eth-go/ethutil"
|
"github.com/ethereum/eth-go/ethutil"
|
||||||
"github.com/ethereum/eth-go/ethwire"
|
"github.com/ethereum/eth-go/ethwire"
|
||||||
"github.com/ethereum/go-ethereum/utils"
|
"github.com/ethereum/go-ethereum/utils"
|
||||||
"github.com/go-qml/qml"
|
"github.com/go-qml/qml"
|
||||||
"math/big"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var logger = ethlog.NewLogger("GUI")
|
var logger = ethlog.NewLogger("GUI")
|
||||||
|
|
@ -144,17 +147,20 @@ func (gui *Gui) showWallet(context *qml.Context) (*qml.Window, error) {
|
||||||
win := gui.createWindow(component)
|
win := gui.createWindow(component)
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
gui.setInitialBlockChain()
|
go gui.setInitialBlockChain()
|
||||||
gui.loadAddressBook()
|
gui.loadAddressBook()
|
||||||
gui.readPreviousTransactions()
|
|
||||||
gui.setPeerInfo()
|
gui.setPeerInfo()
|
||||||
|
gui.readPreviousTransactions()
|
||||||
}()
|
}()
|
||||||
|
|
||||||
go gui.update()
|
gui.update()
|
||||||
|
|
||||||
return win, nil
|
return win, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (gui *Gui) ImportKey(filePath string) {
|
||||||
|
}
|
||||||
|
|
||||||
func (gui *Gui) showKeyImport(context *qml.Context) (*qml.Window, error) {
|
func (gui *Gui) showKeyImport(context *qml.Context) (*qml.Window, error) {
|
||||||
context.SetVar("lib", gui)
|
context.SetVar("lib", gui)
|
||||||
component, err := gui.engine.LoadFile(gui.uiLib.AssetPath("qml/first_run.qml"))
|
component, err := gui.engine.LoadFile(gui.uiLib.AssetPath("qml/first_run.qml"))
|
||||||
|
|
@ -231,20 +237,54 @@ func (gui *Gui) loadAddressBook() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (gui *Gui) insertTransaction(window string, tx *ethchain.Transaction) {
|
||||||
|
nameReg := ethpipe.New(gui.eth).World().Config().Get("NameReg")
|
||||||
|
addr := gui.address()
|
||||||
|
|
||||||
|
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 {
|
||||||
|
r = ethutil.Bytes2Hex(tx.Recipient)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ptx.Sender = s
|
||||||
|
ptx.Address = r
|
||||||
|
|
||||||
|
gui.win.Root().Call("addTx", window, ptx, inout)
|
||||||
|
}
|
||||||
|
|
||||||
func (gui *Gui) readPreviousTransactions() {
|
func (gui *Gui) readPreviousTransactions() {
|
||||||
it := gui.txDb.Db().NewIterator(nil, nil)
|
it := gui.txDb.Db().NewIterator(nil, nil)
|
||||||
addr := gui.address()
|
|
||||||
for it.Next() {
|
for it.Next() {
|
||||||
tx := ethchain.NewTransactionFromBytes(it.Value())
|
tx := ethchain.NewTransactionFromBytes(it.Value())
|
||||||
|
|
||||||
var inout string
|
gui.insertTransaction("post", tx)
|
||||||
if bytes.Compare(tx.Sender(), addr) == 0 {
|
|
||||||
inout = "send"
|
|
||||||
} else {
|
|
||||||
inout = "recv"
|
|
||||||
}
|
|
||||||
|
|
||||||
gui.win.Root().Call("addTx", ethpub.NewPTx(tx), inout)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
it.Release()
|
it.Release()
|
||||||
|
|
@ -280,17 +320,100 @@ func (self *Gui) getObjectByName(objectName string) qml.Object {
|
||||||
|
|
||||||
// Simple go routine function that updates the list of peers in the GUI
|
// Simple go routine function that updates the list of peers in the GUI
|
||||||
func (gui *Gui) update() {
|
func (gui *Gui) update() {
|
||||||
reactor := gui.eth.Reactor()
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
blockChan = make(chan ethutil.React, 1)
|
blockChan = make(chan ethreact.Event, 100)
|
||||||
txChan = make(chan ethutil.React, 1)
|
txChan = make(chan ethreact.Event, 100)
|
||||||
objectChan = make(chan ethutil.React, 1)
|
objectChan = make(chan ethreact.Event, 100)
|
||||||
peerChan = make(chan ethutil.React, 1)
|
peerChan = make(chan ethreact.Event, 100)
|
||||||
chainSyncChan = make(chan ethutil.React, 1)
|
chainSyncChan = make(chan ethreact.Event, 100)
|
||||||
miningChan = make(chan ethutil.React, 1)
|
miningChan = make(chan ethreact.Event, 100)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
peerUpdateTicker := time.NewTicker(5 * time.Second)
|
||||||
|
generalUpdateTicker := time.NewTicker(1 * time.Second)
|
||||||
|
|
||||||
|
state := gui.eth.StateManager().TransState()
|
||||||
|
|
||||||
|
unconfirmedFunds := new(big.Int)
|
||||||
|
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")
|
||||||
|
|
||||||
|
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()).Balance, nil)
|
||||||
|
}
|
||||||
|
case txMsg := <-txChan:
|
||||||
|
tx := txMsg.Resource.(*ethchain.Transaction)
|
||||||
|
|
||||||
|
if txMsg.Name == "newTx:pre" {
|
||||||
|
object := state.GetAccount(gui.address())
|
||||||
|
|
||||||
|
if bytes.Compare(tx.Sender(), gui.address()) == 0 {
|
||||||
|
unconfirmedFunds.Sub(unconfirmedFunds, tx.Value)
|
||||||
|
} else if bytes.Compare(tx.Recipient, gui.address()) == 0 {
|
||||||
|
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)
|
||||||
|
|
||||||
|
state.UpdateStateObject(object)
|
||||||
|
}
|
||||||
|
case msg := <-chainSyncChan:
|
||||||
|
sync := msg.Resource.(bool)
|
||||||
|
gui.win.Root().ObjectByName("syncProgressIndicator").Set("visible", sync)
|
||||||
|
|
||||||
|
case <-objectChan:
|
||||||
|
gui.loadAddressBook()
|
||||||
|
case <-peerChan:
|
||||||
|
gui.setPeerInfo()
|
||||||
|
case <-peerUpdateTicker.C:
|
||||||
|
gui.setPeerInfo()
|
||||||
|
case msg := <-miningChan:
|
||||||
|
if msg.Name == "miner:start" {
|
||||||
|
gui.miner = msg.Resource.(*ethminer.Miner)
|
||||||
|
} else {
|
||||||
|
gui.miner = nil
|
||||||
|
}
|
||||||
|
case <-generalUpdateTicker.C:
|
||||||
|
statusText := "#" + gui.eth.BlockChain().CurrentBlock.Number.String()
|
||||||
|
if gui.miner != nil {
|
||||||
|
pow := gui.miner.GetPow()
|
||||||
|
if pow.GetHashrate() != 0 {
|
||||||
|
statusText = "Mining @ " + strconv.FormatInt(pow.GetHashrate(), 10) + "Khash - " + statusText
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastBlockLabel.Set("text", statusText)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
reactor := gui.eth.Reactor()
|
||||||
|
|
||||||
reactor.Subscribe("newBlock", blockChan)
|
reactor.Subscribe("newBlock", blockChan)
|
||||||
reactor.Subscribe("newTx:pre", txChan)
|
reactor.Subscribe("newTx:pre", txChan)
|
||||||
reactor.Subscribe("newTx:post", txChan)
|
reactor.Subscribe("newTx:post", txChan)
|
||||||
|
|
@ -303,86 +426,6 @@ func (gui *Gui) update() {
|
||||||
reactor.Subscribe("object:"+string(nameReg.Address()), objectChan)
|
reactor.Subscribe("object:"+string(nameReg.Address()), objectChan)
|
||||||
}
|
}
|
||||||
reactor.Subscribe("peerList", peerChan)
|
reactor.Subscribe("peerList", peerChan)
|
||||||
|
|
||||||
peerUpdateTicker := time.NewTicker(5 * time.Second)
|
|
||||||
generalUpdateTicker := time.NewTicker(1 * time.Second)
|
|
||||||
|
|
||||||
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.getObjectByName("syncProgressIndicator").Set("visible", !gui.eth.IsUpToDate())
|
|
||||||
|
|
||||||
lastBlockLabel := gui.getObjectByName("lastBlockLabel")
|
|
||||||
|
|
||||||
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)
|
|
||||||
|
|
||||||
if txMsg.Event == "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())
|
|
||||||
|
|
||||||
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.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)
|
|
||||||
|
|
||||||
state.UpdateStateObject(object)
|
|
||||||
}
|
|
||||||
case msg := <-chainSyncChan:
|
|
||||||
sync := msg.Resource.(bool)
|
|
||||||
gui.win.Root().ObjectByName("syncProgressIndicator").Set("visible", sync)
|
|
||||||
|
|
||||||
case <-objectChan:
|
|
||||||
gui.loadAddressBook()
|
|
||||||
case <-peerChan:
|
|
||||||
gui.setPeerInfo()
|
|
||||||
case <-peerUpdateTicker.C:
|
|
||||||
gui.setPeerInfo()
|
|
||||||
case msg := <-miningChan:
|
|
||||||
if msg.Event == "miner:start" {
|
|
||||||
gui.miner = msg.Resource.(*ethminer.Miner)
|
|
||||||
} else {
|
|
||||||
gui.miner = nil
|
|
||||||
}
|
|
||||||
|
|
||||||
case <-generalUpdateTicker.C:
|
|
||||||
statusText := "#" + gui.eth.BlockChain().CurrentBlock.Number.String()
|
|
||||||
if gui.miner != nil {
|
|
||||||
pow := gui.miner.GetPow()
|
|
||||||
if pow.GetHashrate() != 0 {
|
|
||||||
statusText = "Mining @ " + strconv.FormatInt(pow.GetHashrate(), 10) + "Khash - " + statusText
|
|
||||||
}
|
|
||||||
}
|
|
||||||
lastBlockLabel.Set("text", statusText)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (gui *Gui) setPeerInfo() {
|
func (gui *Gui) setPeerInfo() {
|
||||||
|
|
@ -416,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)
|
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) {
|
func (gui *Gui) SetCustomIdentifier(customIdentifier string) {
|
||||||
gui.clientIdentity.SetCustomIdentifier(customIdentifier)
|
gui.clientIdentity.SetCustomIdentifier(customIdentifier)
|
||||||
gui.config.Save("id", customIdentifier)
|
gui.config.Save("id", customIdentifier)
|
||||||
|
|
|
||||||
|
|
@ -2,17 +2,18 @@ package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
"github.com/ethereum/eth-go/ethchain"
|
"github.com/ethereum/eth-go/ethchain"
|
||||||
"github.com/ethereum/eth-go/ethpub"
|
"github.com/ethereum/eth-go/ethpub"
|
||||||
"github.com/ethereum/eth-go/ethstate"
|
"github.com/ethereum/eth-go/ethstate"
|
||||||
"github.com/ethereum/eth-go/ethutil"
|
"github.com/ethereum/eth-go/ethutil"
|
||||||
"github.com/go-qml/qml"
|
"github.com/go-qml/qml"
|
||||||
"github.com/howeyc/fsnotify"
|
"github.com/howeyc/fsnotify"
|
||||||
"io/ioutil"
|
|
||||||
"net/url"
|
|
||||||
"os"
|
|
||||||
"path"
|
|
||||||
"path/filepath"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type HtmlApplication struct {
|
type HtmlApplication struct {
|
||||||
|
|
@ -41,7 +42,7 @@ func (app *HtmlApplication) Create() error {
|
||||||
return errors.New("Ethereum package not yet supported")
|
return errors.New("Ethereum package not yet supported")
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
ethutil.OpenPackage(app.path)
|
//ethutil.OpenPackage(app.path)
|
||||||
}
|
}
|
||||||
|
|
||||||
win := component.CreateWindow(nil)
|
win := component.CreateWindow(nil)
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,17 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
"github.com/ethereum/eth-go/ethlog"
|
"github.com/ethereum/eth-go/ethlog"
|
||||||
"github.com/ethereum/go-ethereum/utils"
|
"github.com/ethereum/go-ethereum/utils"
|
||||||
"github.com/go-qml/qml"
|
"github.com/go-qml/qml"
|
||||||
"os"
|
|
||||||
"runtime"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ClientIdentifier = "Ethereal"
|
ClientIdentifier = "Ethereal"
|
||||||
Version = "0.6.0"
|
Version = "0.6.1"
|
||||||
)
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ func (app *QmlApplication) Create() error {
|
||||||
path := string(app.path)
|
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
|
// 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:]
|
path = app.path[1:]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"path"
|
||||||
|
|
||||||
"github.com/ethereum/eth-go"
|
"github.com/ethereum/eth-go"
|
||||||
"github.com/ethereum/eth-go/ethutil"
|
"github.com/ethereum/eth-go/ethutil"
|
||||||
"github.com/go-qml/qml"
|
"github.com/go-qml/qml"
|
||||||
"path"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type memAddr struct {
|
type memAddr struct {
|
||||||
|
|
@ -42,6 +43,10 @@ func (ui *UiLib) OpenHtml(path string) {
|
||||||
go app.run()
|
go app.run()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ui *UiLib) OpenBrowser() {
|
||||||
|
ui.OpenHtml("file://" + ui.AssetPath("ext/home.html"))
|
||||||
|
}
|
||||||
|
|
||||||
func (ui *UiLib) Muted(content string) {
|
func (ui *UiLib) Muted(content string) {
|
||||||
component, err := ui.engine.LoadFile(ui.AssetPath("qml/muted.qml"))
|
component, err := ui.engine.LoadFile(ui.AssetPath("qml/muted.qml"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,11 @@ package main
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/ethereum/eth-go/ethlog"
|
|
||||||
"os"
|
"os"
|
||||||
"os/user"
|
"os/user"
|
||||||
"path"
|
"path"
|
||||||
|
|
||||||
|
"github.com/ethereum/eth-go/ethlog"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Identifier string
|
var Identifier string
|
||||||
|
|
@ -31,6 +32,9 @@ var LogFile string
|
||||||
var ConfigFile string
|
var ConfigFile string
|
||||||
var DebugFile string
|
var DebugFile string
|
||||||
var LogLevel int
|
var LogLevel int
|
||||||
|
var Dump bool
|
||||||
|
var DumpHash string
|
||||||
|
var DumpNumber int
|
||||||
|
|
||||||
// flags specific to cli client
|
// flags specific to cli client
|
||||||
var StartMining bool
|
var StartMining bool
|
||||||
|
|
@ -71,6 +75,10 @@ func Init() {
|
||||||
flag.BoolVar(&DiffTool, "difftool", false, "creates output for diff'ing. Sets LogLevel=0")
|
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.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(&StartMining, "mine", false, "start dagger mining")
|
||||||
flag.BoolVar(&StartJsConsole, "js", false, "launches javascript console")
|
flag.BoolVar(&StartJsConsole, "js", false, "launches javascript console")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,19 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"os"
|
||||||
|
"runtime"
|
||||||
|
|
||||||
|
"github.com/ethereum/eth-go/ethchain"
|
||||||
"github.com/ethereum/eth-go/ethlog"
|
"github.com/ethereum/eth-go/ethlog"
|
||||||
"github.com/ethereum/eth-go/ethutil"
|
"github.com/ethereum/eth-go/ethutil"
|
||||||
"github.com/ethereum/go-ethereum/utils"
|
"github.com/ethereum/go-ethereum/utils"
|
||||||
"runtime"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
ClientIdentifier = "Ethereum(G)"
|
ClientIdentifier = "Ethereum(G)"
|
||||||
Version = "0.6.0"
|
Version = "0.6.1"
|
||||||
)
|
)
|
||||||
|
|
||||||
var logger = ethlog.NewLogger("CLI")
|
var logger = ethlog.NewLogger("CLI")
|
||||||
|
|
@ -23,7 +27,7 @@ func main() {
|
||||||
Init() // parsing command line
|
Init() // parsing command line
|
||||||
|
|
||||||
// If the difftool option is selected ignore all other log output
|
// If the difftool option is selected ignore all other log output
|
||||||
if DiffTool {
|
if DiffTool || Dump {
|
||||||
LogLevel = 0
|
LogLevel = 0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -46,6 +50,32 @@ func main() {
|
||||||
|
|
||||||
ethereum := utils.NewEthereum(db, clientIdentity, keyManager, UseUPnP, OutboundPort, MaxPeer)
|
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 {
|
if ShowGenesis {
|
||||||
utils.ShowGenesis(ethereum)
|
utils.ShowGenesis(ethereum)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,18 +2,20 @@ package ethrepl
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/ethereum/eth-go"
|
|
||||||
"github.com/ethereum/eth-go/ethchain"
|
|
||||||
"github.com/ethereum/eth-go/ethlog"
|
|
||||||
"github.com/ethereum/eth-go/ethpub"
|
|
||||||
"github.com/ethereum/eth-go/ethstate"
|
|
||||||
"github.com/ethereum/eth-go/ethutil"
|
|
||||||
"github.com/ethereum/go-ethereum/utils"
|
|
||||||
"github.com/obscuren/otto"
|
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/ethereum/eth-go"
|
||||||
|
"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/ethstate"
|
||||||
|
"github.com/ethereum/eth-go/ethutil"
|
||||||
|
"github.com/ethereum/go-ethereum/utils"
|
||||||
|
"github.com/obscuren/otto"
|
||||||
)
|
)
|
||||||
|
|
||||||
var jsrelogger = ethlog.NewLogger("JSRE")
|
var jsrelogger = ethlog.NewLogger("JSRE")
|
||||||
|
|
@ -23,8 +25,8 @@ type JSRE struct {
|
||||||
vm *otto.Otto
|
vm *otto.Otto
|
||||||
lib *ethpub.PEthereum
|
lib *ethpub.PEthereum
|
||||||
|
|
||||||
blockChan chan ethutil.React
|
blockChan chan ethreact.Event
|
||||||
changeChan chan ethutil.React
|
changeChan chan ethreact.Event
|
||||||
quitChan chan bool
|
quitChan chan bool
|
||||||
|
|
||||||
objectCb map[string][]otto.Value
|
objectCb map[string][]otto.Value
|
||||||
|
|
@ -49,8 +51,8 @@ func NewJSRE(ethereum *eth.Ethereum) *JSRE {
|
||||||
ethereum,
|
ethereum,
|
||||||
otto.New(),
|
otto.New(),
|
||||||
ethpub.NewPEthereum(ethereum),
|
ethpub.NewPEthereum(ethereum),
|
||||||
make(chan ethutil.React, 1),
|
make(chan ethreact.Event, 10),
|
||||||
make(chan ethutil.React, 1),
|
make(chan ethreact.Event, 10),
|
||||||
make(chan bool),
|
make(chan bool),
|
||||||
make(map[string][]otto.Value),
|
make(map[string][]otto.Value),
|
||||||
}
|
}
|
||||||
|
|
@ -65,6 +67,10 @@ func NewJSRE(ethereum *eth.Ethereum) *JSRE {
|
||||||
// We have to make sure that, whoever calls this, calls "Stop"
|
// We have to make sure that, whoever calls this, calls "Stop"
|
||||||
go re.mainLoop()
|
go re.mainLoop()
|
||||||
|
|
||||||
|
// Subscribe to events
|
||||||
|
reactor := ethereum.Reactor()
|
||||||
|
reactor.Subscribe("newBlock", re.blockChan)
|
||||||
|
|
||||||
re.Bind("eth", &JSEthereum{re.lib, re.vm})
|
re.Bind("eth", &JSEthereum{re.lib, re.vm})
|
||||||
|
|
||||||
re.initStdFuncs()
|
re.initStdFuncs()
|
||||||
|
|
@ -109,10 +115,6 @@ func (self *JSRE) Stop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *JSRE) mainLoop() {
|
func (self *JSRE) mainLoop() {
|
||||||
// Subscribe to events
|
|
||||||
reactor := self.ethereum.Reactor()
|
|
||||||
reactor.Subscribe("newBlock", self.blockChan)
|
|
||||||
|
|
||||||
out:
|
out:
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
|
|
@ -146,12 +148,44 @@ func (self *JSRE) initStdFuncs() {
|
||||||
eth.Set("stopMining", self.stopMining)
|
eth.Set("stopMining", self.stopMining)
|
||||||
eth.Set("startMining", self.startMining)
|
eth.Set("startMining", self.startMining)
|
||||||
eth.Set("execBlock", self.execBlock)
|
eth.Set("execBlock", self.execBlock)
|
||||||
|
eth.Set("dump", self.dump)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The following methods are natively implemented javascript functions
|
* 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()
|
||||||
|
}
|
||||||
|
|
||||||
|
v, _ := self.vm.ToValue(state.Dump())
|
||||||
|
|
||||||
|
return v
|
||||||
|
}
|
||||||
|
|
||||||
func (self *JSRE) stopMining(call otto.FunctionCall) otto.Value {
|
func (self *JSRE) stopMining(call otto.FunctionCall) otto.Value {
|
||||||
v, _ := self.vm.ToValue(utils.StopMining(self.ethereum))
|
v, _ := self.vm.ToValue(utils.StopMining(self.ethereum))
|
||||||
return v
|
return v
|
||||||
|
|
|
||||||
10
utils/cmd.go
10
utils/cmd.go
|
|
@ -127,6 +127,7 @@ func NewDatabase() ethutil.Database {
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClientIdentity(clientIdentifier, version, customIdentifier string) *ethwire.SimpleClientIdentity {
|
func NewClientIdentity(clientIdentifier, version, customIdentifier string) *ethwire.SimpleClientIdentity {
|
||||||
|
logger.Infoln("identity created")
|
||||||
return ethwire.NewSimpleClientIdentity(clientIdentifier, version, customIdentifier)
|
return ethwire.NewSimpleClientIdentity(clientIdentifier, version, customIdentifier)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -243,21 +244,18 @@ func GetMiner() *ethminer.Miner {
|
||||||
func StartMining(ethereum *eth.Ethereum) bool {
|
func StartMining(ethereum *eth.Ethereum) bool {
|
||||||
if !ethereum.Mining {
|
if !ethereum.Mining {
|
||||||
ethereum.Mining = true
|
ethereum.Mining = true
|
||||||
|
|
||||||
addr := ethereum.KeyManager().Address()
|
addr := ethereum.KeyManager().Address()
|
||||||
|
|
||||||
go func() {
|
go func() {
|
||||||
|
logger.Infoln("Start mining")
|
||||||
if miner == nil {
|
if miner == nil {
|
||||||
miner = ethminer.NewDefaultMiner(addr, ethereum)
|
miner = ethminer.NewDefaultMiner(addr, ethereum)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Give it some time to connect with peers
|
// Give it some time to connect with peers
|
||||||
time.Sleep(3 * time.Second)
|
time.Sleep(3 * time.Second)
|
||||||
for !ethereum.IsUpToDate() {
|
for !ethereum.IsUpToDate() {
|
||||||
time.Sleep(5 * time.Second)
|
time.Sleep(5 * time.Second)
|
||||||
}
|
}
|
||||||
|
|
||||||
logger.Infoln("Miner started")
|
|
||||||
miner.Start()
|
miner.Start()
|
||||||
}()
|
}()
|
||||||
RegisterInterrupt(func(os.Signal) {
|
RegisterInterrupt(func(os.Signal) {
|
||||||
|
|
@ -271,9 +269,7 @@ func StartMining(ethereum *eth.Ethereum) bool {
|
||||||
func StopMining(ethereum *eth.Ethereum) bool {
|
func StopMining(ethereum *eth.Ethereum) bool {
|
||||||
if ethereum.Mining && miner != nil {
|
if ethereum.Mining && miner != nil {
|
||||||
miner.Stop()
|
miner.Stop()
|
||||||
|
logger.Infoln("Stopped mining")
|
||||||
logger.Infoln("Miner stopped")
|
|
||||||
|
|
||||||
ethereum.Mining = false
|
ethereum.Mining = false
|
||||||
|
|
||||||
return true
|
return true
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue