aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ethereal/assets/ext/big.js380
-rw-r--r--ethereal/assets/ext/ethereum.js (renamed from ethereal/assets/ethereum.js)115
-rw-r--r--ethereal/assets/ext/pre.js58
-rw-r--r--ethereal/assets/ext/string.js58
-rw-r--r--ethereal/assets/muted/index.html1
-rw-r--r--ethereal/assets/qml/newTransaction/_new_contract.qml4
-rw-r--r--ethereal/assets/qml/newTransaction/_simple_send.qml4
-rw-r--r--ethereal/assets/qml/webapp.qml2
-rw-r--r--ethereal/assets/samplecoin/samplecoin.html12
-rw-r--r--ethereal/ethereum.go1
-rw-r--r--ethereal/ui/gui.go148
-rw-r--r--ethereal/ui/library.go85
-rw-r--r--ethereal/ui/ui_lib.go16
-rw-r--r--ethereum/ethereum.go4
14 files changed, 590 insertions, 298 deletions
diff --git a/ethereal/assets/ext/big.js b/ethereal/assets/ext/big.js
new file mode 100644
index 000000000..db633fd2f
--- /dev/null
+++ b/ethereal/assets/ext/big.js
@@ -0,0 +1,380 @@
+var bigInt = (function () {
+ var base = 10000000, logBase = 7;
+ var sign = {
+ positive: false,
+ negative: true
+ };
+
+ var normalize = function (first, second) {
+ var a = first.value, b = second.value;
+ var length = a.length > b.length ? a.length : b.length;
+ for (var i = 0; i < length; i++) {
+ a[i] = a[i] || 0;
+ b[i] = b[i] || 0;
+ }
+ for (var i = length - 1; i >= 0; i--) {
+ if (a[i] === 0 && b[i] === 0) {
+ a.pop();
+ b.pop();
+ } else break;
+ }
+ if (!a.length) a = [0], b = [0];
+ first.value = a;
+ second.value = b;
+ };
+
+ var parse = function (text, first) {
+ if (typeof text === "object") return text;
+ text += "";
+ var s = sign.positive, value = [];
+ if (text[0] === "-") {
+ s = sign.negative;
+ text = text.slice(1);
+ }
+ var base = 10;
+ if (text.slice(0, 2) == "0x") {
+ base = 16;
+ text = text.slice(2);
+ }
+ else {
+ var texts = text.split("e");
+ if (texts.length > 2) throw new Error("Invalid integer");
+ if (texts[1]) {
+ var exp = texts[1];
+ if (exp[0] === "+") exp = exp.slice(1);
+ exp = parse(exp);
+ if (exp.lesser(0)) throw new Error("Cannot include negative exponent part for integers");
+ while (exp.notEquals(0)) {
+ texts[0] += "0";
+ exp = exp.prev();
+ }
+ }
+ text = texts[0];
+ }
+ if (text === "-0") text = "0";
+ text = text.toUpperCase();
+ var isValid = (base == 16 ? /^[0-9A-F]*$/ : /^[0-9]+$/).test(text);
+ if (!isValid) throw new Error("Invalid integer");
+ if (base == 16) {
+ var val = bigInt(0);
+ while (text.length) {
+ v = text.charCodeAt(0) - 48;
+ if (v > 9)
+ v -= 7;
+ text = text.slice(1);
+ val = val.times(16).plus(v);
+ }
+ return val;
+ }
+ else {
+ while (text.length) {
+ var divider = text.length > logBase ? text.length - logBase : 0;
+ value.push(+text.slice(divider));
+ text = text.slice(0, divider);
+ }
+ var val = bigInt(value, s);
+ if (first) normalize(first, val);
+ return val;
+ }
+ };
+
+ var goesInto = function (a, b) {
+ var a = bigInt(a, sign.positive), b = bigInt(b, sign.positive);
+ if (a.equals(0)) throw new Error("Cannot divide by 0");
+ var n = 0;
+ do {
+ var inc = 1;
+ var c = bigInt(a.value, sign.positive), t = c.times(10);
+ while (t.lesser(b)) {
+ c = t;
+ inc *= 10;
+ t = t.times(10);
+ }
+ while (c.lesserOrEquals(b)) {
+ b = b.minus(c);
+ n += inc;
+ }
+ } while (a.lesserOrEquals(b));
+
+ return {
+ remainder: b.value,
+ result: n
+ };
+ };
+
+ var bigInt = function (value, s) {
+ var self = {
+ value: value,
+ sign: s
+ };
+ var o = {
+ value: value,
+ sign: s,
+ negate: function (m) {
+ var first = m || self;
+ return bigInt(first.value, !first.sign);
+ },
+ abs: function (m) {
+ var first = m || self;
+ return bigInt(first.value, sign.positive);
+ },
+ add: function (n, m) {
+ var s, first = self, second;
+ if (m) (first = parse(n)) && (second = parse(m));
+ else second = parse(n, first);
+ s = first.sign;
+ if (first.sign !== second.sign) {
+ first = bigInt(first.value, sign.positive);
+ second = bigInt(second.value, sign.positive);
+ return s === sign.positive ?
+ o.subtract(first, second) :
+ o.subtract(second, first);
+ }
+ normalize(first, second);
+ var a = first.value, b = second.value;
+ var result = [],
+ carry = 0;
+ for (var i = 0; i < a.length || carry > 0; i++) {
+ var sum = (a[i] || 0) + (b[i] || 0) + carry;
+ carry = sum >= base ? 1 : 0;
+ sum -= carry * base;
+ result.push(sum);
+ }
+ return bigInt(result, s);
+ },
+ plus: function (n, m) {
+ return o.add(n, m);
+ },
+ subtract: function (n, m) {
+ var first = self, second;
+ if (m) (first = parse(n)) && (second = parse(m));
+ else second = parse(n, first);
+ if (first.sign !== second.sign) return o.add(first, o.negate(second));
+ if (first.sign === sign.negative) return o.subtract(o.negate(second), o.negate(first));
+ if (o.compare(first, second) === -1) return o.negate(o.subtract(second, first));
+ var a = first.value, b = second.value;
+ var result = [],
+ borrow = 0;
+ for (var i = 0; i < a.length; i++) {
+ var tmp = a[i] - borrow;
+ borrow = tmp < b[i] ? 1 : 0;
+ var minuend = (borrow * base) + tmp - b[i];
+ result.push(minuend);
+ }
+ return bigInt(result, sign.positive);
+ },
+ minus: function (n, m) {
+ return o.subtract(n, m);
+ },
+ multiply: function (n, m) {
+ var s, first = self, second;
+ if (m) (first = parse(n)) && (second = parse(m));
+ else second = parse(n, first);
+ s = first.sign !== second.sign;
+ var a = first.value, b = second.value;
+ var resultSum = [];
+ for (var i = 0; i < a.length; i++) {
+ resultSum[i] = [];
+ var j = i;
+ while (j--) {
+ resultSum[i].push(0);
+ }
+ }
+ var carry = 0;
+ for (var i = 0; i < a.length; i++) {
+ var x = a[i];
+ for (var j = 0; j < b.length || carry > 0; j++) {
+ var y = b[j];
+ var product = y ? (x * y) + carry : carry;
+ carry = product > base ? Math.floor(product / base) : 0;
+ product -= carry * base;
+ resultSum[i].push(product);
+ }
+ }
+ var max = -1;
+ for (var i = 0; i < resultSum.length; i++) {
+ var len = resultSum[i].length;
+ if (len > max) max = len;
+ }
+ var result = [], carry = 0;
+ for (var i = 0; i < max || carry > 0; i++) {
+ var sum = carry;
+ for (var j = 0; j < resultSum.length; j++) {
+ sum += resultSum[j][i] || 0;
+ }
+ carry = sum > base ? Math.floor(sum / base) : 0;
+ sum -= carry * base;
+ result.push(sum);
+ }
+ return bigInt(result, s);
+ },
+ times: function (n, m) {
+ return o.multiply(n, m);
+ },
+ divmod: function (n, m) {
+ var s, first = self, second;
+ if (m) (first = parse(n)) && (second = parse(m));
+ else second = parse(n, first);
+ s = first.sign !== second.sign;
+ if (bigInt(first.value, first.sign).equals(0)) return {
+ quotient: bigInt([0], sign.positive),
+ remainder: bigInt([0], sign.positive)
+ };
+ if (second.equals(0)) throw new Error("Cannot divide by zero");
+ var a = first.value, b = second.value;
+ var result = [], remainder = [];
+ for (var i = a.length - 1; i >= 0; i--) {
+ var n = [a[i]].concat(remainder);
+ var quotient = goesInto(b, n);
+ result.push(quotient.result);
+ remainder = quotient.remainder;
+ }
+ result.reverse();
+ return {
+ quotient: bigInt(result, s),
+ remainder: bigInt(remainder, first.sign)
+ };
+ },
+ divide: function (n, m) {
+ return o.divmod(n, m).quotient;
+ },
+ over: function (n, m) {
+ return o.divide(n, m);
+ },
+ mod: function (n, m) {
+ return o.divmod(n, m).remainder;
+ },
+ pow: function (n, m) {
+ var first = self, second;
+ if (m) (first = parse(n)) && (second = parse(m));
+ else second = parse(n, first);
+ var a = first, b = second;
+ if (b.lesser(0)) return ZERO;
+ if (b.equals(0)) return ONE;
+ var result = bigInt(a.value, a.sign);
+
+ if (b.mod(2).equals(0)) {
+ var c = result.pow(b.over(2));
+ return c.times(c);
+ } else {
+ return result.times(result.pow(b.minus(1)));
+ }
+ },
+ next: function (m) {
+ var first = m || self;
+ return o.add(first, 1);
+ },
+ prev: function (m) {
+ var first = m || self;
+ return o.subtract(first, 1);
+ },
+ compare: function (n, m) {
+ var first = self, second;
+ if (m) (first = parse(n)) && (second = parse(m, first));
+ else second = parse(n, first);
+ normalize(first, second);
+ if (first.value.length === 1 && second.value.length === 1 && first.value[0] === 0 && second.value[0] === 0) return 0;
+ if (second.sign !== first.sign) return first.sign === sign.positive ? 1 : -1;
+ var multiplier = first.sign === sign.positive ? 1 : -1;
+ var a = first.value, b = second.value;
+ for (var i = a.length - 1; i >= 0; i--) {
+ if (a[i] > b[i]) return 1 * multiplier;
+ if (b[i] > a[i]) return -1 * multiplier;
+ }
+ return 0;
+ },
+ compareAbs: function (n, m) {
+ var first = self, second;
+ if (m) (first = parse(n)) && (second = parse(m, first));
+ else second = parse(n, first);
+ first.sign = second.sign = sign.positive;
+ return o.compare(first, second);
+ },
+ equals: function (n, m) {
+ return o.compare(n, m) === 0;
+ },
+ notEquals: function (n, m) {
+ return !o.equals(n, m);
+ },
+ lesser: function (n, m) {
+ return o.compare(n, m) < 0;
+ },
+ greater: function (n, m) {
+ return o.compare(n, m) > 0;
+ },
+ greaterOrEquals: function (n, m) {
+ return o.compare(n, m) >= 0;
+ },
+ lesserOrEquals: function (n, m) {
+ return o.compare(n, m) <= 0;
+ },
+ isPositive: function (m) {
+ var first = m || self;
+ return first.sign === sign.positive;
+ },
+ isNegative: function (m) {
+ var first = m || self;
+ return first.sign === sign.negative;
+ },
+ isEven: function (m) {
+ var first = m || self;
+ return first.value[0] % 2 === 0;
+ },
+ isOdd: function (m) {
+ var first = m || self;
+ return first.value[0] % 2 === 1;
+ },
+ toString: function (m) {
+ var first = m || self;
+ var str = "", len = first.value.length;
+ while (len--) {
+ if (first.value[len].toString().length === 8) str += first.value[len];
+ else str += (base.toString() + first.value[len]).slice(-logBase);
+ }
+ while (str[0] === "0") {
+ str = str.slice(1);
+ }
+ if (!str.length) str = "0";
+ var s = (first.sign === sign.positive || str == "0") ? "" : "-";
+ return s + str;
+ },
+ toHex: function (m) {
+ var first = m || self;
+ var str = "";
+ var l = this.abs();
+ while (l > 0) {
+ var qr = l.divmod(256);
+ var b = qr.remainder.toJSNumber();
+ str = (b >> 4).toString(16) + (b & 15).toString(16) + str;
+ l = qr.quotient;
+ }
+ return (this.isNegative() ? "-" : "") + "0x" + str;
+ },
+ toJSNumber: function (m) {
+ return +o.toString(m);
+ },
+ valueOf: function (m) {
+ return o.toJSNumber(m);
+ }
+ };
+ return o;
+ };
+
+ var ZERO = bigInt([0], sign.positive);
+ var ONE = bigInt([1], sign.positive);
+ var MINUS_ONE = bigInt([1], sign.negative);
+
+ var fnReturn = function (a) {
+ if (typeof a === "undefined") return ZERO;
+ return parse(a);
+ };
+ fnReturn.zero = ZERO;
+ fnReturn.one = ONE;
+ fnReturn.minusOne = MINUS_ONE;
+ return fnReturn;
+})();
+
+if (typeof module !== "undefined") {
+ module.exports = bigInt;
+}
+
diff --git a/ethereal/assets/ethereum.js b/ethereal/assets/ext/ethereum.js
index 8f1a60300..f565e58bd 100644
--- a/ethereal/assets/ethereum.js
+++ b/ethereal/assets/ext/ethereum.js
@@ -119,118 +119,3 @@ window.eth = {
window.eth._callbacks = {}
window.eth._onCallbacks = {}
-function hello() {
- debug("hello")
- window.dataTest = true;
-}
-
-function debug(/**/) {
- var args = arguments;
- var msg = ""
- for(var i = 0; i < args.length; i++){
- if(typeof args[i] === "object") {
- msg += " " + JSON.stringify(args[i])
- } else {
- msg += args[i]
- }
- }
-
- postData({call:"debug", args:[msg]})
- document.getElementById("debug").innerHTML += "<br>" + msg
-}
-
-// Helper function for generating pseudo callbacks and sending data to the QML part of the application
-function postData(data, cb) {
- data._seed = Math.floor(Math.random() * 1000000)
- if(cb) {
- eth._callbacks[data._seed] = cb;
- }
-
- if(data.args === undefined) {
- data.args = [];
- }
-
- navigator.qt.postMessage(JSON.stringify(data));
-}
-
-navigator.qt.onmessage = function(ev) {
- var data = JSON.parse(ev.data)
-
- if(data._event !== undefined) {
- eth.trigger(data._event, data.data);
- } else {
- if(data._seed) {
- var cb = eth._callbacks[data._seed];
- if(cb) {
- // Figure out whether the returned data was an array
- // array means multiple return arguments (multiple params)
- if(data.data instanceof Array) {
- cb.apply(this, data.data)
- } else {
- cb.call(this, data.data)
- }
-
- // Remove the "trigger" callback
- delete eth._callbacks[ev._seed];
- }
- }
- }
-}
-
-window.eth._0 = "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
-String.prototype.pad = function(len) {
- var bin = this.bin();
- var l = bin.length;
- if(l < 32) {
- return eth._0.substr(0, 32 - bin.length) + bin;
- }
-
- return bin;
-}
-
-String.prototype.unpad = function() {
- var i, l;
- for(i = 0, l = this.length; i < l; i++) {
- if(this[i] != "\0") {
- return this.substr(i, this.length);
- }
- }
-
- return this.substr(i, this.length);
-}
-
-String.prototype.bin = function() {
- if(this.substr(0, 2) == "0x") {
- return this.hex2bin();
- } else if(/^\d+$/.test(this)) {
- return this.num2bin()
- }
-
- // Otherwise we'll return the "String" object instead of an actual string
- return this.substr(0, this.length)
-}
-
-String.prototype.unbin = function() {
- var i, l, o = '';
- for(i = 0, l = this.length; i < l; i++) {
- var n = this.charCodeAt(i).toString(16);
- o += n.length < 2 ? '0' + n : n;
- }
-
- return "0x" + o;
-}
-
-String.prototype.hex2bin = function() {
- bytes = []
-
- for(var i=2; i< this.length-1; i+=2) {
- bytes.push(parseInt(this.substr(i, 2), 16));
- }
-
- return String.fromCharCode.apply(String, bytes);
-}
-
-String.prototype.num2bin = function() {
- return ("0x"+parseInt(this).toString(16)).bin()
-}
-
diff --git a/ethereal/assets/ext/pre.js b/ethereal/assets/ext/pre.js
new file mode 100644
index 000000000..ca520f152
--- /dev/null
+++ b/ethereal/assets/ext/pre.js
@@ -0,0 +1,58 @@
+function debug(/**/) {
+ var args = arguments;
+ var msg = ""
+ for(var i = 0; i < args.length; i++){
+ if(typeof args[i] === "object") {
+ msg += " " + JSON.stringify(args[i])
+ } else {
+ msg += " " + args[i]
+ }
+ }
+
+ postData({call:"debug", args:[msg]})
+ document.getElementById("debug").innerHTML += "<br>" + msg
+}
+
+// Helper function for generating pseudo callbacks and sending data to the QML part of the application
+function postData(data, cb) {
+ data._seed = Math.floor(Math.random() * 1000000)
+ if(cb) {
+ eth._callbacks[data._seed] = cb;
+ }
+
+ if(data.args === undefined) {
+ data.args = [];
+ }
+
+ navigator.qt.postMessage(JSON.stringify(data));
+}
+
+navigator.qt.onmessage = function(ev) {
+ var data = JSON.parse(ev.data)
+
+ if(data._event !== undefined) {
+ eth.trigger(data._event, data.data);
+ } else {
+ if(data._seed) {
+ var cb = eth._callbacks[data._seed];
+ if(cb) {
+ // Figure out whether the returned data was an array
+ // array means multiple return arguments (multiple params)
+ if(data.data instanceof Array) {
+ cb.apply(this, data.data)
+ } else {
+ cb.call(this, data.data)
+ }
+
+ // Remove the "trigger" callback
+ delete eth._callbacks[ev._seed];
+ }
+ }
+ }
+}
+
+window.onerror = function(message, file, lineNumber, column, errorObj) {
+ debug(file, message, lineNumber+":"+column, errorObj);
+
+ return false;
+}
diff --git a/ethereal/assets/ext/string.js b/ethereal/assets/ext/string.js
new file mode 100644
index 000000000..2473b5c36
--- /dev/null
+++ b/ethereal/assets/ext/string.js
@@ -0,0 +1,58 @@
+String.prototype.pad = function(l, r) {
+ if (r === undefined) {
+ r = l
+ if (!(this.substr(0, 2) == "0x" || /^\d+$/.test(this)))
+ l = 0
+ }
+ var ret = this.bin();
+ while (ret.length < l)
+ ret = "\0" + ret
+ while (ret.length < r)
+ ret = ret + "\0"
+ return ret;
+}
+
+String.prototype.unpad = function() {
+ var i = this.length;
+ while (i && this[i - 1] == "\0")
+ --i
+ return this.substr(0, i)
+}
+
+String.prototype.bin = function() {
+ if (this.substr(0, 2) == "0x") {
+ bytes = []
+ var i = 2;
+
+ // Check if it's odd - pad with a zero if so.
+ if (this.length % 2)
+ bytes.push(parseInt(this.substr(i++, 1), 16))
+
+ for (; i < this.length - 1; i += 2)
+ bytes.push(parseInt(this.substr(i, 2), 16));
+
+ return String.fromCharCode.apply(String, bytes);
+ } else if (/^\d+$/.test(this))
+ return bigInt(this.substr(0)).toHex().bin()
+
+ // Otherwise we'll return the "String" object instead of an actual string
+ return this.substr(0, this.length)
+}
+
+String.prototype.unbin = function() {
+ var i, l, o = '';
+ for(i = 0, l = this.length; i < l; i++) {
+ var n = this.charCodeAt(i).toString(16);
+ o += n.length < 2 ? '0' + n : n;
+ }
+
+ return "0x" + o;
+}
+
+String.prototype.dec = function() {
+ return bigInt(this.substr(0)).toString()
+}
+
+String.prototype.hex = function() {
+ return bigInt(this.substr(0)).toHex()
+}
diff --git a/ethereal/assets/muted/index.html b/ethereal/assets/muted/index.html
index 14949b5ac..84584e373 100644
--- a/ethereal/assets/muted/index.html
+++ b/ethereal/assets/muted/index.html
@@ -46,7 +46,6 @@
.CodeMirror {
height: 70%;
- font-size: 14pt;
}
</style>
</head>
diff --git a/ethereal/assets/qml/newTransaction/_new_contract.qml b/ethereal/assets/qml/newTransaction/_new_contract.qml
index 0794d3dcd..f8f3d53a0 100644
--- a/ethereal/assets/qml/newTransaction/_new_contract.qml
+++ b/ethereal/assets/qml/newTransaction/_new_contract.qml
@@ -150,7 +150,7 @@ Component {
text: "Send"
onClicked: {
//this.enabled = false
- var res = eth.createTx(txFuelRecipient.text, txValue.text, txGas.text, txGasPrice.text, codeView.text)
+ var res = eth.create(txFuelRecipient.text, txValue.text, txGas.text, txGasPrice.text, codeView.text)
if(res[1]) {
txResult.text = "Your contract <b>could not</b> be send over the network:\n<b>"
txResult.text += res[1].error()
@@ -158,7 +158,7 @@ Component {
mainContractColumn.state = "ERROR"
} else {
txResult.text = "Your transaction has been submitted:\n"
- txOutput.text = res[0]
+ txOutput.text = res[0].address
mainContractColumn.state = "DONE"
}
}
diff --git a/ethereal/assets/qml/newTransaction/_simple_send.qml b/ethereal/assets/qml/newTransaction/_simple_send.qml
index d460797ea..12420c15a 100644
--- a/ethereal/assets/qml/newTransaction/_simple_send.qml
+++ b/ethereal/assets/qml/newTransaction/_simple_send.qml
@@ -77,12 +77,12 @@ Component {
text: "Send"
onClicked: {
//this.enabled = false
- var res = eth.createTx(txSimpleRecipient.text, txSimpleValue.text,"","","")
+ var res = eth.transact(txSimpleRecipient.text, txSimpleValue.text,"","","")
if(res[1]) {
txSimpleResult.text = "There has been an error broadcasting your transaction:" + res[1].error()
} else {
txSimpleResult.text = "Your transaction has been broadcasted over the network.\nYour transaction id is:"
- txSimpleOutput.text = res[0]
+ txSimpleOutput.text = res[0].hash
this.visible = false
simpleSendColumn.state = "DONE"
}
diff --git a/ethereal/assets/qml/webapp.qml b/ethereal/assets/qml/webapp.qml
index d02c9a82e..1f3c3874a 100644
--- a/ethereal/assets/qml/webapp.qml
+++ b/ethereal/assets/qml/webapp.qml
@@ -39,7 +39,7 @@ ApplicationWindow {
experimental.preferences.javascriptEnabled: true
experimental.preferences.navigatorQtObjectEnabled: true
experimental.preferences.developerExtrasEnabled: true
- experimental.userScripts: [ui.assetPath("ethereum.js")]
+ experimental.userScripts: [ui.assetPath("ext/pre.js"), ui.assetPath("ext/big.js"), ui.assetPath("ext/string.js"), ui.assetPath("ext/ethereum.js")]
experimental.onMessageReceived: {
console.log("[onMessageReceived]: ", message.data)
// TODO move to messaging.js
diff --git a/ethereal/assets/samplecoin/samplecoin.html b/ethereal/assets/samplecoin/samplecoin.html
index c1ee941a2..384936780 100644
--- a/ethereal/assets/samplecoin/samplecoin.html
+++ b/ethereal/assets/samplecoin/samplecoin.html
@@ -5,19 +5,18 @@
<link rel="stylesheet" href="bootstrap.min.css">
<link rel="stylesheet" href="bootstrap-theme.min.css">
<link rel="stylesheet" href="samplecoin.css">
-<script src="promise.min.js"></script>
<meta name="viewport" content="minimum-scale=1; maximum-scale=1; initial-scale=1;">
<script type="text/javascript">
-var jefcoinAddr = "3dff537f51350239abc95c76a5864aa605259e7d"
+var jefcoinAddr = "b7cb72c47ec4f31751d0d628b5a33fd6671bbba0"
var mAddr = ""
function createTransaction() {
- var addr = document.querySelector("#addr").value;
- var amount = document.querySelector("#amount").value;
+ var addr = ("0x" + document.querySelector("#addr").value).pad(32);
+ var amount = document.querySelector("#amount").value.pad(32);
- var data = (("0x"+addr).pad(32) + amount.pad(32)).unbin()
+ var data = (addr + amount).unbin();
eth.transact(mAddr, jefcoinAddr, 0, "10000000", "250", data, function(receipt) {
debug("received tx hash:", reciept.address)
})
@@ -27,9 +26,8 @@ function init() {
eth.set({width: 500});
eth.getKey(function(sec) {
+ mAddr = sec;
eth.getSecretToAddress(sec, function(addr) {
- mAddr = addr;
-
eth.getStorageAt(jefcoinAddr, addr, function(storage) {
document.querySelector("#current-amount").innerHTML = storage;
});
diff --git a/ethereal/ethereum.go b/ethereal/ethereum.go
index f3240adec..8b8889e37 100644
--- a/ethereal/ethereum.go
+++ b/ethereal/ethereum.go
@@ -42,7 +42,6 @@ func main() {
ethchain.InitFees()
ethutil.ReadConfig(DataDir)
- ethutil.Config.Seed = UseSeed
// Instantiated a eth stack
ethereum, err := eth.New(eth.CapDefault, UseUPnP)
diff --git a/ethereal/ui/gui.go b/ethereal/ui/gui.go
index 522c081a3..92c6e9389 100644
--- a/ethereal/ui/gui.go
+++ b/ethereal/ui/gui.go
@@ -9,6 +9,7 @@ import (
"github.com/ethereum/eth-go/ethpub"
"github.com/ethereum/eth-go/ethutil"
"github.com/go-qml/qml"
+ "github.com/obscuren/mutan"
"math/big"
"strings"
)
@@ -28,6 +29,8 @@ type Gui struct {
txDb *ethdb.LDBDatabase
addr []byte
+
+ pub *ethpub.PEthereum
}
// Create GUI, but doesn't start it
@@ -46,14 +49,16 @@ func New(ethereum *eth.Ethereum) *Gui {
key := ethutil.Config.Db.GetKeys()[0]
addr = key.Address()
- ethereum.StateManager().WatchAddr(addr)
+ //ethereum.StateManager().WatchAddr(addr)
}
- return &Gui{eth: ethereum, lib: lib, txDb: db, addr: addr}
+ pub := ethpub.NewPEthereum(ethereum.StateManager(), ethereum.BlockChain(), ethereum.TxPool())
+
+ return &Gui{eth: ethereum, lib: lib, txDb: db, addr: addr, pub: pub}
}
-func (ui *Gui) Start(assetPath string) {
- defer ui.txDb.Close()
+func (gui *Gui) Start(assetPath string) {
+ defer gui.txDb.Close()
// Register ethereum functions
qml.RegisterTypes("Ethereum", 1, 0, []qml.TypeSpec{{
@@ -62,15 +67,15 @@ func (ui *Gui) Start(assetPath string) {
Init: func(p *ethpub.PTx, obj qml.Object) { p.Value = ""; p.Hash = ""; p.Address = "" },
}})
- ethutil.Config.SetClientString(fmt.Sprintf("/Ethereal v%s", "0.2"))
+ ethutil.Config.SetClientString(fmt.Sprintf("/Ethereal v%s", "0.5.0 RC2"))
ethutil.Config.Log.Infoln("[GUI] Starting GUI")
// Create a new QML engine
- ui.engine = qml.NewEngine()
- context := ui.engine.Context()
+ gui.engine = qml.NewEngine()
+ context := gui.engine.Context()
// Expose the eth library and the ui library to QML
- context.SetVar("eth", ui.lib)
- uiLib := NewUiLib(ui.engine, ui.eth, assetPath)
+ context.SetVar("eth", gui)
+ uiLib := NewUiLib(gui.engine, gui.eth, assetPath)
context.SetVar("ui", uiLib)
// Load the main QML interface
@@ -80,9 +85,9 @@ func (ui *Gui) Start(assetPath string) {
firstRun := len(data) == 0
if firstRun {
- component, err = ui.engine.LoadFile(uiLib.AssetPath("qml/first_run.qml"))
+ component, err = gui.engine.LoadFile(uiLib.AssetPath("qml/first_run.qml"))
} else {
- component, err = ui.engine.LoadFile(uiLib.AssetPath("qml/wallet.qml"))
+ component, err = gui.engine.LoadFile(uiLib.AssetPath("qml/wallet.qml"))
}
if err != nil {
ethutil.Config.Log.Infoln("FATAL: asset not found: you can set an alternative asset path on on the command line using option 'asset_path'")
@@ -90,65 +95,60 @@ func (ui *Gui) Start(assetPath string) {
panic(err)
}
- ui.win = component.CreateWindow(nil)
- uiLib.win = ui.win
- db := &Debugger{ui.win, make(chan bool)}
- ui.lib.Db = db
+ gui.win = component.CreateWindow(nil)
+ uiLib.win = gui.win
+ db := &Debugger{gui.win, make(chan bool)}
+ gui.lib.Db = db
uiLib.Db = db
- // Register the ui as a block processor
- //ui.eth.BlockManager.SecondaryBlockProcessor = ui
- //ui.eth.TxPool.SecondaryProcessor = ui
-
// Add the ui as a log system so we can log directly to the UGI
- ethutil.Config.Log.AddLogSystem(ui)
+ ethutil.Config.Log.AddLogSystem(gui)
// Loads previous blocks
if firstRun == false {
- go ui.setInitialBlockChain()
- go ui.readPreviousTransactions()
- go ui.update()
+ go gui.setInitialBlockChain()
+ go gui.readPreviousTransactions()
+ go gui.update()
}
- ui.win.Show()
- ui.win.Wait()
+ gui.win.Show()
+ gui.win.Wait()
- ui.eth.Stop()
+ gui.eth.Stop()
}
-func (ui *Gui) setInitialBlockChain() {
+func (gui *Gui) setInitialBlockChain() {
// Load previous 10 blocks
- chain := ui.eth.BlockChain().GetChain(ui.eth.BlockChain().CurrentBlock.Hash(), 10)
+ chain := gui.eth.BlockChain().GetChain(gui.eth.BlockChain().CurrentBlock.Hash(), 10)
for _, block := range chain {
- ui.ProcessBlock(block)
+ gui.processBlock(block)
}
}
-func (ui *Gui) readPreviousTransactions() {
- it := ui.txDb.Db().NewIterator(nil, nil)
+func (gui *Gui) readPreviousTransactions() {
+ it := gui.txDb.Db().NewIterator(nil, nil)
for it.Next() {
tx := ethchain.NewTransactionFromBytes(it.Value())
- ui.win.Root().Call("addTx", ethpub.NewPTx(tx))
+ gui.win.Root().Call("addTx", ethpub.NewPTx(tx))
}
it.Release()
}
-func (ui *Gui) ProcessBlock(block *ethchain.Block) {
- ui.win.Root().Call("addBlock", ethpub.NewPBlock(block))
+func (gui *Gui) processBlock(block *ethchain.Block) {
+ gui.win.Root().Call("addBlock", ethpub.NewPBlock(block))
}
// Simple go routine function that updates the list of peers in the GUI
-func (ui *Gui) update() {
+func (gui *Gui) update() {
txChan := make(chan ethchain.TxMsg, 1)
- ui.eth.TxPool().Subscribe(txChan)
+ gui.eth.TxPool().Subscribe(txChan)
- account := ui.eth.StateManager().GetAddrState(ui.addr).Object
- unconfirmedFunds := new(big.Int)
- ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(account.Amount)))
+ state := gui.eth.StateManager().TransState()
- addrState := ui.eth.StateManager().GetAddrState(ui.addr)
+ unconfirmedFunds := new(big.Int)
+ gui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(state.GetStateObject(gui.addr).Amount)))
for {
select {
@@ -156,15 +156,19 @@ func (ui *Gui) update() {
tx := txMsg.Tx
if txMsg.Type == ethchain.TxPre {
- if bytes.Compare(tx.Sender(), ui.addr) == 0 && addrState.Nonce <= tx.Nonce {
- ui.win.Root().Call("addTx", ethpub.NewPTx(tx))
- ui.txDb.Put(tx.Hash(), tx.RlpEncode())
+ object := state.GetStateObject(gui.addr)
+
+ if bytes.Compare(tx.Sender(), gui.addr) == 0 && object.Nonce <= tx.Nonce {
+ gui.win.Root().Call("addTx", ethpub.NewPTx(tx))
+ gui.txDb.Put(tx.Hash(), tx.RlpEncode())
+
+ object.Nonce += 1
+ state.SetStateObject(object)
- addrState.Nonce += 1
unconfirmedFunds.Sub(unconfirmedFunds, tx.Value)
- } else if bytes.Compare(tx.Recipient, ui.addr) == 0 {
- ui.win.Root().Call("addTx", ethpub.NewPTx(tx))
- ui.txDb.Put(tx.Hash(), tx.RlpEncode())
+ } else if bytes.Compare(tx.Recipient, gui.addr) == 0 {
+ gui.win.Root().Call("addTx", ethpub.NewPTx(tx))
+ gui.txDb.Put(tx.Hash(), tx.RlpEncode())
unconfirmedFunds.Add(unconfirmedFunds, tx.Value)
}
@@ -174,46 +178,52 @@ func (ui *Gui) update() {
pos = "-"
}
val := ethutil.CurrencyToString(new(big.Int).Abs(ethutil.BigCopy(unconfirmedFunds)))
- str := fmt.Sprintf("%v (%s %v)", ethutil.CurrencyToString(account.Amount), pos, val)
+ str := fmt.Sprintf("%v (%s %v)", ethutil.CurrencyToString(object.Amount), pos, val)
- ui.win.Root().Call("setWalletValue", str)
+ gui.win.Root().Call("setWalletValue", str)
} else {
- amount := account.Amount
- if bytes.Compare(tx.Sender(), ui.addr) == 0 {
- amount.Sub(account.Amount, tx.Value)
- } else if bytes.Compare(tx.Recipient, ui.addr) == 0 {
- amount.Add(account.Amount, tx.Value)
+ object := state.GetStateObject(gui.addr)
+ if bytes.Compare(tx.Sender(), gui.addr) == 0 {
+ object.SubAmount(tx.Value)
+ } else if bytes.Compare(tx.Recipient, gui.addr) == 0 {
+ object.AddAmount(tx.Value)
}
- ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(amount)))
+ gui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(object.Amount)))
+
+ state.SetStateObject(object)
}
}
-
- /*
- accountAmount := ui.eth.BlockManager.GetAddrState(ui.addr).Account.Amount
- ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", accountAmount))
-
- ui.win.Root().Call("setPeers", fmt.Sprintf("%d / %d", ui.eth.Peers().Len(), ui.eth.MaxPeers))
-
- time.Sleep(1 * time.Second)
- */
-
}
}
// Logging functions that log directly to the GUI interface
-func (ui *Gui) Println(v ...interface{}) {
+func (gui *Gui) Println(v ...interface{}) {
str := strings.TrimRight(fmt.Sprintln(v...), "\n")
lines := strings.Split(str, "\n")
for _, line := range lines {
- ui.win.Root().Call("addLog", line)
+ gui.win.Root().Call("addLog", line)
}
}
-func (ui *Gui) Printf(format string, v ...interface{}) {
+func (gui *Gui) Printf(format string, v ...interface{}) {
str := strings.TrimRight(fmt.Sprintf(format, v...), "\n")
lines := strings.Split(str, "\n")
for _, line := range lines {
- ui.win.Root().Call("addLog", line)
+ gui.win.Root().Call("addLog", line)
}
}
+
+func (gui *Gui) Transact(recipient, value, gas, gasPrice, data string) (*ethpub.PReceipt, error) {
+ keyPair := ethutil.Config.Db.GetKeys()[0]
+
+ return gui.pub.Transact(ethutil.Hex(keyPair.PrivateKey), recipient, value, gas, gasPrice, data)
+}
+
+func (gui *Gui) Create(recipient, value, gas, gasPrice, data string) (*ethpub.PReceipt, error) {
+ keyPair := ethutil.Config.Db.GetKeys()[0]
+
+ mainInput, initInput := mutan.PreProcess(data)
+
+ return gui.pub.Create(ethutil.Hex(keyPair.PrivateKey), value, gas, gasPrice, initInput, mainInput)
+}
diff --git a/ethereal/ui/library.go b/ethereal/ui/library.go
index 1328cd6b7..c889efb45 100644
--- a/ethereal/ui/library.go
+++ b/ethereal/ui/library.go
@@ -1,10 +1,8 @@
package ethui
import (
- "encoding/hex"
"fmt"
"github.com/ethereum/eth-go/ethchain"
- "github.com/ethereum/eth-go/ethpub"
"github.com/ethereum/eth-go/ethutil"
"github.com/ethereum/go-ethereum/utils"
"github.com/obscuren/secp256k1-go"
@@ -43,86 +41,3 @@ func (lib *EthLib) CreateAndSetPrivKey() (string, string, string, string) {
mnemonicString := strings.Join(mne, " ")
return mnemonicString, fmt.Sprintf("%x", pair.Address()), fmt.Sprintf("%x", prv), fmt.Sprintf("%x", pub)
}
-
-func (lib *EthLib) GetKey() string {
- return ethutil.Hex(ethutil.Config.Db.GetKeys()[0].Address())
-}
-
-func (lib *EthLib) GetStateObject(address string) *ethpub.PStateObject {
- stateObject := lib.stateManager.ProcState().GetContract(ethutil.FromHex(address))
- if stateObject != nil {
- return ethpub.NewPStateObject(stateObject)
- }
-
- // See GetStorage for explanation on "nil"
- return ethpub.NewPStateObject(nil)
-}
-
-func (lib *EthLib) Watch(addr, storageAddr string) {
- // lib.stateManager.Watch(ethutil.FromHex(addr), ethutil.FromHex(storageAddr))
-}
-
-func (lib *EthLib) CreateTx(recipient, valueStr, gasStr, gasPriceStr, dataStr string) (string, error) {
- return lib.Transact(recipient, valueStr, gasStr, gasPriceStr, dataStr)
-}
-
-func (lib *EthLib) Transact(recipient, valueStr, gasStr, gasPriceStr, dataStr string) (string, error) {
- var hash []byte
- var contractCreation bool
- if len(recipient) == 0 {
- contractCreation = true
- } else {
- var err error
- hash, err = hex.DecodeString(recipient)
- if err != nil {
- return "", err
- }
- }
-
- keyPair := ethutil.Config.Db.GetKeys()[0]
- value := ethutil.Big(valueStr)
- gas := ethutil.Big(gasStr)
- gasPrice := ethutil.Big(gasPriceStr)
- var tx *ethchain.Transaction
- // Compile and assemble the given data
- if contractCreation {
- // Compile script
- mainScript, initScript, err := utils.CompileScript(dataStr)
- if err != nil {
- return "", err
- }
-
- tx = ethchain.NewContractCreationTx(value, gas, gasPrice, mainScript, initScript)
- } else {
- lines := strings.Split(dataStr, "\n")
- var data []byte
- for _, line := range lines {
- data = append(data, ethutil.BigToBytes(ethutil.Big(line), 256)...)
- }
-
- tx = ethchain.NewTransactionMessage(hash, value, gas, gasPrice, data)
- }
- acc := lib.stateManager.GetAddrState(keyPair.Address())
- tx.Nonce = acc.Nonce
- tx.Sign(keyPair.PrivateKey)
- lib.txPool.QueueTransaction(tx)
-
- if contractCreation {
- ethutil.Config.Log.Infof("Contract addr %x", tx.Hash()[12:])
- } else {
- ethutil.Config.Log.Infof("Tx hash %x", tx.Hash())
- }
-
- return ethutil.Hex(tx.Hash()), nil
-}
-
-func (lib *EthLib) GetBlock(hexHash string) *ethpub.PBlock {
- hash, err := hex.DecodeString(hexHash)
- if err != nil {
- return nil
- }
-
- block := lib.blockChain.GetBlock(hash)
-
- return &ethpub.PBlock{Number: int(block.BlockInfo().Number), Hash: ethutil.Hex(block.Hash())}
-}
diff --git a/ethereal/ui/ui_lib.go b/ethereal/ui/ui_lib.go
index 0feb522bc..35ceb7d79 100644
--- a/ethereal/ui/ui_lib.go
+++ b/ethereal/ui/ui_lib.go
@@ -59,14 +59,6 @@ func (ui *UiLib) OpenHtml(path string) {
go app.run()
}
-func (ui *UiLib) Watch(addr, storageAddr string) {
- if len(storageAddr) == 0 {
- ui.eth.Reactor().Subscribe("storage:"+string(ethutil.FromHex(addr))+":"+string(ethutil.FromHex(storageAddr)), nil)
- } else {
- ui.eth.Reactor().Subscribe("object:"+string(ethutil.FromHex(addr)), nil)
- }
-}
-
func (ui *UiLib) Muted(content string) {
component, err := ui.engine.LoadFile(ui.AssetPath("qml/muted.qml"))
if err != nil {
@@ -78,8 +70,6 @@ func (ui *UiLib) Muted(content string) {
go func() {
path := "file://" + ui.AssetPath("muted/index.html")
win.Set("url", path)
- //debuggerPath := "file://" + ui.AssetPath("muted/debugger.html")
- //win.Set("debugUrl", debuggerPath)
win.Show()
win.Wait()
@@ -88,7 +78,7 @@ func (ui *UiLib) Muted(content string) {
func (ui *UiLib) Connect(button qml.Object) {
if !ui.connected {
- ui.eth.Start()
+ ui.eth.Start(true)
ui.connected = true
button.Set("enabled", false)
}
@@ -149,9 +139,9 @@ func (ui *UiLib) DebugTx(recipient, valueStr, gasStr, gasPriceStr, data string)
// Contract addr as test address
keyPair := ethutil.Config.Db.GetKeys()[0]
- account := ui.eth.StateManager().GetAddrState(keyPair.Address()).Object
+ account := ui.eth.StateManager().TransState().GetStateObject(keyPair.Address())
c := ethchain.MakeContract(callerTx, state)
- callerClosure := ethchain.NewClosure(account, c, c.Script(), state, ethutil.Big(gasStr), ethutil.Big(gasPriceStr), ethutil.Big(valueStr))
+ callerClosure := ethchain.NewClosure(account, c, c.Script(), state, ethutil.Big(gasStr), ethutil.Big(gasPriceStr))
block := ui.eth.BlockChain().CurrentBlock
vm := ethchain.NewVm(state, ui.eth.StateManager(), ethchain.RuntimeVars{
diff --git a/ethereum/ethereum.go b/ethereum/ethereum.go
index 8719f3e87..2f05bf2a1 100644
--- a/ethereum/ethereum.go
+++ b/ethereum/ethereum.go
@@ -73,7 +73,6 @@ func main() {
}*/
ethchain.InitFees()
- ethutil.Config.Seed = UseSeed
// Instantiated a eth stack
ethereum, err := eth.New(eth.CapDefault, UseUPnP)
@@ -139,7 +138,8 @@ func main() {
}
RegisterInterrupts(ethereum)
- ethereum.Start()
+
+ ethereum.Start(UseSeed)
if StartMining {
logger.Infoln("Miner started")