Compare commits
35 Commits
Author | SHA1 | Date | |
---|---|---|---|
|
1adfc272a8 | ||
|
9caf53f8c6 | ||
|
edc281ac5f | ||
|
ee2cef3b2e | ||
|
54eff2d778 | ||
|
20ea78945e | ||
|
dd60382fc3 | ||
|
32c6126593 | ||
|
03371b74d7 | ||
|
c99aa7bdcf | ||
|
5208b04821 | ||
|
9a03df7bd8 | ||
|
67820506cb | ||
|
8c9e6746ce | ||
|
b9876df5dc | ||
|
a5963d1377 | ||
|
c3ad210846 | ||
|
618f523124 | ||
|
c7132e5d22 | ||
|
c43ea30e75 | ||
|
cf7ab07264 | ||
|
5d15563ea7 | ||
|
a3cc4b0b80 | ||
|
721d3a9a57 | ||
|
23fc50c61b | ||
|
faa3aa14ed | ||
|
b0023f66b0 | ||
|
109395daaa | ||
|
f73a5f067a | ||
|
1471585af0 | ||
|
0bf2d24cb0 | ||
|
f59f515def | ||
|
71defc11fa | ||
|
53eb59ed81 | ||
|
fb903619e8 |
@@ -5,7 +5,7 @@ Ethereum
|
||||
|
||||
Ethereum Go Client © 2014 Jeffrey Wilcke.
|
||||
|
||||
Current state: Proof of Concept 5.0 RC1.
|
||||
Current state: Proof of Concept 5.0 RC3.
|
||||
|
||||
For the development package please see the [eth-go package](https://github.com/ethereum/eth-go).
|
||||
|
||||
|
380
ethereal/assets/ext/big.js
Normal file
380
ethereal/assets/ext/big.js
Normal file
@@ -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;
|
||||
}
|
||||
|
@@ -36,6 +36,21 @@ window.eth = {
|
||||
postData({call: "getKey"}, cb);
|
||||
},
|
||||
|
||||
getTxCountAt: function(address, cb) {
|
||||
postData({call: "getTxCountAt", args: [address]}, cb);
|
||||
},
|
||||
getIsMining: function(cb){
|
||||
postData({call: "getIsMining"}, cb)
|
||||
},
|
||||
getIsListening: function(cb){
|
||||
postData({call: "getIsListening"}, cb)
|
||||
},
|
||||
getCoinBase: function(cb){
|
||||
postData({call: "getCoinBase"}, cb);
|
||||
},
|
||||
getPeerCount: function(cb){
|
||||
postData({call: "getPeerCount"}, cb);
|
||||
},
|
||||
getBalanceAt: function(address, cb) {
|
||||
postData({call: "getBalance", args: [address]}, cb);
|
||||
},
|
||||
@@ -115,122 +130,9 @@ 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()
|
||||
}
|
||||
|
58
ethereal/assets/ext/pre.js
Normal file
58
ethereal/assets/ext/pre.js
Normal file
@@ -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;
|
||||
}
|
58
ethereal/assets/ext/string.js
Normal file
58
ethereal/assets/ext/string.js
Normal file
@@ -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()
|
||||
}
|
@@ -46,7 +46,6 @@
|
||||
|
||||
.CodeMirror {
|
||||
height: 70%;
|
||||
font-size: 14pt;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
|
@@ -61,7 +61,7 @@ ApplicationWindow {
|
||||
text: "Restore"
|
||||
enabled: false
|
||||
onClicked: {
|
||||
var success = eth.importAndSetPrivKey(txPrivKey.text)
|
||||
var success = lib.importAndSetPrivKey(txPrivKey.text)
|
||||
if(success){
|
||||
importedDetails.visible = true
|
||||
restoreColumn.visible = false
|
||||
@@ -139,7 +139,7 @@ ApplicationWindow {
|
||||
id: newKey
|
||||
text: "I don't have an account yet"
|
||||
onClicked: {
|
||||
var res = eth.createAndSetPrivKey()
|
||||
var res = lib.createAndSetPrivKey()
|
||||
mnemonicInput.text = res[0]
|
||||
addressInput.text = res[1]
|
||||
privkeyInput.text = res[2]
|
||||
|
@@ -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"
|
||||
}
|
||||
}
|
||||
|
@@ -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"
|
||||
}
|
||||
|
@@ -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
|
||||
@@ -47,13 +47,37 @@ ApplicationWindow {
|
||||
|
||||
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("b9b56cf6f907fbee21db0cd7cbc0e6fea2fe29503a3943e275c5e467d649cb06")
|
||||
postData(data._seed, block)
|
||||
|
||||
break
|
||||
case "getBlockByHash":
|
||||
var block = eth.getBlock("b9b56cf6f907fbee21db0cd7cbc0e6fea2fe29503a3943e275c5e467d649cb06")
|
||||
postData(data._seed, block)
|
||||
|
||||
break
|
||||
case "transact":
|
||||
require(5)
|
||||
@@ -94,11 +118,14 @@ ApplicationWindow {
|
||||
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)
|
||||
|
@@ -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;
|
||||
});
|
||||
|
43
ethereal/assets/util/test.html
Normal file
43
ethereal/assets/util/test.html
Normal file
@@ -0,0 +1,43 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Utils</title>
|
||||
</head>
|
||||
<body onload="init();">
|
||||
<label>Nonce for 2ef47100e0787b915105fd5e3f4ff6752079d5cb</label>
|
||||
<p id="nonce"></p>
|
||||
|
||||
<label>Connected peers</label>
|
||||
<p id="peers"></p>
|
||||
|
||||
<label>Is mining</label>
|
||||
<p id="isMining"></p>
|
||||
|
||||
<label>Is listening</label>
|
||||
<p id="isListen"></p>
|
||||
|
||||
<label>Coinbase</label>
|
||||
<p id="coinbase"></p>
|
||||
|
||||
<script type="text/javascript">
|
||||
|
||||
function init() {
|
||||
eth.getTxCountAt("2ef47100e0787b915105fd5e3f4ff6752079d5cb", function(nonce){
|
||||
document.querySelector("#nonce").innerHTML = nonce;
|
||||
})
|
||||
eth.getPeerCount(function(peerLength){
|
||||
document.querySelector("#peers").innerHTML = peerLength;
|
||||
})
|
||||
eth.getIsMining(function(mining){
|
||||
document.querySelector("#isMining").innerHTML = mining;
|
||||
})
|
||||
eth.getIsListening(function(listen){
|
||||
document.querySelector("#isListen").innerHTML = listen;
|
||||
})
|
||||
eth.getCoinBase(function(address){
|
||||
document.querySelector("#coinbase").innerHTML = address;
|
||||
})
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
@@ -7,6 +7,7 @@ import (
|
||||
var StartConsole bool
|
||||
var StartMining bool
|
||||
var StartRpc bool
|
||||
var RpcPort int
|
||||
var UseUPnP bool
|
||||
var OutboundPort string
|
||||
var ShowGenesis bool
|
||||
@@ -28,6 +29,7 @@ func Init() {
|
||||
flag.BoolVar(&UseSeed, "seed", true, "seed peers")
|
||||
flag.BoolVar(&GenAddr, "genaddr", false, "create a new priv/pub key")
|
||||
flag.BoolVar(&ExportKey, "export", false, "export private key")
|
||||
flag.IntVar(&RpcPort, "rpcport", 8080, "port to start json-rpc server on")
|
||||
flag.StringVar(&OutboundPort, "p", "30303", "listening port")
|
||||
flag.StringVar(&DataDir, "dir", ".ethereal", "ethereum data directory")
|
||||
flag.StringVar(&ImportKey, "import", "", "imports the given private key (hex)")
|
||||
|
@@ -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)
|
||||
@@ -101,9 +100,13 @@ func main() {
|
||||
}
|
||||
|
||||
if StartRpc {
|
||||
ethereum.RpcServer = ethrpc.NewJsonRpcServer(ethpub.NewPEthereum(ethereum.StateManager(), ethereum.BlockChain(), ethereum.TxPool()))
|
||||
ethereum.RpcServer, err = ethrpc.NewJsonRpcServer(ethpub.NewPEthereum(ethereum), RpcPort)
|
||||
if err != nil {
|
||||
log.Println("Could not start RPC interface:", err)
|
||||
} else {
|
||||
go ethereum.RpcServer.Start()
|
||||
}
|
||||
}
|
||||
|
||||
log.Printf("Starting Ethereum GUI v%s\n", ethutil.Config.Ver)
|
||||
|
||||
@@ -111,5 +114,11 @@ func main() {
|
||||
ethereum.MaxPeers = MaxPeer
|
||||
|
||||
gui := ethui.New(ethereum)
|
||||
|
||||
ethereum.Start(UseSeed)
|
||||
|
||||
gui.Start(AssetPath)
|
||||
|
||||
// Wait for shutdown
|
||||
ethereum.WaitForShutdown()
|
||||
}
|
||||
|
@@ -34,7 +34,7 @@ type ExtApplication struct {
|
||||
|
||||
func NewExtApplication(container AppContainer, lib *UiLib) *ExtApplication {
|
||||
app := &ExtApplication{
|
||||
ethpub.NewPEthereum(lib.eth.StateManager(), lib.eth.BlockChain(), lib.eth.TxPool()),
|
||||
ethpub.NewPEthereum(lib.eth),
|
||||
make(chan ethutil.React, 1),
|
||||
make(chan ethutil.React, 1),
|
||||
make(chan bool),
|
||||
|
@@ -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"
|
||||
)
|
||||
@@ -24,10 +25,13 @@ type Gui struct {
|
||||
|
||||
// The public Ethereum library
|
||||
lib *EthLib
|
||||
uiLib *UiLib
|
||||
|
||||
txDb *ethdb.LDBDatabase
|
||||
|
||||
addr []byte
|
||||
|
||||
pub *ethpub.PEthereum
|
||||
}
|
||||
|
||||
// Create GUI, but doesn't start it
|
||||
@@ -46,14 +50,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)
|
||||
|
||||
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,27 +68,28 @@ 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 RC4"))
|
||||
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("ui", uiLib)
|
||||
context.SetVar("eth", gui)
|
||||
gui.uiLib = NewUiLib(gui.engine, gui.eth, assetPath)
|
||||
context.SetVar("ui", gui.uiLib)
|
||||
|
||||
// Load the main QML interface
|
||||
data, _ := ethutil.Config.Db.Get([]byte("KeyRing"))
|
||||
/*
|
||||
var err error
|
||||
var component qml.Object
|
||||
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 +97,117 @@ 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()
|
||||
*/
|
||||
|
||||
var win *qml.Window
|
||||
var err error
|
||||
if len(data) == 0 {
|
||||
win, err = gui.showKeyImport(context)
|
||||
} else {
|
||||
win, err = gui.showWallet(context)
|
||||
}
|
||||
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'")
|
||||
|
||||
panic(err)
|
||||
}
|
||||
|
||||
func (ui *Gui) setInitialBlockChain() {
|
||||
win.Show()
|
||||
win.Wait()
|
||||
|
||||
gui.eth.Stop()
|
||||
}
|
||||
|
||||
func (gui *Gui) showWallet(context *qml.Context) (*qml.Window, error) {
|
||||
component, err := gui.engine.LoadFile(gui.uiLib.AssetPath("qml/wallet.qml"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
win := gui.createWindow(component)
|
||||
|
||||
go gui.setInitialBlockChain()
|
||||
go gui.readPreviousTransactions()
|
||||
go gui.update()
|
||||
|
||||
return win, nil
|
||||
}
|
||||
|
||||
func (gui *Gui) showKeyImport(context *qml.Context) (*qml.Window, error) {
|
||||
context.SetVar("lib", gui.lib)
|
||||
component, err := gui.engine.LoadFile(gui.uiLib.AssetPath("qml/first_run.qml"))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return gui.createWindow(component), nil
|
||||
}
|
||||
|
||||
func (gui *Gui) createWindow(comp qml.Object) *qml.Window {
|
||||
win := comp.CreateWindow(nil)
|
||||
|
||||
gui.win = win
|
||||
gui.uiLib.win = win
|
||||
|
||||
db := &Debugger{gui.win, make(chan bool)}
|
||||
gui.lib.Db = db
|
||||
gui.uiLib.Db = db
|
||||
|
||||
return gui.win
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
state := gui.eth.StateManager().TransState()
|
||||
|
||||
account := ui.eth.StateManager().GetAddrState(ui.addr).Object
|
||||
unconfirmedFunds := new(big.Int)
|
||||
ui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(account.Amount)))
|
||||
|
||||
addrState := ui.eth.StateManager().GetAddrState(ui.addr)
|
||||
gui.win.Root().Call("setWalletValue", fmt.Sprintf("%v", ethutil.CurrencyToString(state.GetAccount(gui.addr).Amount)))
|
||||
|
||||
for {
|
||||
select {
|
||||
@@ -156,15 +215,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.GetAccount(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 +237,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.GetAccount(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.PreParse(data)
|
||||
|
||||
return gui.pub.Create(ethutil.Hex(keyPair.PrivateKey), value, gas, gasPrice, initInput, mainInput)
|
||||
}
|
||||
|
@@ -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 ðpub.PBlock{Number: int(block.BlockInfo().Number), Hash: ethutil.Hex(block.Hash())}
|
||||
}
|
||||
|
@@ -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)
|
||||
}
|
||||
@@ -131,7 +121,7 @@ func DefaultAssetPath() string {
|
||||
func (ui *UiLib) DebugTx(recipient, valueStr, gasStr, gasPriceStr, data string) {
|
||||
state := ui.eth.BlockChain().CurrentBlock.State()
|
||||
|
||||
mainInput, _ := mutan.PreProcess(data)
|
||||
mainInput, _ := mutan.PreParse(data)
|
||||
callerScript, err := utils.Compile(mainInput)
|
||||
if err != nil {
|
||||
ethutil.Config.Log.Debugln(err)
|
||||
@@ -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{
|
||||
|
@@ -7,6 +7,7 @@ import (
|
||||
var StartConsole bool
|
||||
var StartMining bool
|
||||
var StartRpc bool
|
||||
var RpcPort int
|
||||
var UseUPnP bool
|
||||
var OutboundPort string
|
||||
var ShowGenesis bool
|
||||
@@ -26,6 +27,7 @@ func Init() {
|
||||
flag.BoolVar(&ShowGenesis, "g", false, "prints genesis header and exits")
|
||||
//flag.BoolVar(&UseGui, "gui", true, "use the gui")
|
||||
flag.BoolVar(&StartRpc, "r", false, "start rpc server")
|
||||
flag.IntVar(&RpcPort, "rpcport", 8080, "port to start json-rpc server on")
|
||||
flag.BoolVar(&NonInteractive, "y", false, "non-interactive mode (say yes to confirmations)")
|
||||
flag.BoolVar(&UseUPnP, "upnp", false, "enable UPnP support")
|
||||
flag.BoolVar(&UseSeed, "seed", true, "seed peers")
|
||||
|
@@ -191,7 +191,7 @@ func (i *Console) ParseInput(input string) bool {
|
||||
case "contract":
|
||||
fmt.Println("Contract editor (Ctrl-D = done)")
|
||||
|
||||
mainInput, initInput := mutan.PreProcess(i.Editor())
|
||||
mainInput, initInput := mutan.PreParse(i.Editor())
|
||||
mainScript, err := utils.Compile(mainInput)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
|
@@ -1,6 +1,7 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"github.com/ethereum/eth-go"
|
||||
"github.com/ethereum/eth-go/ethchain"
|
||||
@@ -73,7 +74,6 @@ func main() {
|
||||
}*/
|
||||
|
||||
ethchain.InitFees()
|
||||
ethutil.Config.Seed = UseSeed
|
||||
|
||||
// Instantiated a eth stack
|
||||
ethereum, err := eth.New(eth.CapDefault, UseUPnP)
|
||||
@@ -123,23 +123,8 @@ func main() {
|
||||
// Set the max peers
|
||||
ethereum.MaxPeers = MaxPeer
|
||||
|
||||
if StartConsole {
|
||||
err := os.Mkdir(ethutil.Config.ExecPath, os.ModePerm)
|
||||
// Error is OK if the error is ErrExist
|
||||
if err != nil && !os.IsExist(err) {
|
||||
log.Panic("Unable to create EXECPATH:", err)
|
||||
}
|
||||
|
||||
console := NewConsole(ethereum)
|
||||
go console.Start()
|
||||
}
|
||||
if StartRpc {
|
||||
ethereum.RpcServer = ethrpc.NewJsonRpcServer(ethpub.NewPEthereum(ethereum.StateManager(), ethereum.BlockChain(), ethereum.TxPool()))
|
||||
go ethereum.RpcServer.Start()
|
||||
}
|
||||
|
||||
RegisterInterrupts(ethereum)
|
||||
ethereum.Start()
|
||||
// Set Mining status
|
||||
ethereum.Mining = StartMining
|
||||
|
||||
if StartMining {
|
||||
logger.Infoln("Miner started")
|
||||
@@ -155,7 +140,9 @@ func main() {
|
||||
keyRing := ethutil.NewValueFromBytes(data)
|
||||
addr := keyRing.Get(1).Bytes()
|
||||
|
||||
miner := ethminer.NewDefaultMiner(addr, ethereum)
|
||||
pair, _ := ethchain.NewKeyPairFromSec(ethutil.FromHex(hex.EncodeToString(addr)))
|
||||
|
||||
miner := ethminer.NewDefaultMiner(pair.Address(), ethereum)
|
||||
miner.Start()
|
||||
|
||||
}()
|
||||
@@ -164,6 +151,29 @@ func main() {
|
||||
|
||||
}
|
||||
|
||||
if StartConsole {
|
||||
err := os.Mkdir(ethutil.Config.ExecPath, os.ModePerm)
|
||||
// Error is OK if the error is ErrExist
|
||||
if err != nil && !os.IsExist(err) {
|
||||
log.Panic("Unable to create EXECPATH:", err)
|
||||
}
|
||||
|
||||
console := NewConsole(ethereum)
|
||||
go console.Start()
|
||||
}
|
||||
if StartRpc {
|
||||
ethereum.RpcServer, err = ethrpc.NewJsonRpcServer(ethpub.NewPEthereum(ethereum), RpcPort)
|
||||
if err != nil {
|
||||
logger.Infoln("Could not start RPC interface:", err)
|
||||
} else {
|
||||
go ethereum.RpcServer.Start()
|
||||
}
|
||||
}
|
||||
|
||||
RegisterInterrupts(ethereum)
|
||||
|
||||
ethereum.Start(UseSeed)
|
||||
|
||||
// Wait for shutdown
|
||||
ethereum.WaitForShutdown()
|
||||
}
|
||||
|
@@ -24,7 +24,7 @@ func Compile(script string) ([]byte, error) {
|
||||
|
||||
func CompileScript(script string) ([]byte, []byte, error) {
|
||||
// Preprocess
|
||||
mainInput, initInput := mutan.PreProcess(script)
|
||||
mainInput, initInput := mutan.PreParse(script)
|
||||
// Compile main script
|
||||
mainScript, err := Compile(mainInput)
|
||||
if err != nil {
|
||||
|
Reference in New Issue
Block a user